mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -664,8 +664,9 @@ def setPluginVersionAndSince(String moduleName, String version) {
|
||||
if (file.isFile()) {
|
||||
def text = file.text
|
||||
if (!text.contains("<version>")) {
|
||||
def nextMajorVersion = Integer.parseInt(version.substring(0, version.indexOf('.'))) + 1
|
||||
file.text = text.replace("</id>", "</id>\n <version>${version}</version>\n <idea-version since-build=\"${version}\" until-build=\"${nextMajorVersion}.0\"/>\n")
|
||||
def dotIndex = version.indexOf('.')
|
||||
def untilBuild = dotIndex > 0 ? (Integer.parseInt(version.substring(0, dotIndex)) + 1).toString() + ".0" : version
|
||||
file.text = text.replace("</id>", "</id>\n <version>${version}</version>\n <idea-version since-build=\"${version}\" until-build=\"${untilBuild}\"/>\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -740,7 +740,7 @@ public class GenericsHighlightUtil {
|
||||
if (type instanceof PsiClassType && ((PsiClassType)type).resolve() == aClass) return null;
|
||||
}
|
||||
|
||||
if (PsiUtil.isCompileTimeConstant(field)) return null;
|
||||
if (PsiUtil.isCompileTimeConstant((PsiVariable)field)) return null;
|
||||
|
||||
String description = JavaErrorMessages.message(
|
||||
"illegal.to.access.static.member.from.enum.constructor.or.instance.initializer",
|
||||
|
||||
+1
-1
@@ -292,7 +292,7 @@ public class HighlightClassUtil {
|
||||
}
|
||||
|
||||
PsiField field = (PsiField)keyword.getParent().getParent();
|
||||
if (PsiUtilCore.hasErrorElementChild(field) || PsiUtil.isCompileTimeConstant(field)) {
|
||||
if (PsiUtilCore.hasErrorElementChild(field) || PsiUtil.isCompileTimeConstant((PsiVariable)field)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.intellij.codeInsight.ExternalAnnotationsManager;
|
||||
import com.intellij.codeInsight.InferredAnnotationsManager;
|
||||
import com.intellij.codeInsight.documentation.DocumentationManagerProtocol;
|
||||
import com.intellij.codeInsight.documentation.DocumentationManagerUtil;
|
||||
import com.intellij.javadoc.JavadocConfiguration;
|
||||
import com.intellij.javadoc.JavadocGeneratorRunProfile;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.LangBundle;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -233,7 +233,7 @@ public class JavaDocInfoGenerator {
|
||||
myProject = project;
|
||||
myElement = element;
|
||||
|
||||
Sdk jdk = JavadocConfiguration.getSdk(myProject);
|
||||
Sdk jdk = JavadocGeneratorRunProfile.getSdk(myProject);
|
||||
mySdkVersion = jdk == null ? null : JavaSdk.getInstance().getVersion(jdk);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
package com.intellij.javadoc;
|
||||
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.JavadocOrderRootType;
|
||||
import com.intellij.psi.PsiKeyword;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -24,14 +27,21 @@ import java.io.File;
|
||||
public final class JavadocConfigurable implements Configurable {
|
||||
private JavadocGenerationPanel myPanel;
|
||||
private final JavadocConfiguration myConfiguration;
|
||||
private final Project myProject;
|
||||
|
||||
public JavadocConfigurable(JavadocConfiguration configuration) {
|
||||
public JavadocConfigurable(JavadocConfiguration configuration, Project project) {
|
||||
myConfiguration = configuration;
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
public static boolean sdkHasJavadocUrls(Project project) {
|
||||
Sdk sdk = JavadocGeneratorRunProfile.getSdk(project);
|
||||
return sdk != null && sdk.getRootProvider().getFiles(JavadocOrderRootType.getInstance()).length > 0;
|
||||
}
|
||||
|
||||
public JComponent createComponent() {
|
||||
myPanel = new JavadocGenerationPanel();
|
||||
myPanel.myLinkToJdkDocs.setEnabled(myConfiguration.sdkHasJavadocUrls());
|
||||
myPanel.myLinkToJdkDocs.setEnabled(sdkHasJavadocUrls(myProject));
|
||||
return myPanel.myPanel;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,57 +15,21 @@
|
||||
*/
|
||||
package com.intellij.javadoc;
|
||||
|
||||
import com.intellij.analysis.AnalysisScope;
|
||||
import com.intellij.execution.CantRunException;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.Executor;
|
||||
import com.intellij.execution.configurations.*;
|
||||
import com.intellij.execution.filters.RegexpFilter;
|
||||
import com.intellij.execution.process.OSProcessHandler;
|
||||
import com.intellij.execution.process.ProcessAdapter;
|
||||
import com.intellij.execution.process.ProcessEvent;
|
||||
import com.intellij.execution.process.ProcessTerminatedListener;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.ide.BrowserUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdk;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkType;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.ex.PathUtilEx;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.PathsList;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.openapi.util.DefaultJDOMExternalizer;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.JDOMExternalizable;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.psi.PsiKeyword;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Apr 24, 2004
|
||||
*/
|
||||
public class JavadocConfiguration implements ModuleRunProfile, JDOMExternalizable{
|
||||
public class JavadocConfiguration implements JDOMExternalizable {
|
||||
public String OUTPUT_DIRECTORY;
|
||||
public String OPTION_SCOPE = PsiKeyword.PROTECTED;
|
||||
public boolean OPTION_HIERARCHY = true;
|
||||
@@ -81,46 +45,10 @@ public class JavadocConfiguration implements ModuleRunProfile, JDOMExternalizabl
|
||||
public String HEAP_SIZE;
|
||||
public String LOCALE;
|
||||
public boolean OPEN_IN_BROWSER = true;
|
||||
|
||||
private final Project myProject;
|
||||
private AnalysisScope myGenerationScope;
|
||||
private static final Logger LOGGER = Logger.getInstance("#" + JavadocConfiguration.class.getName());
|
||||
public boolean OPTION_INCLUDE_LIBS = false;
|
||||
public boolean OPTION_LINK_TO_JDK_DOCS = false;
|
||||
|
||||
public void setGenerationScope(AnalysisScope generationScope) {
|
||||
myGenerationScope = generationScope;
|
||||
}
|
||||
|
||||
public JavadocConfiguration(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
public RunProfileState getState(@NotNull final Executor executor, @NotNull final ExecutionEnvironment env) throws ExecutionException {
|
||||
return new MyJavaCommandLineState(myProject, myGenerationScope, env);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return JavadocBundle.message("javadoc.settings.title");
|
||||
}
|
||||
|
||||
public void checkConfiguration() throws RuntimeConfigurationException {
|
||||
if (myGenerationScope == null) {
|
||||
throw new RuntimeConfigurationError(JavadocBundle.message("javadoc.settings.not.specified"));
|
||||
}
|
||||
}
|
||||
|
||||
public JavadocConfigurable createConfigurable() {
|
||||
return new JavadocConfigurable(this);
|
||||
}
|
||||
|
||||
public Icon getIcon() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Module[] getModules() {
|
||||
return Module.EMPTY_ARRAY;
|
||||
public JavadocConfiguration() {
|
||||
}
|
||||
|
||||
public void readExternal(Element element) throws InvalidDataException {
|
||||
@@ -128,280 +56,12 @@ public class JavadocConfiguration implements ModuleRunProfile, JDOMExternalizabl
|
||||
}
|
||||
|
||||
public void writeExternal(Element element) throws WriteExternalException {
|
||||
DefaultJDOMExternalizer.writeExternal(this, element);
|
||||
}
|
||||
|
||||
public boolean sdkHasJavadocUrls() {
|
||||
Sdk sdk = getSdk(myProject);
|
||||
return sdk != null && sdk.getRootProvider().getFiles(JavadocOrderRootType.getInstance()).length > 0;
|
||||
}
|
||||
|
||||
public static Sdk getSdk(@NotNull Project project) {
|
||||
return PathUtilEx.getAnyJdk(project);
|
||||
}
|
||||
|
||||
private class MyJavaCommandLineState extends CommandLineState {
|
||||
private final AnalysisScope myGenerationOptions;
|
||||
private final Project myProject;
|
||||
@NonNls private static final String INDEX_HTML = "index.html";
|
||||
|
||||
public MyJavaCommandLineState(Project project, AnalysisScope generationOptions, ExecutionEnvironment env) {
|
||||
super(env);
|
||||
myGenerationOptions = generationOptions;
|
||||
myProject = project;
|
||||
addConsoleFilters(new RegexpFilter(project, "$FILE_PATH$:$LINE$:[^\\^]+\\^"),
|
||||
new RegexpFilter(project, "$FILE_PATH$:$LINE$: warning - .+$"));
|
||||
}
|
||||
|
||||
protected GeneralCommandLine createCommandLine() throws ExecutionException {
|
||||
final GeneralCommandLine cmdLine = new GeneralCommandLine();
|
||||
final Sdk jdk = getSdk(myProject);
|
||||
setupExeParams(jdk, cmdLine);
|
||||
setupProgramParameters(jdk, cmdLine);
|
||||
return cmdLine;
|
||||
}
|
||||
|
||||
private void setupExeParams(final Sdk jdk, GeneralCommandLine cmdLine) throws ExecutionException {
|
||||
final String jdkPath = jdk != null && jdk.getSdkType() instanceof JavaSdkType ? ((JavaSdkType)jdk.getSdkType()).getBinPath(jdk) : null;
|
||||
if (jdkPath == null) {
|
||||
throw new CantRunException(JavadocBundle.message("javadoc.generate.no.jdk.path"));
|
||||
DefaultJDOMExternalizer.writeExternal(this, element, new DefaultJDOMExternalizer.JDOMFilter() {
|
||||
@Override
|
||||
public boolean isAccept(@NotNull Field field) {
|
||||
return !field.getName().equals("OPTION_LINK_TO_JDK_DOCS") || OPTION_LINK_TO_JDK_DOCS;
|
||||
}
|
||||
JavaSdkVersion version = JavaSdk.getInstance().getVersion(jdk);
|
||||
if (HEAP_SIZE != null && HEAP_SIZE.trim().length() != 0) {
|
||||
if (version == null || version.isAtLeast(JavaSdkVersion.JDK_1_2)) {
|
||||
cmdLine.getParametersList().prepend("-J-Xmx" + HEAP_SIZE + "m");
|
||||
}
|
||||
else {
|
||||
cmdLine.getParametersList().prepend("-J-mx" + HEAP_SIZE + "m");
|
||||
}
|
||||
}
|
||||
cmdLine.setWorkDirectory((File)null);
|
||||
@NonNls final String javadocExecutableName = File.separator + (SystemInfo.isWindows ? "javadoc.exe" : "javadoc");
|
||||
@NonNls String exePath = jdkPath.replace('/', File.separatorChar) + javadocExecutableName;
|
||||
if (new File(exePath).exists()) {
|
||||
cmdLine.setExePath(exePath);
|
||||
} else { //try to use wrapper jdk
|
||||
exePath = new File(jdkPath).getParent().replace('/', File.separatorChar) + javadocExecutableName;
|
||||
if (!new File(exePath).exists()){
|
||||
final File parent = new File(System.getProperty("java.home")).getParentFile(); //try system jre
|
||||
exePath = parent.getPath() + File.separator + "bin" + javadocExecutableName;
|
||||
if (!new File(exePath).exists()){
|
||||
throw new CantRunException(JavadocBundle.message("javadoc.generate.no.jdk.path"));
|
||||
}
|
||||
}
|
||||
cmdLine.setExePath(exePath);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupProgramParameters(final Sdk jdk, final GeneralCommandLine cmdLine) throws CantRunException {
|
||||
@NonNls final ParametersList parameters = cmdLine.getParametersList();
|
||||
|
||||
if (LOCALE != null && LOCALE.length() > 0) {
|
||||
parameters.add("-locale");
|
||||
parameters.add(LOCALE);
|
||||
}
|
||||
|
||||
if (OPTION_SCOPE != null) {
|
||||
parameters.add("-" + OPTION_SCOPE);
|
||||
}
|
||||
|
||||
if (!OPTION_HIERARCHY) {
|
||||
parameters.add("-notree");
|
||||
}
|
||||
|
||||
if (!OPTION_NAVIGATOR) {
|
||||
parameters.add("-nonavbar");
|
||||
}
|
||||
|
||||
if (!OPTION_INDEX) {
|
||||
parameters.add("-noindex");
|
||||
}
|
||||
else if (OPTION_SEPARATE_INDEX) {
|
||||
parameters.add("-splitindex");
|
||||
}
|
||||
|
||||
if (OPTION_DOCUMENT_TAG_USE) {
|
||||
parameters.add("-use");
|
||||
}
|
||||
|
||||
if (OPTION_DOCUMENT_TAG_AUTHOR) {
|
||||
parameters.add("-author");
|
||||
}
|
||||
|
||||
if (OPTION_DOCUMENT_TAG_VERSION) {
|
||||
parameters.add("-version");
|
||||
}
|
||||
|
||||
if (!OPTION_DOCUMENT_TAG_DEPRECATED) {
|
||||
parameters.add("-nodeprecated");
|
||||
}
|
||||
else if (!OPTION_DEPRECATED_LIST) {
|
||||
parameters.add("-nodeprecatedlist");
|
||||
}
|
||||
|
||||
parameters.addParametersString(OTHER_OPTIONS);
|
||||
|
||||
final Set<Module> modules = new LinkedHashSet<Module>();
|
||||
try {
|
||||
final File sourcePathTempFile = FileUtil.createTempFile("javadoc", "args.txt", true);
|
||||
parameters.add("@" + sourcePathTempFile.getCanonicalPath());
|
||||
final PrintWriter writer = new PrintWriter(new FileWriter(sourcePathTempFile));
|
||||
try {
|
||||
final Collection<String> packages = new HashSet<String>();
|
||||
final Collection<String> sources = new HashSet<String>();
|
||||
final Runnable findRunnable = new Runnable() {
|
||||
public void run() {
|
||||
final int scopeType = myGenerationOptions.getScopeType();
|
||||
final boolean usePackageNotation = scopeType == AnalysisScope.MODULE ||
|
||||
scopeType == AnalysisScope.MODULES ||
|
||||
scopeType == AnalysisScope.PROJECT ||
|
||||
scopeType == AnalysisScope.DIRECTORY;
|
||||
myGenerationOptions.accept(new MyContentIterator(myProject, packages, sources, modules, usePackageNotation));
|
||||
}
|
||||
};
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(findRunnable, "Search for sources to generate javadoc in...", true, myProject)) {
|
||||
return;
|
||||
}
|
||||
if (packages.size() + sources.size() == 0) {
|
||||
throw new CantRunException(JavadocBundle.message("javadoc.generate.no.classes.in.selected.packages.error"));
|
||||
}
|
||||
for (String aPackage : packages) {
|
||||
writer.println(aPackage);
|
||||
}
|
||||
//http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#runningjavadoc
|
||||
for (String source : sources) {
|
||||
writer.println(StringUtil.wrapWithDoubleQuote(source));
|
||||
}
|
||||
writer.println("-sourcepath");
|
||||
OrderEnumerator enumerator = OrderEnumerator.orderEntries(myProject);
|
||||
if (!OPTION_INCLUDE_LIBS) {
|
||||
enumerator = enumerator.withoutSdk().withoutLibraries();
|
||||
}
|
||||
final PathsList pathsList = enumerator.getSourcePathsList();
|
||||
final List<VirtualFile> files = pathsList.getRootDirs();
|
||||
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
|
||||
final StringBuilder sourcePath = new StringBuilder();
|
||||
boolean start = true;
|
||||
for (VirtualFile file : files) {
|
||||
if (!myGenerationOptions.isIncludeTestSource() && fileIndex.isInTestSourceContent(file)) continue;
|
||||
if (start) {
|
||||
start = false;
|
||||
}
|
||||
else {
|
||||
sourcePath.append(File.pathSeparator);
|
||||
}
|
||||
sourcePath.append(file.getPath());
|
||||
}
|
||||
writer.println(StringUtil.wrapWithDoubleQuote(sourcePath.toString()));
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
|
||||
if (OPTION_LINK_TO_JDK_DOCS) {
|
||||
VirtualFile[] docUrls = jdk.getRootProvider().getFiles(JavadocOrderRootType.getInstance());
|
||||
for (VirtualFile docUrl : docUrls) {
|
||||
parameters.add("-link");
|
||||
parameters.add(VfsUtil.toUri(docUrl).toString());
|
||||
}
|
||||
}
|
||||
|
||||
final PathsList classPath;
|
||||
final OrderEnumerator orderEnumerator = ProjectRootManager.getInstance(myProject).orderEntries(modules);
|
||||
if (jdk.getSdkType() instanceof JavaSdk) {
|
||||
classPath = orderEnumerator.withoutSdk().withoutModuleSourceEntries().getPathsList();
|
||||
}
|
||||
else {
|
||||
//libraries are included into jdk
|
||||
classPath = orderEnumerator.withoutModuleSourceEntries().getPathsList();
|
||||
}
|
||||
final String classPathString = classPath.getPathsString();
|
||||
if (classPathString.length() > 0) {
|
||||
parameters.add("-classpath");
|
||||
parameters.add(classPathString);
|
||||
}
|
||||
|
||||
if (OUTPUT_DIRECTORY != null) {
|
||||
parameters.add("-d");
|
||||
parameters.add(OUTPUT_DIRECTORY.replace('/', File.separatorChar));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected OSProcessHandler startProcess() throws ExecutionException {
|
||||
final OSProcessHandler handler = JavaCommandLineStateUtil.startProcess(createCommandLine());
|
||||
ProcessTerminatedListener.attach(handler, myProject, JavadocBundle.message("javadoc.generate.exited"));
|
||||
handler.addProcessListener(new ProcessAdapter() {
|
||||
public void processTerminated(ProcessEvent event) {
|
||||
if (OPEN_IN_BROWSER) {
|
||||
File url = new File(OUTPUT_DIRECTORY, INDEX_HTML);
|
||||
if (url.exists() && event.getExitCode() == 0) {
|
||||
BrowserUtil.browse(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyContentIterator extends PsiRecursiveElementWalkingVisitor {
|
||||
private final PsiManager myPsiManager;
|
||||
private final Collection<String> myPackages;
|
||||
private final Collection<String> mySourceFiles;
|
||||
private final Set<Module> myModules;
|
||||
private final boolean myUsePackageNotation;
|
||||
|
||||
public MyContentIterator(Project project,
|
||||
Collection<String> packages,
|
||||
Collection<String> sources,
|
||||
Set<Module> modules,
|
||||
boolean canUsePackageNotation) {
|
||||
myModules = modules;
|
||||
myUsePackageNotation = canUsePackageNotation;
|
||||
myPsiManager = PsiManager.getInstance(project);
|
||||
myPackages = packages;
|
||||
mySourceFiles = sources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFile(PsiFile file) {
|
||||
final VirtualFile fileOrDir = file.getVirtualFile();
|
||||
if (fileOrDir == null) return;
|
||||
if (!fileOrDir.isInLocalFileSystem()) return;
|
||||
final Module module = ModuleUtilCore.findModuleForFile(fileOrDir, myPsiManager.getProject());
|
||||
if (module != null) {
|
||||
myModules.add(module);
|
||||
}
|
||||
if (file instanceof PsiJavaFile) {
|
||||
final PsiJavaFile javaFile = (PsiJavaFile)file;
|
||||
final String packageName = javaFile.getPackageName();
|
||||
if (containsPackagePrefix(module, packageName) || (packageName.length() == 0 && !(javaFile instanceof ServerPageFile)) || !myUsePackageNotation) {
|
||||
mySourceFiles.add(FileUtil.toSystemIndependentName(fileOrDir.getPath()));
|
||||
}
|
||||
else {
|
||||
myPackages.add(packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean containsPackagePrefix(Module module, String packageFQName) {
|
||||
if (module == null) return false;
|
||||
for (ContentEntry contentEntry : ModuleRootManager.getInstance(module).getContentEntries()) {
|
||||
for (SourceFolder sourceFolder : contentEntry.getSourceFolders(JavaModuleSourceRootTypes.SOURCES)) {
|
||||
final String packagePrefix = sourceFolder.getPackagePrefix();
|
||||
final int prefixLength = packagePrefix.length();
|
||||
if (prefixLength > 0 && packageFQName.startsWith(packagePrefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.intellij.analysis.AnalysisScope;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.executors.DefaultRunExecutor;
|
||||
import com.intellij.execution.runners.ExecutionEnvironmentBuilder;
|
||||
import com.intellij.execution.runners.ExecutionUtil;
|
||||
import com.intellij.execution.util.ExecutionErrorDialog;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -48,7 +47,7 @@ public final class JavadocGenerationManager implements PersistentStateComponent<
|
||||
|
||||
JavadocGenerationManager(Project project) {
|
||||
myProject = project;
|
||||
myConfiguration = new JavadocConfiguration(project);
|
||||
myConfiguration = new JavadocConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,9 +77,9 @@ public final class JavadocGenerationManager implements PersistentStateComponent<
|
||||
}
|
||||
|
||||
public void generateJavadoc(AnalysisScope scope) {
|
||||
myConfiguration.setGenerationScope(scope);
|
||||
try {
|
||||
ExecutionEnvironmentBuilder.create(myProject, DefaultRunExecutor.getRunExecutorInstance(), myConfiguration).buildAndExecute();
|
||||
JavadocGeneratorRunProfile profile = new JavadocGeneratorRunProfile(myProject, scope, myConfiguration);
|
||||
ExecutionEnvironmentBuilder.create(myProject, DefaultRunExecutor.getRunExecutorInstance(), profile).buildAndExecute();
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
ExecutionErrorDialog.show(e, CommonBundle.getErrorTitle(), myProject);
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.javadoc;
|
||||
|
||||
import com.intellij.analysis.AnalysisScope;
|
||||
import com.intellij.execution.CantRunException;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.Executor;
|
||||
import com.intellij.execution.configurations.*;
|
||||
import com.intellij.execution.filters.RegexpFilter;
|
||||
import com.intellij.execution.process.OSProcessHandler;
|
||||
import com.intellij.execution.process.ProcessAdapter;
|
||||
import com.intellij.execution.process.ProcessEvent;
|
||||
import com.intellij.execution.process.ProcessTerminatedListener;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.ide.BrowserUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdk;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkType;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.ex.PathUtilEx;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.PathsList;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class JavadocGeneratorRunProfile implements ModuleRunProfile {
|
||||
private static final Logger LOGGER = Logger.getInstance("#" + JavadocConfiguration.class.getName());
|
||||
private final Project myProject;
|
||||
private final AnalysisScope myGenerationScope;
|
||||
private final JavadocConfiguration myConfiguration;
|
||||
|
||||
public JavadocGeneratorRunProfile(Project project, AnalysisScope generationScope, JavadocConfiguration configuration) {
|
||||
myProject = project;
|
||||
myGenerationScope = generationScope;
|
||||
myConfiguration = configuration;
|
||||
}
|
||||
|
||||
public static Sdk getSdk(@NotNull Project project) {
|
||||
return PathUtilEx.getAnyJdk(project);
|
||||
}
|
||||
|
||||
public RunProfileState getState(@NotNull final Executor executor, @NotNull final ExecutionEnvironment env) throws ExecutionException {
|
||||
return new MyJavaCommandLineState(myConfiguration, myProject, myGenerationScope, env);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return JavadocBundle.message("javadoc.settings.title");
|
||||
}
|
||||
|
||||
public Icon getIcon() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Module[] getModules() {
|
||||
return Module.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
private static class MyJavaCommandLineState extends CommandLineState {
|
||||
private final AnalysisScope myGenerationOptions;
|
||||
private final Project myProject;
|
||||
@NonNls private static final String INDEX_HTML = "index.html";
|
||||
private JavadocConfiguration myConfiguration;
|
||||
|
||||
public MyJavaCommandLineState(final JavadocConfiguration configuration,
|
||||
Project project,
|
||||
AnalysisScope generationOptions,
|
||||
ExecutionEnvironment env) {
|
||||
super(env);
|
||||
myGenerationOptions = generationOptions;
|
||||
myProject = project;
|
||||
addConsoleFilters(new RegexpFilter(project, "$FILE_PATH$:$LINE$:[^\\^]+\\^"),
|
||||
new RegexpFilter(project, "$FILE_PATH$:$LINE$: warning - .+$"));
|
||||
this.myConfiguration = configuration;
|
||||
}
|
||||
|
||||
protected GeneralCommandLine createCommandLine() throws ExecutionException {
|
||||
final GeneralCommandLine cmdLine = new GeneralCommandLine();
|
||||
final Sdk jdk = getSdk(myProject);
|
||||
setupExeParams(jdk, cmdLine);
|
||||
setupProgramParameters(jdk, cmdLine);
|
||||
return cmdLine;
|
||||
}
|
||||
|
||||
private void setupExeParams(final Sdk jdk, GeneralCommandLine cmdLine) throws ExecutionException {
|
||||
final String jdkPath =
|
||||
jdk != null && jdk.getSdkType() instanceof JavaSdkType ? ((JavaSdkType)jdk.getSdkType()).getBinPath(jdk) : null;
|
||||
if (jdkPath == null) {
|
||||
throw new CantRunException(JavadocBundle.message("javadoc.generate.no.jdk.path"));
|
||||
}
|
||||
JavaSdkVersion version = JavaSdk.getInstance().getVersion(jdk);
|
||||
if (myConfiguration.HEAP_SIZE != null && myConfiguration.HEAP_SIZE.trim().length() != 0) {
|
||||
if (version == null || version.isAtLeast(JavaSdkVersion.JDK_1_2)) {
|
||||
cmdLine.getParametersList().prepend("-J-Xmx" + myConfiguration.HEAP_SIZE + "m");
|
||||
}
|
||||
else {
|
||||
cmdLine.getParametersList().prepend("-J-mx" + myConfiguration.HEAP_SIZE + "m");
|
||||
}
|
||||
}
|
||||
cmdLine.setWorkDirectory((File)null);
|
||||
@NonNls final String javadocExecutableName = File.separator + (SystemInfo.isWindows ? "javadoc.exe" : "javadoc");
|
||||
@NonNls String exePath = jdkPath.replace('/', File.separatorChar) + javadocExecutableName;
|
||||
if (new File(exePath).exists()) {
|
||||
cmdLine.setExePath(exePath);
|
||||
}
|
||||
else { //try to use wrapper jdk
|
||||
exePath = new File(jdkPath).getParent().replace('/', File.separatorChar) + javadocExecutableName;
|
||||
if (!new File(exePath).exists()) {
|
||||
final File parent = new File(System.getProperty("java.home")).getParentFile(); //try system jre
|
||||
exePath = parent.getPath() + File.separator + "bin" + javadocExecutableName;
|
||||
if (!new File(exePath).exists()) {
|
||||
throw new CantRunException(JavadocBundle.message("javadoc.generate.no.jdk.path"));
|
||||
}
|
||||
}
|
||||
cmdLine.setExePath(exePath);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupProgramParameters(final Sdk jdk, final GeneralCommandLine cmdLine) throws CantRunException {
|
||||
@NonNls final ParametersList parameters = cmdLine.getParametersList();
|
||||
|
||||
if (myConfiguration.LOCALE != null && myConfiguration.LOCALE.length() > 0) {
|
||||
parameters.add("-locale");
|
||||
parameters.add(myConfiguration.LOCALE);
|
||||
}
|
||||
|
||||
if (myConfiguration.OPTION_SCOPE != null) {
|
||||
parameters.add("-" + myConfiguration.OPTION_SCOPE);
|
||||
}
|
||||
|
||||
if (!myConfiguration.OPTION_HIERARCHY) {
|
||||
parameters.add("-notree");
|
||||
}
|
||||
|
||||
if (!myConfiguration.OPTION_NAVIGATOR) {
|
||||
parameters.add("-nonavbar");
|
||||
}
|
||||
|
||||
if (!myConfiguration.OPTION_INDEX) {
|
||||
parameters.add("-noindex");
|
||||
}
|
||||
else if (myConfiguration.OPTION_SEPARATE_INDEX) {
|
||||
parameters.add("-splitindex");
|
||||
}
|
||||
|
||||
if (myConfiguration.OPTION_DOCUMENT_TAG_USE) {
|
||||
parameters.add("-use");
|
||||
}
|
||||
|
||||
if (myConfiguration.OPTION_DOCUMENT_TAG_AUTHOR) {
|
||||
parameters.add("-author");
|
||||
}
|
||||
|
||||
if (myConfiguration.OPTION_DOCUMENT_TAG_VERSION) {
|
||||
parameters.add("-version");
|
||||
}
|
||||
|
||||
if (!myConfiguration.OPTION_DOCUMENT_TAG_DEPRECATED) {
|
||||
parameters.add("-nodeprecated");
|
||||
}
|
||||
else if (!myConfiguration.OPTION_DEPRECATED_LIST) {
|
||||
parameters.add("-nodeprecatedlist");
|
||||
}
|
||||
|
||||
parameters.addParametersString(myConfiguration.OTHER_OPTIONS);
|
||||
|
||||
final Set<Module> modules = new LinkedHashSet<Module>();
|
||||
try {
|
||||
final File sourcePathTempFile = FileUtil.createTempFile("javadoc", "args.txt", true);
|
||||
parameters.add("@" + sourcePathTempFile.getCanonicalPath());
|
||||
final PrintWriter writer = new PrintWriter(new FileWriter(sourcePathTempFile));
|
||||
try {
|
||||
final Collection<String> packages = new HashSet<String>();
|
||||
final Collection<String> sources = new HashSet<String>();
|
||||
final Runnable findRunnable = new Runnable() {
|
||||
public void run() {
|
||||
final int scopeType = myGenerationOptions.getScopeType();
|
||||
final boolean usePackageNotation = scopeType == AnalysisScope.MODULE ||
|
||||
scopeType == AnalysisScope.MODULES ||
|
||||
scopeType == AnalysisScope.PROJECT ||
|
||||
scopeType == AnalysisScope.DIRECTORY;
|
||||
myGenerationOptions.accept(new MyContentIterator(myProject, packages, sources, modules, usePackageNotation));
|
||||
}
|
||||
};
|
||||
if (!ProgressManager
|
||||
.getInstance()
|
||||
.runProcessWithProgressSynchronously(findRunnable, "Search for sources to generate javadoc in...", true, myProject)) {
|
||||
return;
|
||||
}
|
||||
if (packages.size() + sources.size() == 0) {
|
||||
throw new CantRunException(JavadocBundle.message("javadoc.generate.no.classes.in.selected.packages.error"));
|
||||
}
|
||||
for (String aPackage : packages) {
|
||||
writer.println(aPackage);
|
||||
}
|
||||
//http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#runningjavadoc
|
||||
for (String source : sources) {
|
||||
writer.println(StringUtil.wrapWithDoubleQuote(source));
|
||||
}
|
||||
writer.println("-sourcepath");
|
||||
OrderEnumerator enumerator = OrderEnumerator.orderEntries(myProject);
|
||||
if (!myConfiguration.OPTION_INCLUDE_LIBS) {
|
||||
enumerator = enumerator.withoutSdk().withoutLibraries();
|
||||
}
|
||||
final PathsList pathsList = enumerator.getSourcePathsList();
|
||||
final List<VirtualFile> files = pathsList.getRootDirs();
|
||||
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
|
||||
final StringBuilder sourcePath = new StringBuilder();
|
||||
boolean start = true;
|
||||
for (VirtualFile file : files) {
|
||||
if (!myGenerationOptions.isIncludeTestSource() && fileIndex.isInTestSourceContent(file)) continue;
|
||||
if (start) {
|
||||
start = false;
|
||||
}
|
||||
else {
|
||||
sourcePath.append(File.pathSeparator);
|
||||
}
|
||||
sourcePath.append(file.getPath());
|
||||
}
|
||||
writer.println(StringUtil.wrapWithDoubleQuote(sourcePath.toString()));
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
|
||||
if (myConfiguration.OPTION_LINK_TO_JDK_DOCS) {
|
||||
VirtualFile[] docUrls = jdk.getRootProvider().getFiles(JavadocOrderRootType.getInstance());
|
||||
for (VirtualFile docUrl : docUrls) {
|
||||
parameters.add("-link");
|
||||
parameters.add(VfsUtil.toUri(docUrl).toString());
|
||||
}
|
||||
}
|
||||
|
||||
final PathsList classPath;
|
||||
final OrderEnumerator orderEnumerator = ProjectRootManager.getInstance(myProject).orderEntries(modules);
|
||||
if (jdk.getSdkType() instanceof JavaSdk) {
|
||||
classPath = orderEnumerator.withoutSdk().withoutModuleSourceEntries().getPathsList();
|
||||
}
|
||||
else {
|
||||
//libraries are included into jdk
|
||||
classPath = orderEnumerator.withoutModuleSourceEntries().getPathsList();
|
||||
}
|
||||
final String classPathString = classPath.getPathsString();
|
||||
if (classPathString.length() > 0) {
|
||||
parameters.add("-classpath");
|
||||
parameters.add(classPathString);
|
||||
}
|
||||
|
||||
if (myConfiguration.OUTPUT_DIRECTORY != null) {
|
||||
parameters.add("-d");
|
||||
parameters.add(myConfiguration.OUTPUT_DIRECTORY.replace('/', File.separatorChar));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected OSProcessHandler startProcess() throws ExecutionException {
|
||||
final OSProcessHandler handler = JavaCommandLineStateUtil.startProcess(createCommandLine());
|
||||
ProcessTerminatedListener.attach(handler, myProject, JavadocBundle.message("javadoc.generate.exited"));
|
||||
handler.addProcessListener(new ProcessAdapter() {
|
||||
public void processTerminated(ProcessEvent event) {
|
||||
if (myConfiguration.OPEN_IN_BROWSER) {
|
||||
File url = new File(myConfiguration.OUTPUT_DIRECTORY, INDEX_HTML);
|
||||
if (url.exists() && event.getExitCode() == 0) {
|
||||
BrowserUtil.browse(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyContentIterator extends PsiRecursiveElementWalkingVisitor {
|
||||
private final PsiManager myPsiManager;
|
||||
private final Collection<String> myPackages;
|
||||
private final Collection<String> mySourceFiles;
|
||||
private final Set<Module> myModules;
|
||||
private final boolean myUsePackageNotation;
|
||||
|
||||
public MyContentIterator(Project project,
|
||||
Collection<String> packages,
|
||||
Collection<String> sources,
|
||||
Set<Module> modules,
|
||||
boolean canUsePackageNotation) {
|
||||
myModules = modules;
|
||||
myUsePackageNotation = canUsePackageNotation;
|
||||
myPsiManager = PsiManager.getInstance(project);
|
||||
myPackages = packages;
|
||||
mySourceFiles = sources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFile(PsiFile file) {
|
||||
final VirtualFile fileOrDir = file.getVirtualFile();
|
||||
if (fileOrDir == null) return;
|
||||
if (!fileOrDir.isInLocalFileSystem()) return;
|
||||
final Module module = ModuleUtilCore.findModuleForFile(fileOrDir, myPsiManager.getProject());
|
||||
if (module != null) {
|
||||
myModules.add(module);
|
||||
}
|
||||
if (file instanceof PsiJavaFile) {
|
||||
final PsiJavaFile javaFile = (PsiJavaFile)file;
|
||||
final String packageName = javaFile.getPackageName();
|
||||
if (containsPackagePrefix(module, packageName) ||
|
||||
(packageName.length() == 0 && !(javaFile instanceof ServerPageFile)) ||
|
||||
!myUsePackageNotation) {
|
||||
mySourceFiles.add(FileUtil.toSystemIndependentName(fileOrDir.getPath()));
|
||||
}
|
||||
else {
|
||||
myPackages.add(packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean containsPackagePrefix(Module module, String packageFQName) {
|
||||
if (module == null) return false;
|
||||
for (ContentEntry contentEntry : ModuleRootManager.getInstance(module).getContentEntries()) {
|
||||
for (SourceFolder sourceFolder : contentEntry.getSourceFolders(JavaModuleSourceRootTypes.SOURCES)) {
|
||||
final String packagePrefix = sourceFolder.getPackagePrefix();
|
||||
final int prefixLength = packagePrefix.length();
|
||||
if (prefixLength > 0 && packageFQName.startsWith(packagePrefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ public final class GenerateJavadocAction extends BaseAnalysisAction{
|
||||
|
||||
@Override
|
||||
protected JComponent getAdditionalActionSettings(Project project, final BaseAnalysisActionDialog dialog) {
|
||||
myConfigurable = JavadocGenerationManager.getInstance(project).getConfiguration().createConfigurable();
|
||||
myConfigurable = new JavadocConfigurable(JavadocGenerationManager.getInstance(project).getConfiguration(), project);
|
||||
final JComponent component = myConfigurable.createComponent();
|
||||
myConfigurable.reset();
|
||||
myConfigurable.getOutputDirField().getDocument().addDocumentListener(new DocumentAdapter() {
|
||||
|
||||
+24
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.refactoring.introduceField;
|
||||
|
||||
import com.intellij.codeInsight.completion.JavaCompletionUtil;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.help.HelpManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
@@ -32,6 +33,8 @@ import com.intellij.refactoring.ui.*;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.RefactoringMessageUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ui.update.Activatable;
|
||||
import com.intellij.util.ui.update.UiNotifyConnector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -147,7 +150,7 @@ class IntroduceFieldDialog extends DialogWrapper {
|
||||
gbConstraints.gridx = 0;
|
||||
gbConstraints.gridy = 0;
|
||||
|
||||
JLabel type = new JLabel(getTypeLabel());
|
||||
final JLabel type = new JLabel(getTypeLabel());
|
||||
|
||||
panel.add(type, gbConstraints);
|
||||
|
||||
@@ -163,7 +166,7 @@ class IntroduceFieldDialog extends DialogWrapper {
|
||||
gbConstraints.weighty = 1;
|
||||
gbConstraints.gridx = 0;
|
||||
gbConstraints.gridy = 1;
|
||||
JLabel namePrompt = new JLabel(RefactoringBundle.message("name.prompt"));
|
||||
final JLabel namePrompt = new JLabel(RefactoringBundle.message("name.prompt"));
|
||||
panel.add(namePrompt, gbConstraints);
|
||||
|
||||
gbConstraints.insets = new Insets(4, 0, 4, 4);
|
||||
@@ -180,10 +183,24 @@ class IntroduceFieldDialog extends DialogWrapper {
|
||||
});
|
||||
namePrompt.setLabelFor(myNameField.getFocusableComponent());
|
||||
|
||||
myNameSuggestionsManager = new NameSuggestionsManager(myTypeSelector, myNameField,
|
||||
createGenerator(myWillBeDeclaredStatic, myLocalVariable, myInitializerExpression, myIsInvokedOnDeclaration, myEnteredName,
|
||||
myParentClass, myProject));
|
||||
myNameSuggestionsManager.setLabelsFor(type, namePrompt);
|
||||
// We delay initialization of name field till dialog is shown, so that it will be executed in a different command and won't
|
||||
// be tied to any document changes performed in current command (and won't prevent undo for them later)
|
||||
new UiNotifyConnector.Once(panel, new Activatable.Adapter() {
|
||||
@Override
|
||||
public void showNotify() {
|
||||
myNameSuggestionsManager = new NameSuggestionsManager(myTypeSelector, myNameField,
|
||||
createGenerator(myWillBeDeclaredStatic, myLocalVariable,
|
||||
myInitializerExpression, myIsInvokedOnDeclaration,
|
||||
myEnteredName, myParentClass, myProject));
|
||||
myNameSuggestionsManager.setLabelsFor(type, namePrompt);
|
||||
|
||||
Editor editor = myNameField.getEditor();
|
||||
if (editor != null) {
|
||||
editor.getSelectionModel().setSelection(0, editor.getDocument().getTextLength());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
+8
-7
@@ -39,17 +39,17 @@ public class TypeMigrationReplacementUtil {
|
||||
private TypeMigrationReplacementUtil() {
|
||||
}
|
||||
|
||||
public static void replaceExpression(PsiExpression expression, final Project project, Object conversion) {
|
||||
public static PsiElement replaceExpression(PsiExpression expression, final Project project, Object conversion) {
|
||||
if (conversion instanceof TypeConversionDescriptorBase) {
|
||||
try {
|
||||
((TypeConversionDescriptorBase)conversion).replace(expression);
|
||||
return ((TypeConversionDescriptorBase)conversion).replace(expression);
|
||||
} catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
} else if (conversion instanceof String) {
|
||||
String replacement = (String)conversion;
|
||||
try {
|
||||
expression.replace(
|
||||
return expression.replace(
|
||||
JavaPsiFacade.getInstance(project).getElementFactory().createExpressionFromText(replacement, expression));
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
@@ -66,7 +66,7 @@ public class TypeMigrationReplacementUtil {
|
||||
if (conversion instanceof PsiMethod) {
|
||||
if (resolved instanceof PsiMethod) {
|
||||
try {
|
||||
expression.replace(
|
||||
return expression.replace(
|
||||
JavaPsiFacade.getInstance(project).getElementFactory().createExpressionFromText(newref, expression));
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
@@ -75,7 +75,7 @@ public class TypeMigrationReplacementUtil {
|
||||
}
|
||||
else {
|
||||
try {
|
||||
expression.replace(JavaPsiFacade.getInstance(project).getElementFactory().createExpressionFromText(
|
||||
return expression.replace(JavaPsiFacade.getInstance(project).getElementFactory().createExpressionFromText(
|
||||
newref + "()", expression));
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
@@ -86,7 +86,7 @@ public class TypeMigrationReplacementUtil {
|
||||
else if (conversion instanceof PsiField) {
|
||||
if (resolved instanceof PsiField) {
|
||||
try {
|
||||
expression.replace(
|
||||
return expression.replace(
|
||||
JavaPsiFacade.getInstance(project).getElementFactory().createExpressionFromText(newref, expression));
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
@@ -98,7 +98,7 @@ public class TypeMigrationReplacementUtil {
|
||||
|
||||
if (parent instanceof PsiMethodCallExpression) {
|
||||
try {
|
||||
parent.replace(
|
||||
return parent.replace(
|
||||
JavaPsiFacade.getInstance(project).getElementFactory().createExpressionFromText(newref, expression));
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
@@ -108,6 +108,7 @@ public class TypeMigrationReplacementUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
static void migratePsiMemberType(final PsiElement element, final Project project, PsiType migratedType) {
|
||||
|
||||
@@ -636,13 +636,16 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
return containingClass1 == null && containingClass2 == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use more generic {@link #isCompileTimeConstant(PsiVariable)} instead
|
||||
*/
|
||||
public static boolean isCompileTimeConstant(@NotNull final PsiField field) {
|
||||
return isCompileTimeConstant((PsiVariable)field);
|
||||
}
|
||||
|
||||
/**
|
||||
* JLS 15.28
|
||||
*/
|
||||
/**
|
||||
* JLS 15.28
|
||||
*/
|
||||
public static boolean isCompileTimeConstant(@NotNull final PsiVariable field) {
|
||||
return field.hasModifierProperty(PsiModifier.FINAL)
|
||||
&& (TypeConversionUtil.isPrimitiveAndNotNull(field.getType()) || field.getType().equalsToText(JAVA_LANG_STRING))
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaFluentIterableConversionRule"/>
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaFunctionConversionRule"/>
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaPredicateConversionRule"/>
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaSupplierConversionRule"/>
|
||||
<intentionAction>
|
||||
<className>com.intellij.refactoring.typeMigration.intentions.ConvertFieldToAtomicIntention</className>
|
||||
<category>Java/Concurrency</category>
|
||||
|
||||
+114
-1
@@ -15,21 +15,31 @@
|
||||
*/
|
||||
package com.intellij.refactoring.typeMigration.inspections;
|
||||
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.VariableTypeFix;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.openapi.command.undo.UndoUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.AtomicNotNullLazyValue;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.typeMigration.TypeMigrationVariableTypeFixProvider;
|
||||
import com.intellij.refactoring.typeMigration.*;
|
||||
import com.intellij.refactoring.typeMigration.rules.TypeConversionRule;
|
||||
import com.intellij.refactoring.typeMigration.rules.guava.BaseGuavaTypeConversionRule;
|
||||
import com.intellij.refactoring.typeMigration.rules.guava.GuavaFluentIterableConversionRule;
|
||||
import com.intellij.refactoring.typeMigration.rules.guava.GuavaFunctionConversionRule;
|
||||
import com.intellij.refactoring.typeMigration.rules.guava.GuavaOptionalConversionRule;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.hash.HashMap;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -43,6 +53,7 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool {
|
||||
private final static Logger LOG = Logger.getInstance(GuavaInspection.class);
|
||||
|
||||
private final static String PROBLEM_DESCRIPTION_FOR_VARIABLE = "Guava's functional primitives can be replaced by Java API";
|
||||
private final static String PROBLEM_DESCRIPTION_FOR_METHOD_CHAIN = "Guava's FluentIterable method chain can be replaced by Java API";
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -93,6 +104,54 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
|
||||
if (!isFluentIterableFromCall(expression)) return;
|
||||
|
||||
final PsiMethodCallExpression chain = findGuavaMethodChain(expression);
|
||||
|
||||
PsiClassType initialType = (PsiClassType)expression.getType();
|
||||
LOG.assertTrue(initialType != null);
|
||||
PsiClass resolvedClass = initialType.resolve();
|
||||
PsiClass target;
|
||||
if (resolvedClass == null || (target = myGuavaClassConversions.getValue().get(resolvedClass.getQualifiedName())) == null) {
|
||||
return;
|
||||
}
|
||||
PsiClassType targetType = addTypeParameters(initialType, initialType.resolveGenerics(), target);
|
||||
|
||||
holder.registerProblem(chain, PROBLEM_DESCRIPTION_FOR_METHOD_CHAIN, new MigrateFluentIterableChainQuickFix(chain, initialType, targetType));
|
||||
}
|
||||
|
||||
private boolean isFluentIterableFromCall(PsiMethodCallExpression expression) {
|
||||
PsiMethod method = expression.resolveMethod();
|
||||
if (method == null || !"from".equals(method.getName())) {
|
||||
return false;
|
||||
}
|
||||
PsiClass aClass = method.getContainingClass();
|
||||
return aClass != null && GuavaFluentIterableConversionRule.FLUENT_ITERABLE.equals(aClass.getQualifiedName());
|
||||
}
|
||||
|
||||
private PsiMethodCallExpression findGuavaMethodChain(PsiMethodCallExpression expression) {
|
||||
PsiMethodCallExpression chain = expression;
|
||||
while (true) {
|
||||
final PsiMethodCallExpression current = PsiTreeUtil.getParentOfType(chain, PsiMethodCallExpression.class);
|
||||
if (current != null && current.getMethodExpression().getQualifierExpression() == chain) {
|
||||
final PsiMethod method = current.resolveMethod();
|
||||
if (method == null) {
|
||||
return chain;
|
||||
}
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass == null || ! (GuavaFluentIterableConversionRule.FLUENT_ITERABLE.equals(containingClass.getQualifiedName())
|
||||
|| GuavaOptionalConversionRule.GUAVA_OPTIONAL.equals(containingClass.getQualifiedName()))) {
|
||||
return chain;
|
||||
}
|
||||
} else {
|
||||
return chain;
|
||||
}
|
||||
chain = current;
|
||||
}
|
||||
}
|
||||
|
||||
private PsiClassType addTypeParameters(PsiType currentType, PsiClassType.ClassResolveResult currentTypeResolveResult, PsiClass targetClass) {
|
||||
final Map<PsiTypeParameter, PsiType> substitutionMap = currentTypeResolveResult.getSubstitutor().getSubstitutionMap();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(holder.getProject());
|
||||
@@ -110,4 +169,58 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static class MigrateFluentIterableChainQuickFix extends LocalQuickFixAndIntentionActionOnPsiElement {
|
||||
private final PsiClassType myInitialType;
|
||||
private final PsiClassType myTargetType;
|
||||
|
||||
private MigrateFluentIterableChainQuickFix(@Nullable PsiElement element, PsiClassType initialType, PsiClassType targetType) {
|
||||
super(element);
|
||||
myInitialType = initialType;
|
||||
myTargetType = targetType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@Nullable("is null when called from inspection") Editor editor,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
|
||||
if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;
|
||||
try {
|
||||
final PsiMethodCallExpression expr = (PsiMethodCallExpression)startElement;
|
||||
final TypeMigrationRules rules = new TypeMigrationRules(myInitialType);
|
||||
rules.setMigrationRootType(myTargetType);
|
||||
rules.setBoundScope(GlobalSearchScope.fileScope(file));
|
||||
final TypeConversionDescriptorBase conversion =
|
||||
rules.findConversion(myInitialType, myTargetType, expr.resolveMethod(), expr, new TypeMigrationLabeler(rules));
|
||||
LOG.assertTrue(conversion != null);
|
||||
final PsiElement replacedExpression = TypeMigrationReplacementUtil.replaceExpression(expr, project, conversion);
|
||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(replacedExpression);
|
||||
UndoUtil.markPsiFileForUndo(file);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return getFamilyName();
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Replace FluentIterable method chain by Java API";
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-9
@@ -45,10 +45,10 @@ public abstract class BaseGuavaTypeConversionRule extends TypeConversionRule {
|
||||
protected void fillSimpleDescriptors(Map<String, TypeConversionDescriptorBase> descriptorsMap) {};
|
||||
|
||||
@Nullable
|
||||
protected TypeConversionDescriptorBase findConversionForMethod(@NotNull PsiType from,
|
||||
@NotNull PsiType to,
|
||||
protected TypeConversionDescriptorBase findConversionForMethod(PsiType from,
|
||||
PsiType to,
|
||||
@NotNull PsiMethod method,
|
||||
String methodName,
|
||||
@NotNull String methodName,
|
||||
PsiExpression context,
|
||||
TypeMigrationLabeler labeler) {
|
||||
return null;
|
||||
@@ -62,12 +62,12 @@ public abstract class BaseGuavaTypeConversionRule extends TypeConversionRule {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public final TypeConversionDescriptorBase findConversion(PsiType from,
|
||||
PsiType to,
|
||||
PsiMember member,
|
||||
PsiExpression context,
|
||||
TypeMigrationLabeler labeler) {
|
||||
if (!canConvert(from, to)) {
|
||||
public final TypeConversionDescriptorBase findConversion(@Nullable PsiType from,
|
||||
@Nullable PsiType to,
|
||||
PsiMember member,
|
||||
PsiExpression context,
|
||||
TypeMigrationLabeler labeler) {
|
||||
if (from != null && to != null && !canConvert(from, to)) {
|
||||
return null;
|
||||
}
|
||||
if (member instanceof PsiMethod) {
|
||||
|
||||
+50
-17
@@ -16,10 +16,12 @@
|
||||
package com.intellij.refactoring.typeMigration.rules.guava;
|
||||
|
||||
import com.intellij.codeInspection.java18StreamApi.StreamApiConstants;
|
||||
import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
|
||||
import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
|
||||
import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
|
||||
import com.intellij.refactoring.typeMigration.rules.TypeConversionRule;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.hash.HashMap;
|
||||
@@ -27,7 +29,6 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -106,11 +107,11 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
|
||||
protected TypeConversionDescriptorBase findConversionForMethod(@NotNull PsiType from,
|
||||
@NotNull PsiType to,
|
||||
@NotNull PsiMethod method,
|
||||
String methodName,
|
||||
@NotNull String methodName,
|
||||
PsiExpression context,
|
||||
TypeMigrationLabeler labeler) {
|
||||
if (context instanceof PsiMethodCallExpression) {
|
||||
return buildCompoundDescriptor((PsiMethodCallExpression)context, to);
|
||||
return buildCompoundDescriptor((PsiMethodCallExpression)context, to, labeler);
|
||||
}
|
||||
final TypeConversionDescriptorFactory base = DESCRIPTORS_MAP.get(methodName);
|
||||
if (base != null) {
|
||||
@@ -126,8 +127,23 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private GuavaChainedConversionDescriptor buildCompoundDescriptor(PsiMethodCallExpression expression, PsiType to) {
|
||||
List<TypeConversionDescriptor> methodDescriptors = new SmartList<TypeConversionDescriptor>();
|
||||
private static GuavaChainedConversionDescriptor buildCompoundDescriptor(PsiMethodCallExpression expression,
|
||||
PsiType to,
|
||||
TypeMigrationLabeler labeler) {
|
||||
List<TypeConversionDescriptorBase> methodDescriptors = new SmartList<TypeConversionDescriptorBase>();
|
||||
|
||||
NotNullLazyValue<TypeConversionRule> optionalDescriptor = new NotNullLazyValue<TypeConversionRule>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected TypeConversionRule compute() {
|
||||
for (TypeConversionRule rule : TypeConversionRule.EP_NAME.getExtensions()) {
|
||||
if (rule instanceof GuavaOptionalConversionRule) {
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("GuavaOptionalConversionRule extension is not found");
|
||||
}
|
||||
};
|
||||
|
||||
PsiMethodCallExpression current = expression;
|
||||
while (true) {
|
||||
@@ -137,15 +153,26 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
|
||||
}
|
||||
final String methodName = method.getName();
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
//TODO for optional too
|
||||
if (containingClass == null || !FLUENT_ITERABLE.equals(containingClass.getQualifiedName())) {
|
||||
if (containingClass == null) {
|
||||
break;
|
||||
}
|
||||
final TypeConversionDescriptorFactory descriptorFactory = DESCRIPTORS_MAP.get(methodName);
|
||||
if (descriptorFactory == null) {
|
||||
return null;
|
||||
TypeConversionDescriptorBase descriptor;
|
||||
if (FLUENT_ITERABLE.equals(containingClass.getQualifiedName())) {
|
||||
final TypeConversionDescriptorFactory descriptorFactory = DESCRIPTORS_MAP.get(methodName);
|
||||
if (descriptorFactory == null) {
|
||||
return null;
|
||||
}
|
||||
descriptor = descriptorFactory.create();
|
||||
}
|
||||
methodDescriptors.add(descriptorFactory.create());
|
||||
else if (GuavaOptionalConversionRule.GUAVA_OPTIONAL.equals(containingClass.getQualifiedName())) {
|
||||
descriptor = optionalDescriptor.getValue().findConversion(null, null, method, current.getMethodExpression(), labeler);
|
||||
if (descriptor == null) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
methodDescriptors.add(descriptor);
|
||||
final PsiExpression qualifier = current.getMethodExpression().getQualifierExpression();
|
||||
if (qualifier instanceof PsiMethodCallExpression) {
|
||||
current = (PsiMethodCallExpression)qualifier;
|
||||
@@ -172,10 +199,10 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
|
||||
}
|
||||
|
||||
private static class GuavaChainedConversionDescriptor extends TypeConversionDescriptorBase {
|
||||
private final List<TypeConversionDescriptor> myMethodDescriptors;
|
||||
private final List<TypeConversionDescriptorBase> myMethodDescriptors;
|
||||
private final PsiType myToType;
|
||||
|
||||
private GuavaChainedConversionDescriptor(List<TypeConversionDescriptor> descriptors, PsiType to) {
|
||||
private GuavaChainedConversionDescriptor(List<TypeConversionDescriptorBase> descriptors, PsiType to) {
|
||||
myMethodDescriptors = descriptors;
|
||||
myToType = to;
|
||||
}
|
||||
@@ -184,15 +211,21 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
|
||||
public PsiExpression replace(PsiExpression expression) throws IncorrectOperationException {
|
||||
PsiMethodCallExpression toReturn = null;
|
||||
PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) expression;
|
||||
for (TypeConversionDescriptor descriptor : myMethodDescriptors) {
|
||||
final SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(expression.getProject());
|
||||
|
||||
for (TypeConversionDescriptorBase descriptor : myMethodDescriptors) {
|
||||
final PsiExpression oldQualifier = methodCallExpression.getMethodExpression().getQualifierExpression();
|
||||
final SmartPsiElementPointer<PsiExpression> qualifierRef = oldQualifier == null
|
||||
? null
|
||||
: smartPointerManager.createSmartPsiElementPointer(oldQualifier);
|
||||
final PsiMethodCallExpression replaced = (PsiMethodCallExpression)descriptor.replace(methodCallExpression);
|
||||
if (toReturn == null) {
|
||||
toReturn = replaced;
|
||||
}
|
||||
|
||||
final PsiExpression qualifier = replaced.getMethodExpression().getQualifierExpression();
|
||||
if (qualifier instanceof PsiMethodCallExpression) {
|
||||
methodCallExpression = (PsiMethodCallExpression)qualifier;
|
||||
final PsiExpression newQualifier = qualifierRef == null ? null : qualifierRef.getElement();
|
||||
if (newQualifier instanceof PsiMethodCallExpression) {
|
||||
methodCallExpression = (PsiMethodCallExpression)newQualifier;
|
||||
} else {
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
+12
-9
@@ -36,10 +36,10 @@ public class GuavaOptionalConversionRule extends BaseGuavaTypeConversionRule {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected TypeConversionDescriptorBase findConversionForMethod(@NotNull PsiType from,
|
||||
@NotNull PsiType to,
|
||||
protected TypeConversionDescriptorBase findConversionForMethod(@Nullable PsiType from,
|
||||
@Nullable PsiType to,
|
||||
@NotNull PsiMethod method,
|
||||
String methodName,
|
||||
@NotNull String methodName,
|
||||
PsiExpression context,
|
||||
TypeMigrationLabeler labeler) {
|
||||
if ("or".equals(methodName)) {
|
||||
@@ -53,9 +53,7 @@ public class GuavaOptionalConversionRule extends BaseGuavaTypeConversionRule {
|
||||
if (aClass != null) {
|
||||
final String qName = aClass.getQualifiedName();
|
||||
String pattern =
|
||||
GUAVA_OPTIONAL.equals(qName) ? "java.util.Optional.ofNullable($expr$.get())" : "com.google.common.bas.Supplier".equals(qName)
|
||||
? "java.util.Optional.ofNullable($expr$)"
|
||||
: "java.util.Optional.ofNullable($expr$)";
|
||||
GUAVA_OPTIONAL.equals(qName) ? "java.util.Optional.ofNullable($expr$.get())" : "java.util.Optional.ofNullable($expr$)";
|
||||
return new TypeConversionDescriptor("$expr$", pattern);
|
||||
}
|
||||
return null;
|
||||
@@ -73,10 +71,15 @@ public class GuavaOptionalConversionRule extends BaseGuavaTypeConversionRule {
|
||||
if (aClass != null) {
|
||||
final String qName = aClass.getQualifiedName();
|
||||
if (GUAVA_OPTIONAL.equals(qName)) {
|
||||
return new TypeConversionDescriptor("$val$.or($other$)", "java.util.Optional.ofNullable($val$.orElseGet($other$::get))", to);
|
||||
TypeConversionDescriptor descriptor =
|
||||
new TypeConversionDescriptor("$val$.or($other$)", "java.util.Optional.ofNullable($val$.orElseGet($other$::get))");
|
||||
if (to != null) {
|
||||
descriptor.withConversionType(to);
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
String pattern = "com.google.common.bas.Supplier".equals(qName) ? "$val$.orElseGet($other$::get)" : "$val$.orElse($other$)";
|
||||
return new TypeConversionDescriptor("$val$.or($other$)", pattern);
|
||||
String pattern = GuavaSupplierConversionRule.GUAVA_SUPPLIER.equals(qName) ? "$val$.orElseGet($other$)" : "$val$.orElse($other$)";
|
||||
return new LambdaParametersTypeConversionDescription("$val$.or($other$)", pattern);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.refactoring.typeMigration.rules.guava;
|
||||
|
||||
import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
|
||||
import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class GuavaSupplierConversionRule extends BaseGuavaTypeConversionRule {
|
||||
public final static String GUAVA_SUPPLIER = "com.google.common.base.Supplier";
|
||||
|
||||
@Override
|
||||
protected void fillSimpleDescriptors(Map<String, TypeConversionDescriptorBase> descriptorsMap) {
|
||||
descriptorsMap.put("get", new TypeConversionDescriptor("$val$.get()", "$val$.get()"));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String ruleFromClass() {
|
||||
return GUAVA_SUPPLIER;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String ruleToClass() {
|
||||
return "java.util.function.Supplier";
|
||||
}
|
||||
}
|
||||
+10
-5
@@ -27,10 +27,6 @@ import org.jetbrains.annotations.NonNls;
|
||||
public class LambdaParametersTypeConversionDescription extends TypeConversionDescriptor {
|
||||
private static final Logger LOG = Logger.getInstance(LambdaParametersTypeConversionDescription.class);
|
||||
|
||||
public LambdaParametersTypeConversionDescription(@NonNls String stringToReplace, @NonNls String replaceByString, PsiType conversionType) {
|
||||
super(stringToReplace, replaceByString, conversionType);
|
||||
}
|
||||
|
||||
public LambdaParametersTypeConversionDescription(@NonNls String stringToReplace, @NonNls String replaceByString) {
|
||||
super(stringToReplace, replaceByString);
|
||||
}
|
||||
@@ -52,7 +48,16 @@ public class LambdaParametersTypeConversionDescription extends TypeConversionDes
|
||||
}
|
||||
|
||||
private static PsiExpression addApplyReference(final PsiExpression expression) {
|
||||
return (PsiExpression)expression.replace(JavaPsiFacade.getElementFactory(expression.getProject()).createExpressionFromText(expression.getText() + "::apply", null));
|
||||
boolean isSupplier = false;
|
||||
PsiType type = expression.getType();
|
||||
if (type instanceof PsiClassType) {
|
||||
PsiClass resolvedClass = ((PsiClassType)type).resolve();
|
||||
if (resolvedClass != null && GuavaSupplierConversionRule.GUAVA_SUPPLIER.equals(resolvedClass.getQualifiedName())) {
|
||||
isSupplier = true;
|
||||
}
|
||||
}
|
||||
return (PsiExpression)expression.replace(
|
||||
JavaPsiFacade.getElementFactory(expression.getProject()).createExpressionFromText(expression.getText() + "::" + (isSupplier ? "get" : "apply"), null));
|
||||
}
|
||||
|
||||
public static PsiExpression convertParameter(PsiExpression expression) {
|
||||
|
||||
+7
-3
@@ -63,7 +63,7 @@ public class GuavaInspectionTest extends JavaCodeInsightFixtureTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void _testFluentIterableChainWithoutVariable() {
|
||||
public void testFluentIterableChainWithoutVariable() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@@ -71,19 +71,23 @@ public class GuavaInspectionTest extends JavaCodeInsightFixtureTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testFluentIterableChainWithOptional() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
myFixture.configureByFile(getTestName(true) + ".java");
|
||||
myFixture.enableInspections(new GuavaInspection());
|
||||
boolean actionFound = false;
|
||||
myFixture.doHighlighting();
|
||||
for (IntentionAction action : myFixture.getAvailableIntentions()) {
|
||||
if (action instanceof VariableTypeFix) {
|
||||
if (action instanceof VariableTypeFix || action instanceof GuavaInspection.MigrateFluentIterableChainQuickFix) {
|
||||
myFixture.launchAction(action);
|
||||
actionFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertTrue(actionFound);
|
||||
assertTrue("Quick fix isn't found", actionFound);
|
||||
myFixture.checkResultByFile(getTestName(true) + "_after.java");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import java.util.*;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
class A {
|
||||
void m1() {
|
||||
ArrayList<String> strings = new ArrayList<String>();
|
||||
String str = FluentIterable.from(strings).transform(s -> s + s).lim<caret>it(10).firstMatch(s -> s.isEmpty()).orNull();
|
||||
System.out.println("s: " + str);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import java.util.*;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
class A {
|
||||
void m1() {
|
||||
ArrayList<String> strings = new ArrayList<String>();
|
||||
String str = strings.stream().map(s -> s + s).limit(10).filter(s -> s.isEmpty()).findFirst().orElse(null);
|
||||
System.out.println("s: " + str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import java.util.*;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
class A {
|
||||
int m1() {
|
||||
ArrayList<String> strings = new ArrayList<String>();
|
||||
int size = FluentIterable.fro<caret>m(strings).transform(s -> s + s).limit(10).size();
|
||||
return size
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
class A {
|
||||
int m1() {
|
||||
ArrayList<String> strings = new ArrayList<String>();
|
||||
int size = strings.stream().map(s -> s + s).limit(10).collect(Collectors.toList()).size();
|
||||
return size
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
|
||||
import com.intellij.openapi.util.io.FileSystemUtil;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.concurrency.Semaphore;
|
||||
import com.intellij.util.concurrency.SequentialTaskExecutor;
|
||||
import com.intellij.util.io.DataOutputStream;
|
||||
import io.netty.channel.Channel;
|
||||
@@ -49,7 +50,6 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope;
|
||||
|
||||
@@ -64,7 +64,7 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
private final Channel myChannel;
|
||||
@Nullable
|
||||
private final PreloadedData myPreloadedData;
|
||||
private volatile boolean myCanceled = false;
|
||||
private volatile boolean myCanceled;
|
||||
private final String myProjectPath;
|
||||
@Nullable
|
||||
private CmdlineRemoteProto.Message.ControllerMessage.FSEvent myInitialFSDelta;
|
||||
@@ -345,7 +345,7 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
}
|
||||
|
||||
public void processFSEvent(final CmdlineRemoteProto.Message.ControllerMessage.FSEvent event) {
|
||||
myEventsProcessor.submit(new Runnable() {
|
||||
myEventsProcessor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
@@ -646,23 +646,21 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
}
|
||||
|
||||
private static class EventsProcessor extends SequentialTaskExecutor {
|
||||
private final AtomicBoolean myProcessingEnabled = new AtomicBoolean(false);
|
||||
private final Semaphore myProcessingEnabled = new Semaphore();
|
||||
|
||||
EventsProcessor() {
|
||||
private EventsProcessor() {
|
||||
super(SharedThreadPool.getInstance());
|
||||
myProcessingEnabled.down();
|
||||
execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myProcessingEnabled.waitFor();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void startProcessing() {
|
||||
if (!myProcessingEnabled.getAndSet(true)) {
|
||||
super.processQueue();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processQueue() {
|
||||
if (myProcessingEnabled.get()) {
|
||||
super.processQueue();
|
||||
}
|
||||
private void startProcessing() {
|
||||
myProcessingEnabled.up();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
package org.jetbrains.ide
|
||||
|
||||
import com.google.gson.stream.JsonWriter
|
||||
import com.intellij.openapi.vfs.CharsetToolkit
|
||||
import io.netty.handler.codec.http.HttpResponseStatus
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.jetbrains.ide.TestManager.TestDescriptor
|
||||
import org.junit.Test
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.OutputStreamWriter
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
|
||||
@@ -72,13 +69,13 @@ private class RestApiTest : BuiltInServerTestCase() {
|
||||
connection = URL("$serviceUrl").openConnection() as HttpURLConnection
|
||||
connection.requestMethod = "POST"
|
||||
connection.doOutput = true
|
||||
val writer = JsonWriter(OutputStreamWriter(BufferedOutputStream(connection.outputStream), CharsetToolkit.UTF8_CHARSET))
|
||||
writer.beginObject()
|
||||
writer.name("file").value(manager.filePath)
|
||||
writer.name("line").value(line)
|
||||
writer.name("column").value(column)
|
||||
writer.endObject()
|
||||
writer.close()
|
||||
JsonWriter(connection.outputStream.bufferedWriter()).use {
|
||||
it.beginObject()
|
||||
it.name("file").value(manager.filePath)
|
||||
it.name("line").value(line)
|
||||
it.name("column").value(column)
|
||||
it.endObject()
|
||||
}
|
||||
assertThat(HttpResponseStatus.valueOf(connection.responseCode)).isEqualTo(expectedStatus)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,9 @@ import java.util.*
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray
|
||||
|
||||
class StateMap private constructor(private val names: Array<String>, private val states: AtomicReferenceArray<Any?>) {
|
||||
override fun toString(): String =
|
||||
if (this == EMPTY) "EMPTY" else states.toString();
|
||||
|
||||
companion object {
|
||||
private val XML_FORMAT = Format.getRawFormat().setTextMode(Format.TextMode.TRIM).setOmitEncoding(true).setOmitDeclaration(true)
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
* See <a href="http://www.jetbrains.org/intellij/sdk/docs/basics/persisting_state_of_components.html">IntelliJ Platform SDK DevGuide</a>
|
||||
* for detailed description.
|
||||
*
|
||||
* Implementation must be thread-safe - a component should expect these methods to be called at any moment of its lifecycle.
|
||||
* In general, implementation should be thread-safe, because "loadState" is called from the same thread where component is initialized.
|
||||
* If component used only from one thread (e.g. EDT), thread-safe implementation is not required.
|
||||
*/
|
||||
public interface PersistentStateComponent<T> {
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,9 @@ import com.intellij.util.ReflectionUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class CodeInsightUtilCore extends FileModificationService {
|
||||
public static <T extends PsiElement> T findElementInRange(@NotNull PsiFile file,
|
||||
int startOffset,
|
||||
@@ -78,7 +81,12 @@ public abstract class CodeInsightUtilCore extends FileModificationService {
|
||||
}
|
||||
|
||||
public static boolean parseStringCharacters(@NotNull String chars, @NotNull StringBuilder outChars, @Nullable int[] sourceOffsets) {
|
||||
return parseStringCharacters(chars, outChars, sourceOffsets, '"', '\'');
|
||||
}
|
||||
|
||||
public static boolean parseStringCharacters(@NotNull String chars, @NotNull StringBuilder outChars, @Nullable int[] sourceOffsets, Character... endChars) {
|
||||
assert sourceOffsets == null || sourceOffsets.length == chars.length()+1;
|
||||
List<Character> endCharList = Arrays.asList(endChars);
|
||||
if (chars.indexOf('\\') < 0) {
|
||||
outChars.append(chars);
|
||||
if (sourceOffsets != null) {
|
||||
@@ -123,14 +131,6 @@ public abstract class CodeInsightUtilCore extends FileModificationService {
|
||||
outChars.append('\r');
|
||||
break;
|
||||
|
||||
case'"':
|
||||
outChars.append('"');
|
||||
break;
|
||||
|
||||
case'\'':
|
||||
outChars.append('\'');
|
||||
break;
|
||||
|
||||
case'\\':
|
||||
outChars.append('\\');
|
||||
break;
|
||||
@@ -193,7 +193,11 @@ public abstract class CodeInsightUtilCore extends FileModificationService {
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
if (endCharList.contains(c)) {
|
||||
outChars.append(c);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (sourceOffsets != null) {
|
||||
sourceOffsets[outChars.length()-outOffset] = index;
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 668 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
@@ -367,7 +367,7 @@ public class SheetController {
|
||||
}
|
||||
|
||||
private static String handleBreaks(final String message) {
|
||||
return message.replaceAll("(\r\n|\n)", "<br/>");
|
||||
return message == null ? "" : message.replaceAll("(\r\n|\n)", "<br/>");
|
||||
}
|
||||
|
||||
private void shiftButtonsToTheBottom(int shiftDistance) {
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
</xi:include>
|
||||
|
||||
<application-components>
|
||||
<component>
|
||||
<implementation-class>com.intellij.javaee.DefaultHtmlDoctypeInitialConfigurator</implementation-class>
|
||||
</component>
|
||||
<!--<component>-->
|
||||
<!--<implementation-class>com.intellij.javaee.DefaultHtmlDoctypeInitialConfigurator</implementation-class>-->
|
||||
<!--</component>-->
|
||||
<component>
|
||||
<implementation-class>com.intellij.codeInsight.editorActions.XmlTagNameSynchronizer</implementation-class>
|
||||
</component>
|
||||
|
||||
@@ -1224,6 +1224,7 @@ public class AllIcons {
|
||||
public static final Icon Canary16 = IconLoader.getIcon("/xml/browsers/canary16.png"); // 16x16
|
||||
public static final Icon Chrome16 = IconLoader.getIcon("/xml/browsers/chrome16.png"); // 16x16
|
||||
public static final Icon Chromium16 = IconLoader.getIcon("/xml/browsers/chromium16.png"); // 16x16
|
||||
public static final Icon Edge16 = IconLoader.getIcon("/xml/browsers/edge16.png"); // 16x16
|
||||
public static final Icon Explorer16 = IconLoader.getIcon("/xml/browsers/explorer16.png"); // 16x16
|
||||
public static final Icon Firefox16 = IconLoader.getIcon("/xml/browsers/firefox16.png"); // 16x16
|
||||
public static final Icon Nwjs16 = IconLoader.getIcon("/xml/browsers/nwjs16.png"); // 16x16
|
||||
|
||||
@@ -41,7 +41,7 @@ public class BuildNumberTest {
|
||||
assertTrue(BuildNumber.fromString("90.SNAPSHOT").compareTo(BuildNumber.fromString("90.12345")) > 0);
|
||||
assertTrue(BuildNumber.fromString("IU-90.SNAPSHOT").compareTo(BuildNumber.fromString("RM-90.12345")) > 0);
|
||||
assertTrue(BuildNumber.fromString("IU-90.SNAPSHOT").compareTo(BuildNumber.fromString("RM-100.12345")) < 0);
|
||||
assertTrue(BuildNumber.fromString("IU-90.SNAPSHOT").compareTo(BuildNumber.fromString("RM-100.SNAPSHOT")) == 0);
|
||||
assertTrue(BuildNumber.fromString("IU-90.SNAPSHOT").compareTo(BuildNumber.fromString("RM-100.SNAPSHOT")) < 0);
|
||||
assertTrue(BuildNumber.fromString("IU-90.SNAPSHOT").compareTo(BuildNumber.fromString("RM-90.SNAPSHOT")) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -93,7 +93,7 @@ public class MagicNumberInspectionBase extends BaseInspection {
|
||||
return;
|
||||
}
|
||||
final PsiField field = PsiTreeUtil.getParentOfType(expression, PsiField.class);
|
||||
if (field != null && PsiUtil.isCompileTimeConstant(field)) {
|
||||
if (field != null && PsiUtil.isCompileTimeConstant((PsiVariable)field)) {
|
||||
return;
|
||||
}
|
||||
final PsiElement parent = expression.getParent();
|
||||
|
||||
+3
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2015 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +23,6 @@ import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.psiutils.IteratorUtils;
|
||||
import com.siyeh.ig.psiutils.MethodUtils;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class IteratorHasNextCallsIteratorNextInspection
|
||||
@@ -48,15 +47,12 @@ public class IteratorHasNextCallsIteratorNextInspection
|
||||
return new IteratorHasNextCallsIteratorNext();
|
||||
}
|
||||
|
||||
private static class IteratorHasNextCallsIteratorNext
|
||||
extends BaseInspectionVisitor {
|
||||
private static class IteratorHasNextCallsIteratorNext extends BaseInspectionVisitor {
|
||||
|
||||
@Override
|
||||
public void visitMethod(@NotNull PsiMethod method) {
|
||||
// note: no call to super
|
||||
@NonNls final String name = method.getName();
|
||||
if (!MethodUtils.methodMatches(method, CommonClassNames.JAVA_UTIL_ITERATOR, null,
|
||||
HardcodedMethodConstants.HAS_NEXT)) {
|
||||
if (!MethodUtils.methodMatches(method, CommonClassNames.JAVA_UTIL_ITERATOR, null, HardcodedMethodConstants.HAS_NEXT)) {
|
||||
return;
|
||||
}
|
||||
if (!IteratorUtils.containsCallToIteratorNext(method, null, true)) {
|
||||
|
||||
+4
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2012 Bas Leijdekkers
|
||||
* Copyright 2008-2015 Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -190,6 +190,9 @@ public class IfMayBeConditionalInspection extends BaseInspection {
|
||||
@Override
|
||||
public void visitIfStatement(PsiIfStatement statement) {
|
||||
super.visitIfStatement(statement);
|
||||
if (ControlFlowUtils.isElseIf(statement)) {
|
||||
return;
|
||||
}
|
||||
final PsiStatement thenBranch = statement.getThenBranch();
|
||||
final PsiStatement elseBranch = statement.getElseBranch();
|
||||
final PsiStatement thenStatement = ControlFlowUtils.stripBraces(thenBranch);
|
||||
|
||||
+2
-2
@@ -77,11 +77,11 @@ public class FieldMayBeStaticInspection extends BaseInspection {
|
||||
if (containingClass != null
|
||||
&& !containingClass.hasModifierProperty(PsiModifier.STATIC)
|
||||
&& containingClass.getContainingClass() != null
|
||||
&& !PsiUtil.isCompileTimeConstant(field)) {
|
||||
&& !PsiUtil.isCompileTimeConstant((PsiVariable)field)) {
|
||||
// inner class cannot have static declarations
|
||||
return;
|
||||
}
|
||||
if (containingClass instanceof PsiAnonymousClass && !PsiUtil.isCompileTimeConstant(field)) {
|
||||
if (containingClass instanceof PsiAnonymousClass && !PsiUtil.isCompileTimeConstant((PsiVariable)field)) {
|
||||
return;
|
||||
}
|
||||
if (!canBeStatic(initializer)) {
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2011 Bas Leijdekkers
|
||||
* Copyright 2003-2015 Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -96,9 +96,8 @@ public class IteratorUtils {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!MethodCallUtils.isCallToMethod(expression,
|
||||
CommonClassNames.JAVA_UTIL_ITERATOR, null,
|
||||
HardcodedMethodConstants.NEXT)) {
|
||||
if (!MethodCallUtils.isCallToMethod(expression, CommonClassNames.JAVA_UTIL_ITERATOR, null, HardcodedMethodConstants.NEXT)
|
||||
&& !MethodCallUtils.isCallToMethod(expression, "java.util.ListIterator", null, "previous")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+16
-3
@@ -9,11 +9,11 @@ public class IfMayBeConditional {
|
||||
|
||||
void foo2(int a, int b) {
|
||||
int c = 0;
|
||||
if (a < b) { c += a - b; } else { c += b; }
|
||||
<warning descr="'if' could be replaced with conditional expression">if</warning> (a < b) { c += a - b; } else { c += b; }
|
||||
}
|
||||
|
||||
void foo3(int i, StringBuilder sb) {
|
||||
if (i == 0) {
|
||||
<warning descr="'if' could be replaced with conditional expression">if</warning> (i == 0) {
|
||||
sb.append("type.getConstructor()", 0, 1);
|
||||
}
|
||||
else {
|
||||
@@ -22,7 +22,7 @@ public class IfMayBeConditional {
|
||||
}
|
||||
|
||||
int foo4(int a, int b) {
|
||||
if (a < b) return a;
|
||||
<warning descr="'if' could be replaced with conditional expression">if</warning> (a < b) return a;
|
||||
else return b;
|
||||
}
|
||||
|
||||
@@ -42,4 +42,17 @@ public class IfMayBeConditional {
|
||||
i = b < c ? b : c;
|
||||
}
|
||||
}
|
||||
|
||||
void largeIf(boolean a, boolean b, boolean c) {
|
||||
final String value;
|
||||
if (a) {
|
||||
value = "a";
|
||||
} else if (b) {
|
||||
value = "b";
|
||||
} else if (c) {
|
||||
value = "c";
|
||||
} else {
|
||||
value = "d";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
|
||||
<problem>
|
||||
<file>IfMayBeConditional.java</file>
|
||||
<line>12</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If statement could be replaced with simple conditional expression</problem_class>
|
||||
<description><code>if</code> could be replaced with simple conditional expression #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>IfMayBeConditional.java</file>
|
||||
<line>16</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'if' statement could be replaced with simple conditional expression</problem_class>
|
||||
<description><code>if</code> could be replaced with simple conditional expression #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>IfMayBeConditional.java</file>
|
||||
<line>25</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'if' statement could be replaced with conditional expression</problem_class>
|
||||
<description><code>if</code> could be replaced with conditional expression #loc</description>
|
||||
</problem>
|
||||
</problems>
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.siyeh.ig.bugs;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.siyeh.ig.LightInspectionTestCase;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class IteratorHasNextCallsIteratorNextInspectionTest extends LightInspectionTestCase {
|
||||
|
||||
public void testHasNextCallsNext() {
|
||||
doTest("import java.util.*;" +
|
||||
"class MyIterator<T> implements Iterator<T> {" +
|
||||
" private Iterator<T> iterator;" +
|
||||
" public MyIterator(Iterator<T> iterator) {" +
|
||||
" this.iterator = iterator;" +
|
||||
" }" +
|
||||
" public boolean /*'Iterator.hasNext()' contains call to 'next()'*/hasNext/**/() {" +
|
||||
" return next() != null;" +
|
||||
" }" +
|
||||
" public T next() {" +
|
||||
" return iterator.next();" +
|
||||
" }" +
|
||||
" public void remove() {" +
|
||||
" iterator.remove();" +
|
||||
" }" +
|
||||
"}");
|
||||
}
|
||||
|
||||
public void testHasNextCallsPrevious() {
|
||||
doTest("import java.util.*;" +
|
||||
"abstract class MyIterator<T> implements ListIterator<T> {" +
|
||||
" private ListIterator<T> iterator;" +
|
||||
" public MyIterator(ListIterator<T> iterator) {" +
|
||||
" this.iterator = iterator;" +
|
||||
" }" +
|
||||
" public boolean /*'Iterator.hasNext()' contains call to 'next()'*/hasNext/**/() {" +
|
||||
" return previous() != null;" +
|
||||
" }" +
|
||||
" public T next() {" +
|
||||
" return iterator.next();" +
|
||||
" }" +
|
||||
" public T previous() {" +
|
||||
" return iterator.previous();" +
|
||||
" }" +
|
||||
"}");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new IteratorHasNextCallsIteratorNextInspection();
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.siyeh.ig.bugs;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.siyeh.ig.LightInspectionTestCase;
|
||||
import junit.framework.TestCase;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class IteratorNextDoesNotThrowNoSuchElementExceptionInspectionTest extends LightInspectionTestCase {
|
||||
|
||||
public void testPrevious() {
|
||||
doTest("import java.util.*;" +
|
||||
"class ReverseListIterator<T> implements Iterator<T> {" +
|
||||
" private ListIterator<T> iterator;" +
|
||||
" public ReverseListIterator(List<T> list) {" +
|
||||
" this.iterator = list.listIterator(list.size());" +
|
||||
" }" +
|
||||
" public boolean hasNext() {" +
|
||||
" return iterator.hasPrevious();" +
|
||||
" }" +
|
||||
" public T next() {" +
|
||||
" return iterator.previous();" +
|
||||
" }" +
|
||||
" public void remove() {" +
|
||||
" iterator.remove();" +
|
||||
" }" +
|
||||
"}");
|
||||
}
|
||||
|
||||
public void testEmpty() {
|
||||
doTest("import java.util.*;" +
|
||||
"class EmptyIterator<T> implements Iterator<T> {" +
|
||||
" public boolean hasNext() {" +
|
||||
" return false;" +
|
||||
" }" +
|
||||
" public T /*'Iterator.next()' which can't throw 'NoSuchElementException'*/next/**/() {" +
|
||||
" return null;" +
|
||||
" }" +
|
||||
" public void remove() {" +
|
||||
" }" +
|
||||
"}");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new IteratorNextDoesNotThrowNoSuchElementExceptionInspection();
|
||||
}
|
||||
}
|
||||
+14
-6
@@ -1,12 +1,20 @@
|
||||
package com.siyeh.ig.controlflow;
|
||||
|
||||
import com.siyeh.ig.IGInspectionTestCase;
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.siyeh.ig.LightInspectionTestCase;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class IfMayBeConditionalInspectionTest extends IGInspectionTestCase {
|
||||
public class IfMayBeConditionalInspectionTest extends LightInspectionTestCase {
|
||||
|
||||
public void test() throws Exception {
|
||||
final IfMayBeConditionalInspection tool = new IfMayBeConditionalInspection();
|
||||
tool.reportMethodCalls = true;
|
||||
doTest("com/siyeh/igtest/controlflow/if_may_be_conditional", tool);
|
||||
public void testIfMayBeConditional() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
final IfMayBeConditionalInspection inspection = new IfMayBeConditionalInspection();
|
||||
inspection.reportMethodCalls = true;
|
||||
return inspection;
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public class PluginProjectWizardTest extends NewProjectWizardTestCase {
|
||||
createSdk("devkit", IdeaJdk.getInstance());
|
||||
Project project = createProjectFromTemplate(PluginModuleType.getInstance().getName(), null, null);
|
||||
VirtualFile baseDir = project.getBaseDir();
|
||||
VirtualFile virtualFile = VfsUtilCore.findRelativeFile("META-INF/plugin.xml", baseDir);
|
||||
VirtualFile virtualFile = VfsUtilCore.findRelativeFile("resources/META-INF/plugin.xml", baseDir);
|
||||
assertNotNull(virtualFile);
|
||||
|
||||
RunnerAndConfigurationSettings configuration = RunManager.getInstance(project).getSelectedConfiguration();
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
|
||||
Reference in New Issue
Block a user