Skip to content

Commit

Permalink
Inspection IO is now async and poll checks for cancellation (#192).
Browse files Browse the repository at this point in the history
  • Loading branch information
jshiell committed Oct 17, 2015
1 parent bd95bdf commit dd95b20
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 26 deletions.
10 changes: 6 additions & 4 deletions CheckStyle-IDEA.ipr
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@
<component name="CheckStyle-IDEA">
<option name="configuration">
<map>
<entry key="active-configuration" value="LOCAL_FILE:$PRJ_DIR$/test-configs/yazino-checkstyle-rules.xml:Yazino" />
<entry key="active-configuration" value="LOCAL_FILE:$PRJ_DIR$/test-configs/issue-193.xml:Issue 193" />
<entry key="check-nonjava-files" value="false" />
<entry key="check-test-classes" value="false" />
<entry key="location-0" value="CLASSPATH:/sun_checks.xml:The default Checkstyle rules" />
<entry key="location-1" value="LOCAL_FILE:$PRJ_DIR$/test-configs/yazino-checkstyle-rules.xml:Yazino" />
<entry key="property-1.checkstyle.suppressions.file" value="" />
<entry key="location-0" value="LOCAL_FILE:$PRJ_DIR$/test-configs/issue-193.xml:Issue 193" />
<entry key="location-1" value="HTTP_URL:http://localhost/cs/issue-193.xml:Issue 193 via HTTP" />
<entry key="location-2" value="CLASSPATH:/sun_checks.xml:The default Checkstyle rules" />
<entry key="location-3" value="LOCAL_FILE:$PRJ_DIR$/test-configs/yazino-checkstyle-rules.xml:Yazino" />
<entry key="property-3.checkstyle.suppressions.file" value="" />
<entry key="suppress-errors" value="false" />
<entry key="thirdparty-classpath" value="$PROJECT_DIR$/../Third Party/CreateYourOwnCheckStyleCheck/BlundellCheckstyle/target/blundell-checkstyle-checks-1.0.jar;$PRJ_DIR$/test-configs/issue-164/vdna-checkstyle-2.1.1-SNAPSHOT.jar" />
</map>
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ Released under a BSD-style licence - please see the LICENCE file for details.
> default IDEA package for OS X runs on Java 6, please make use of the versions
> with the bundled JDK, e.g.
>
> [Community Edition (14.1.5)](https://download.jetbrains.com/idea/ideaIC-14.1.5-custom-jdk-bundled.dmg)
>
> [Ultimate Edition (14.1.5)](https://download.jetbrains.com/idea/ideaIU-14.1.5-custom-jdk-bundled.dmg)
> * [Community Edition (14.1.5)](https://download.jetbrains.com/idea/ideaIC-14.1.5-custom-jdk-bundled.dmg)
> * [Ultimate Edition (14.1.5)](https://download.jetbrains.com/idea/ideaIU-14.1.5-custom-jdk-bundled.dmg)
>
> or, for Brew Cask users,
>
> brew cask install intellij-idea-ce-bundled-jdk
> brew cask install intellij-idea-bundled-jdk
> * brew cask install intellij-idea-ce-bundled-jdk
> * brew cask install intellij-idea-bundled-jdk
>
> All other users please note - we require IDEA to be running on JDK 8.
Expand Down Expand Up @@ -137,6 +136,7 @@ This code is released under a BSD licence, as specified in the accompanying LICE

## Version History

* **4.20.1** Fixed: Inspection now checks for cancellation (#192).
* **4.20.1** Fixed: Rules accessed via HTTP no longer use temporary files (#67).
* **4.20.0** New: Updated to CheckStyle 6.11.2 (#189).
* **4.19.1** Fixed: Improved handling of unparsable files (#185).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static java.util.Collections.singletonList;
import static java.util.Optional.ofNullable;
import static org.infernus.idea.checkstyle.util.Async.asyncResultOf;

public class CheckStyleInspection extends LocalInspectionTool {

private static final Log LOG = LogFactory.getLog(CheckStyleInspection.class);
private static final ProblemDescriptor[] NO_PROBLEMS_FOUND = null;
private static final List<Problem> NO_PROBLEMS_FOUND = Collections.emptyList();

private final CheckStyleInspectionPanel configPanel = new CheckStyleInspectionPanel();

Expand All @@ -49,10 +50,16 @@ public JComponent createOptionsPanel() {
return configPanel;
}

@Nullable
@Override
public ProblemDescriptor[] checkFile(@NotNull final PsiFile psiFile,
@NotNull final InspectionManager manager,
final boolean isOnTheFly) {
return asProblemDescriptors(asyncResultOf(() -> inspectFile(psiFile, manager), NO_PROBLEMS_FOUND), manager);
}

@Nullable
public List<Problem> inspectFile(@NotNull final PsiFile psiFile,
@NotNull final InspectionManager manager) {
LOG.debug("Inspection has been invoked.");

final CheckStylePlugin plugin = plugin(manager.getProject());
Expand All @@ -69,12 +76,11 @@ public ProblemDescriptor[] checkFile(@NotNull final PsiFile psiFile,

scannableFiles.addAll(ScannableFile.createAndValidate(singletonList(psiFile), plugin, module));

return asArray(checkerFactory(psiFile.getProject())
return checkerFactory(psiFile.getProject())
.checker(module, configurationLocation)
.map(checker -> checker.scan(scannableFiles, plugin.getConfiguration()))
.map(results -> results.get(psiFile))
.map(results -> asProblemDescriptors(results, manager))
.orElseGet(Collections::emptyList));
.orElseGet(() -> NO_PROBLEMS_FOUND);

} catch (ProcessCanceledException | AssertionError e) {
LOG.debug("Process cancelled when scanning: " + psiFile.getName());
Expand Down Expand Up @@ -104,25 +110,22 @@ private void blacklist(final ConfigurationLocation configurationLocation) {
}
}

private List<ProblemDescriptor> asProblemDescriptors(final List<Problem> results, final InspectionManager manager) {
return results.stream()
.map(problem -> problem.toProblemDescriptor(manager))
.collect(Collectors.toList());
@NotNull
private ProblemDescriptor[] asProblemDescriptors(final List<Problem> results, final InspectionManager manager) {
return ofNullable(results)
.map(problems -> problems.stream()
.map(problem -> problem.toProblemDescriptor(manager))
.toArray(ProblemDescriptor[]::new))
.orElseGet(() -> ProblemDescriptor.EMPTY_ARRAY);
}

private Module moduleOf(@NotNull final PsiFile psiFile) {
return ModuleUtil.findModuleForPsiElement(psiFile);
}

private ProblemDescriptor[] asArray(final List<ProblemDescriptor> problems) {
if (problems != null) {
return problems.toArray(new ProblemDescriptor[problems.size()]);
}
return NO_PROBLEMS_FOUND;
}

private CheckerFactory checkerFactory(final Project project) {
return ServiceManager.getService(project, CheckerFactory.class);
}


}
44 changes: 44 additions & 0 deletions src/main/java/org/infernus/idea/checkstyle/util/Async.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.infernus.idea.checkstyle.util;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;

public class Async {
private static final int FIFTY_MS = 50;

@Nullable
public static <T> T asyncResultOf(@NotNull final Callable<T> callable,
@Nullable final T defaultValue) {
try {
return whenFinished(executeOnPooledThread(callable)).get();

} catch (Exception e) {
return defaultValue;
}
}

private static <T> Future<T> executeOnPooledThread(final Callable<T> callable) {
return ApplicationManager.getApplication().executeOnPooledThread(callable);
}

private static <T> Future<T> whenFinished(final Future<T> future) {
while (!future.isDone() && !future.isCancelled()) {
ProgressManager.checkCanceled();
waitFor(FIFTY_MS);
}
return future;
}

private static void waitFor(final int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException ignored) {
// ignored
}
}
}
1 change: 1 addition & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<change-notes>
<![CDATA[
<ul>
<li>4.20.1: Fixed: Inspection now checks for cancellation (#192).</li>
<li>4.20.1: Fixed: Rules accessed via HTTP no longer use temporary files (#67).</li>
<li>4.20.0: New: Updated to CheckStyle 6.11.2 (#189).</li>
<li>4.19.1: Fixed: Improved handling of unparsable files (#185).</li>
Expand Down

0 comments on commit dd95b20

Please sign in to comment.