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))
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import java.util.ArrayList;
|
||||
|
||||
class Test {
|
||||
public static void main(String[] args) {
|
||||
ArrayList<Object> list = new ArrayList<Object>();
|
||||
list.iter<caret>
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import java.util.ArrayList;
|
||||
|
||||
class Test {
|
||||
public static void main(String[] args) {
|
||||
ArrayList<Object> list = new ArrayList<Object>();
|
||||
for (Object o : list) {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
@@ -37,6 +37,10 @@ public class ForeachTemplateTest extends PostfixTemplateTestCase {
|
||||
public void testInAnonymousRunnable() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIterSameAsFor() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testFinalLocals() {
|
||||
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.jetbrains.ide;
|
||||
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.openapi.wm.IdeFrame;
|
||||
import com.intellij.ui.AppIcon;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.QueryStringDecoder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class ActivateApplicationHttpService extends RestService {
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getServiceName() {
|
||||
return "show";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isMethodSupported(@NotNull HttpMethod method) {
|
||||
return method == HttpMethod.GET;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String execute(@NotNull QueryStringDecoder urlDecoder, @NotNull FullHttpRequest request, @NotNull ChannelHandlerContext context)
|
||||
throws IOException {
|
||||
final IdeFrame frame = IdeFocusManager.findInstance().getLastFocusedFrame();
|
||||
if (frame instanceof Window) {
|
||||
sendOk(request, context);
|
||||
Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
Window window = (Window)frame;
|
||||
window.toFront();
|
||||
window.requestFocusInWindow();
|
||||
|
||||
AppIcon.getInstance().requestFocus(frame);
|
||||
|
||||
}
|
||||
};
|
||||
//noinspection SSBasedInspection
|
||||
SwingUtilities.invokeLater(runnable);
|
||||
return "Success";
|
||||
}
|
||||
sendStatus(HttpResponseStatus.NOT_FOUND, false, context.channel());
|
||||
return "Can't find IDE Frame";
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.components.StoragePathMacros
|
||||
import com.intellij.openapi.components.TrackingPathMacroSubstitutor
|
||||
import com.intellij.openapi.components.impl.stores.StorageUtil
|
||||
import com.intellij.openapi.components.store.ReadOnlyModificationException
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.fileEditor.impl.LoadTextUtil
|
||||
import com.intellij.openapi.util.JDOMUtil
|
||||
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream
|
||||
@@ -113,9 +114,7 @@ open class FileBasedStorage(file: File,
|
||||
try {
|
||||
val file = getVirtualFile()
|
||||
if (file == null || file.isDirectory || !file.isValid) {
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug("Document was not loaded for $fileSpec file is ${if (file == null) "null" else "directory"}")
|
||||
}
|
||||
LOG.debug { "Document was not loaded for $fileSpec file is ${if (file == null) "null" else "directory"}" }
|
||||
}
|
||||
else if (file.length == 0L) {
|
||||
processReadException(null)
|
||||
@@ -194,10 +193,7 @@ private fun isEqualContent(result: VirtualFile, lineSeparator: LineSeparator, co
|
||||
}
|
||||
|
||||
private fun doWrite(requestor: Any, file: VirtualFile, content: Any, lineSeparator: LineSeparator, prependXmlProlog: Boolean) {
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug("Save ${file.presentableUrl}")
|
||||
}
|
||||
|
||||
LOG.debug { "Save ${file.presentableUrl}" }
|
||||
val token = WriteAction.start()
|
||||
try {
|
||||
val out = file.getOutputStream(requestor)
|
||||
|
||||
@@ -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,6 +24,7 @@ import com.intellij.openapi.components.ComponentManager
|
||||
import com.intellij.openapi.components.StateStorage
|
||||
import com.intellij.openapi.components.impl.stores.*
|
||||
import com.intellij.openapi.components.stateStore
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.project.Project
|
||||
@@ -117,9 +118,7 @@ class StoreAwareProjectManager(virtualFileManager: VirtualFileManager, progressM
|
||||
|
||||
private fun isReloadUnblocked(): Boolean {
|
||||
val count = reloadBlockCount.get()
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug("[RELOAD] myReloadBlockCount = $count")
|
||||
}
|
||||
LOG.debug { "[RELOAD] myReloadBlockCount = $count" }
|
||||
return count == 0
|
||||
}
|
||||
|
||||
|
||||
@@ -19,13 +19,13 @@ import com.intellij.openapi.components.RoamingType
|
||||
import com.intellij.openapi.components.StateStorage
|
||||
import com.intellij.openapi.components.TrackingPathMacroSubstitutor
|
||||
import com.intellij.openapi.components.impl.stores.FileStorageCoreUtil
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.util.JDOMUtil
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import com.intellij.util.containers.SmartHashSet
|
||||
import gnu.trove.THashMap
|
||||
import org.jdom.Attribute
|
||||
import org.jdom.Element
|
||||
import java.io.IOException
|
||||
|
||||
abstract class XmlElementStorage protected constructor(protected val fileSpec: String,
|
||||
protected val rootElementName: String,
|
||||
@@ -87,16 +87,12 @@ abstract class XmlElementStorage protected constructor(protected val fileSpec: S
|
||||
val oldData = storageDataRef.get()
|
||||
val newData = getStorageData(true)
|
||||
if (oldData == null) {
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug("analyzeExternalChangesAndUpdateIfNeed: old data null, load new for ${toString()}")
|
||||
}
|
||||
LOG.debug { "analyzeExternalChangesAndUpdateIfNeed: old data null, load new for ${toString()}" }
|
||||
componentNames.addAll(newData.keys())
|
||||
}
|
||||
else {
|
||||
val changedComponentNames = oldData.getChangedComponentNames(newData)
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug("analyzeExternalChangesAndUpdateIfNeed: changedComponentNames $changedComponentNames for ${toString()}")
|
||||
}
|
||||
LOG debug { "analyzeExternalChangesAndUpdateIfNeed: changedComponentNames $changedComponentNames for ${toString()}" }
|
||||
if (!ContainerUtil.isEmpty(changedComponentNames)) {
|
||||
componentNames.addAll(changedComponentNames)
|
||||
}
|
||||
|
||||
@@ -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 |
@@ -35,7 +35,7 @@ public class ToggleRegex extends EditorHeaderToggleAction {
|
||||
FindModel findModel = session.getFindModel();
|
||||
findModel.setRegularExpressions(selected);
|
||||
if (selected) {
|
||||
findModel.setWholeWordsOnly(true);
|
||||
findModel.setWholeWordsOnly(false);
|
||||
}
|
||||
FindSettings.getInstance().setLocalRegularExpressions(selected);
|
||||
}
|
||||
|
||||
@@ -1221,7 +1221,16 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
|
||||
}
|
||||
else if (isSetting(value)) {
|
||||
String text = getSettingText((OptionDescription)value);
|
||||
append(text);
|
||||
SimpleTextAttributes attrs = SimpleTextAttributes.REGULAR_ATTRIBUTES;
|
||||
if (value instanceof Changeable && ((Changeable)value).hasChanged()) {
|
||||
if (selected) {
|
||||
attrs = SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES;
|
||||
} else {
|
||||
SimpleTextAttributes base = SimpleTextAttributes.LINK_BOLD_ATTRIBUTES;
|
||||
attrs = base.derive(SimpleTextAttributes.STYLE_BOLD, base.getFgColor(), null, null);
|
||||
}
|
||||
}
|
||||
append(text, attrs);
|
||||
final String id = ((OptionDescription)value).getConfigurableId();
|
||||
final String name = myConfigurables.get(id);
|
||||
if (name != null) {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
/**
|
||||
* This markup interface is used to provide meta-information to element renderers
|
||||
*
|
||||
* @author Konstantin Bulenkov
|
||||
* @since 15.0
|
||||
*/
|
||||
public interface Changeable {
|
||||
boolean hasChanged();
|
||||
}
|
||||
@@ -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.
|
||||
@@ -17,11 +17,12 @@ package com.intellij.ide.ui;
|
||||
|
||||
import com.intellij.ide.ui.search.BooleanOptionDescription;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.ui.Changeable;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class RegistryBooleanOptionDescriptor extends BooleanOptionDescription {
|
||||
public class RegistryBooleanOptionDescriptor extends BooleanOptionDescription implements Changeable {
|
||||
private final String myKey;
|
||||
|
||||
public RegistryBooleanOptionDescriptor(String option, String registryKey) {
|
||||
@@ -38,4 +39,9 @@ public class RegistryBooleanOptionDescriptor extends BooleanOptionDescription {
|
||||
public void setOptionState(boolean enabled) {
|
||||
Registry.get(myKey).setValue(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChanged() {
|
||||
return Registry.get(myKey).isChangedFromDefault();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -55,7 +55,12 @@ public class RegistryOptionsTopHitProvider extends OptionsTopHitProvider {
|
||||
for (RegistryValue value : Registry.getAll()) {
|
||||
if (value.isBoolean()) {
|
||||
final String key = value.getKey();
|
||||
result.add(new RegistryBooleanOptionDescriptor(key, key));
|
||||
RegistryBooleanOptionDescriptor optionDescriptor = new RegistryBooleanOptionDescriptor(key, key);
|
||||
if (value.isChangedFromDefault()) {
|
||||
result.add(0, optionDescriptor);
|
||||
} else {
|
||||
result.add(optionDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
+8
-17
@@ -17,14 +17,13 @@ package com.intellij.openapi.components.impl.stores
|
||||
|
||||
import com.intellij.openapi.components.StateStorage
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import org.jdom.Element
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
abstract class StateStorageBase<T : Any> : StateStorage {
|
||||
companion object {
|
||||
private val LOG: Logger = Logger.getInstance(StateStorageBase::class.java)
|
||||
}
|
||||
private val LOG: Logger = Logger.getInstance(StateStorageBase::class.java)
|
||||
|
||||
abstract class StateStorageBase<T : Any> : StateStorage {
|
||||
private var mySavingDisabled = false
|
||||
|
||||
protected val storageDataRef: AtomicReference<T> = AtomicReference()
|
||||
@@ -45,13 +44,11 @@ abstract class StateStorageBase<T : Any> : StateStorage {
|
||||
|
||||
protected abstract fun hasState(storageData: T, componentName: String): Boolean
|
||||
|
||||
override fun hasState(componentName: String, reloadData: Boolean): Boolean {
|
||||
override final fun hasState(componentName: String, reloadData: Boolean): Boolean {
|
||||
return hasState(getStorageData(reloadData), componentName)
|
||||
}
|
||||
|
||||
public fun getStorageData(): T = getStorageData(false)
|
||||
|
||||
protected fun getStorageData(reload: Boolean): T {
|
||||
protected fun getStorageData(reload: Boolean = false): T {
|
||||
val storageData = storageDataRef.get()
|
||||
if (storageData != null && !reload) {
|
||||
return storageData
|
||||
@@ -69,23 +66,17 @@ abstract class StateStorageBase<T : Any> : StateStorage {
|
||||
protected abstract fun loadData(): T
|
||||
|
||||
public fun disableSaving() {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Disabled saving for " + toString())
|
||||
}
|
||||
LOG.debug { "Disabled saving for ${toString()}" }
|
||||
mySavingDisabled = true
|
||||
}
|
||||
|
||||
public fun enableSaving() {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Enabled saving " + toString())
|
||||
}
|
||||
LOG.debug { "Enabled saving ${toString()}" }
|
||||
mySavingDisabled = false
|
||||
}
|
||||
|
||||
protected fun checkIsSavingDisabled(): Boolean {
|
||||
if (mySavingDisabled && LOG.isDebugEnabled()) {
|
||||
LOG.debug("Saving disabled for " + toString())
|
||||
}
|
||||
LOG.debug { "Saving disabled for ${toString()}" }
|
||||
return mySavingDisabled
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.openapi.diagnostic
|
||||
|
||||
inline fun Logger.debug(lazyMessage: () -> String) {
|
||||
if (isDebugEnabled) {
|
||||
debug(lazyMessage())
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -15,13 +15,13 @@
|
||||
*/
|
||||
package com.intellij.openapi.editor.impl;
|
||||
|
||||
import com.intellij.Patches;
|
||||
import com.intellij.ide.ui.AntialiasingType;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.ide.ui.UISettingsListener;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.colors.FontPreferences;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.intellij.lang.annotations.JdkConstants;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -111,7 +111,7 @@ public class ComplementaryFontsRegistry {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
ourFontNames.add("Monospaced");
|
||||
} else {
|
||||
if (SystemInfo.isMac) {
|
||||
if (Patches.JDK_MAC_FONT_STYLE_BUG) {
|
||||
fillStyledFontMap();
|
||||
}
|
||||
String[] fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
|
||||
@@ -199,7 +199,7 @@ public class ComplementaryFontsRegistry {
|
||||
@Nullable
|
||||
private static FontInfo doGetFontAbleToDisplay(char c, int size, @JdkConstants.FontStyle int style, @NotNull String defaultFontFamily) {
|
||||
synchronized (lock) {
|
||||
if (SystemInfo.isMac && style > 0 && style < 4) {
|
||||
if (Patches.JDK_MAC_FONT_STYLE_BUG && style > 0 && style < 4) {
|
||||
Pair<String, Integer>[] replacement = ourStyledFontMap.get(defaultFontFamily);
|
||||
if (replacement != null) {
|
||||
defaultFontFamily = replacement[style].first;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
<httpRequestHandler implementation="org.jetbrains.ide.XmlRpcServerImpl$XmlRpcRequestHandler"/>
|
||||
<httpRequestHandler implementation="org.jetbrains.ide.ProjectSetRequestHandler"/>
|
||||
<httpRequestHandler implementation="org.jetbrains.ide.DiffHttpService"/>
|
||||
<httpRequestHandler implementation="org.jetbrains.ide.ActivateApplicationHttpService"/>
|
||||
<httpRequestHandler implementation="org.jetbrains.ide.OpenFileHttpService"/>
|
||||
<httpRequestHandler implementation="org.jetbrains.ide.AboutHttpService"/>
|
||||
<httpRequestHandler implementation="org.jetbrains.ide.JetBrainsProtocolHandlerHttpService"/>
|
||||
|
||||
@@ -129,4 +129,10 @@ public class Patches {
|
||||
* See <a href="https://bugs.openjdk.java.net/browse/JDK-8042123">JDK-8042123</a>
|
||||
*/
|
||||
public static final boolean JDK_BUG_ID_8042123 = !SystemInfo.isJavaVersionAtLeast("1.8.0_40");
|
||||
|
||||
/**
|
||||
* Older JDK versions could mistakenly use derived italics font, when genuine italics font was available in the system.
|
||||
* The issue was fixed in JDK 1.8.0_60 as part of <a href="https://bugs.openjdk.java.net/browse/JDK-8064833">JDK-8064833</a>.
|
||||
*/
|
||||
public static final boolean JDK_MAC_FONT_STYLE_BUG = SystemInfo.isMac && !SystemInfo.isJavaVersionAtLeast("1.8.0_60");
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -181,11 +181,6 @@ public class BuildNumber implements Comparable<BuildNumber> {
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull BuildNumber o) {
|
||||
//if both are snapshots then IDEA and plugin are built from sources,
|
||||
//in that case comparing baselines doesn't make sense,
|
||||
//so we treat those builds equal
|
||||
if (isSnapshot() && o.isSnapshot()) return 0;
|
||||
|
||||
if (myBaselineVersion == o.myBaselineVersion) return myBuildNumber - o.myBuildNumber;
|
||||
return myBaselineVersion - o.myBaselineVersion;
|
||||
}
|
||||
@@ -210,8 +205,6 @@ public class BuildNumber implements Comparable<BuildNumber> {
|
||||
|
||||
BuildNumber that = (BuildNumber)o;
|
||||
|
||||
if (isSnapshot() && ((BuildNumber)o).isSnapshot()) return true;
|
||||
|
||||
if (myBaselineVersion != that.myBaselineVersion) return false;
|
||||
if (myBuildNumber != that.myBuildNumber) return false;
|
||||
if (!myProductCode.equals(that.myProductCode)) return false;
|
||||
@@ -222,9 +215,6 @@ public class BuildNumber implements Comparable<BuildNumber> {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (isSnapshot()) {
|
||||
return 0;
|
||||
}
|
||||
int result = myProductCode.hashCode();
|
||||
result = 31 * result + myBaselineVersion;
|
||||
result = 31 * result + myBuildNumber;
|
||||
|
||||
@@ -63,12 +63,12 @@ public class CompressionUtil {
|
||||
public static final boolean DUMP_COMPRESSION_STATS = SystemProperties.getBooleanProperty("idea.dump.compression.stats", false);
|
||||
|
||||
public static int writeCompressedWithoutOriginalBufferLength(@NotNull DataOutput out, @NotNull byte[] bytes, int length) throws IOException {
|
||||
long started = System.nanoTime();
|
||||
long started = DUMP_COMPRESSION_STATS ? System.nanoTime() : 0;
|
||||
|
||||
final byte[] compressedOutputBuffer = spareBufferLocal.getBuffer(Snappy.maxCompressedLength(length));
|
||||
int compressedSize = Snappy.compress(bytes, 0, length, compressedOutputBuffer, 0);
|
||||
|
||||
final long time = System.nanoTime() - started;
|
||||
final long time = (DUMP_COMPRESSION_STATS ? System.nanoTime() : 0) - started;
|
||||
mySizeAfterCompression.addAndGet(compressedSize);
|
||||
mySizeBeforeCompression.addAndGet(length);
|
||||
int requests = myCompressionRequests.incrementAndGet();
|
||||
@@ -92,11 +92,11 @@ public class CompressionUtil {
|
||||
in.readFully(bytes, 0, size);
|
||||
|
||||
int decompressedRequests = myDecompressionRequests.incrementAndGet();
|
||||
long started = System.nanoTime();
|
||||
long started = DUMP_COMPRESSION_STATS ? System.nanoTime() : 0;
|
||||
|
||||
byte[] decompressedResult = Snappy.uncompress(bytes, 0, size);
|
||||
|
||||
long doneTime = System.nanoTime() - started;
|
||||
long doneTime = (DUMP_COMPRESSION_STATS ? System.nanoTime() : 0) - started;
|
||||
long decompressedSize = myDecompressedSize.addAndGet(size);
|
||||
long decompressedTime = myDecompressionTime.addAndGet(doneTime);
|
||||
if (DUMP_COMPRESSION_STATS && decompressedRequests % 1000 == 0) {
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.intellij.util.CompressionUtil;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import com.intellij.util.containers.SLRUMap;
|
||||
import gnu.trove.TLongArrayList;
|
||||
import org.iq80.snappy.CorruptionException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.*;
|
||||
@@ -201,11 +200,13 @@ public class CompressedAppendableFile {
|
||||
} catch (IOException ignore) {}
|
||||
}
|
||||
|
||||
assert false;
|
||||
assert false:"data corruption detected:"+chunkNumber + "," + myChunkTableLength;
|
||||
return ArrayUtil.EMPTY_BYTE_ARRAY;
|
||||
}
|
||||
catch (CorruptionException e) {
|
||||
catch (RuntimeException e) { // CorruptedException, ArrayIndexOutofBounds, etc
|
||||
throw new IOException(e);
|
||||
} catch(AssertionError ae) {
|
||||
throw new IOException(ae);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -354,7 +354,7 @@ public class PersistentHashMapValueStorage {
|
||||
forceAppender(myPath);
|
||||
|
||||
checkCancellation();
|
||||
long startedTime = System.nanoTime();
|
||||
long startedTime = ourDumpChunkRemovalTime ? System.nanoTime() : 0;
|
||||
long chunk = tailChunkAddress;
|
||||
int chunkCount = 0;
|
||||
|
||||
@@ -426,7 +426,7 @@ public class PersistentHashMapValueStorage {
|
||||
|
||||
if (chunkCount > 1 && !myCompactionMode) {
|
||||
checkCancellation();
|
||||
long endCompactionTime = System.nanoTime();
|
||||
long endCompactionTime = ourDumpChunkRemovalTime ? System.nanoTime() : 0;
|
||||
long diff = endCompactionTime - startedTime;
|
||||
|
||||
myChunksRemovalTime += diff;
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.jetbrains.settingsRepository
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.invokeAndWaitIfNeed
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.vcs.merge.MergeDialogCustomizer
|
||||
@@ -80,9 +81,7 @@ public abstract class BaseRepositoryManager(protected val dir: File) : Repositor
|
||||
|
||||
override fun read(path: String): InputStream? {
|
||||
if (isPathIgnored(path)) {
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug("$path is ignored")
|
||||
}
|
||||
LOG.debug { "$path is ignored" }
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -114,15 +113,11 @@ public abstract class BaseRepositoryManager(protected val dir: File) : Repositor
|
||||
|
||||
override fun write(path: String, content: ByteArray, size: Int): Boolean {
|
||||
if (isPathIgnored(path)) {
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug("$path is ignored")
|
||||
}
|
||||
LOG.debug { "$path is ignored" }
|
||||
return false
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug("Write $path")
|
||||
}
|
||||
LOG.debug { "Write $path" }
|
||||
|
||||
try {
|
||||
lock.write {
|
||||
@@ -145,9 +140,7 @@ public abstract class BaseRepositoryManager(protected val dir: File) : Repositor
|
||||
protected abstract fun addToIndex(file: File, path: String, content: ByteArray, size: Int)
|
||||
|
||||
override fun delete(path: String) {
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug("Remove $path")
|
||||
}
|
||||
LOG.debug { "Remove $path"}
|
||||
|
||||
lock.write {
|
||||
val file = File(dir, path)
|
||||
@@ -212,7 +205,7 @@ class RepositoryVirtualFile(private val path: String) : LightVirtualFile(PathUti
|
||||
override fun getPath() = path
|
||||
|
||||
override fun setBinaryContent(content: ByteArray, newModificationStamp: Long, newTimeStamp: Long, requestor: Any?) {
|
||||
$content = content
|
||||
this.content = content
|
||||
}
|
||||
|
||||
override fun getOutputStream(requestor: Any?, newModificationStamp: Long, newTimeStamp: Long): OutputStream {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.settingsRepository.git
|
||||
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.util.PathUtilRt
|
||||
import com.intellij.util.SmartList
|
||||
@@ -54,9 +55,7 @@ fun commit(repository: Repository, indicator: ProgressIndicator?, commitMessageF
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug(indexDiffToString(diff))
|
||||
}
|
||||
LOG.debug { indexDiffToString(diff) }
|
||||
|
||||
indicator?.checkCanceled()
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.settingsRepository.git
|
||||
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.util.SmartList
|
||||
@@ -64,9 +65,7 @@ open internal class Pull(val manager: GitRepositoryManager, val indicator: Progr
|
||||
var refToMerge = prefetchedRefToMerge ?: fetch() ?: return null
|
||||
val mergeResult = merge(refToMerge, mergeStrategy, commitMessage = commitMessage)
|
||||
val mergeStatus = mergeResult.status
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug(mergeStatus.toString())
|
||||
}
|
||||
LOG.debug { mergeStatus.toString() }
|
||||
|
||||
if (mergeStatus == MergeStatus.CONFLICTING) {
|
||||
return resolveConflicts(mergeResult, repository)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.settingsRepository.git
|
||||
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import org.eclipse.jgit.api.MergeResult
|
||||
import org.eclipse.jgit.merge.MergeStrategy
|
||||
@@ -26,9 +27,7 @@ import org.jetbrains.settingsRepository.UpdateResult
|
||||
internal class Reset(manager: GitRepositoryManager, indicator: ProgressIndicator) : Pull(manager, indicator) {
|
||||
fun reset(toTheirs: Boolean, localRepositoryInitializer: (() -> Unit)? = null): UpdateResult {
|
||||
val message = if (toTheirs) "Overwrite local to ${manager.getUpstream()}" else "Overwrite remote ${manager.getUpstream()} to local"
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug(message)
|
||||
}
|
||||
LOG.debug { message }
|
||||
|
||||
val resetResult = repository.resetHard()
|
||||
val result = MutableUpdateResult(resetResult.updated.keySet(), resetResult.removed)
|
||||
|
||||
@@ -442,4 +442,9 @@ public abstract class AbstractPythonRunConfiguration<T extends AbstractRunConfig
|
||||
Module module = getModule();
|
||||
return module != null? module.getName() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileBeforeLaunchAddedByDefault() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user