Merge remote-tracking branch 'origin/master'

This commit is contained in:
Egor.Ushakov
2014-04-11 12:31:49 +04:00
64 changed files with 1319 additions and 646 deletions
@@ -56,10 +56,8 @@ public class JavaParametersUtil {
if (vmParameters != null) {
vmParameters = ProgramParametersUtil.expandPath(vmParameters, module, project);
if (parameters.getEnv() != null) {
for (Map.Entry<String, String> each : parameters.getEnv().entrySet()) {
vmParameters = StringUtil.replace(vmParameters, "$" + each.getKey() + "$", each.getValue(), false); //replace env usages
}
for (Map.Entry<String, String> each : parameters.getEnv().entrySet()) {
vmParameters = StringUtil.replace(vmParameters, "$" + each.getKey() + "$", each.getValue(), false); //replace env usages
}
}
@@ -18,23 +18,24 @@ package com.intellij.codeInspection.inferNullity;
import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.SequentialModalProgressTask;
import com.intellij.util.SequentialTask;
class AnnotateTask implements SequentialTask {
private final Project myProject;
private final NullityInferrer myInferrer;
private UsageInfo[] myInfos;
private final SequentialModalProgressTask myTask;
private int myCount = 0;
private final int myTotal;
private final NullableNotNullManager myNotNullManager;
public AnnotateTask(Project project, NullityInferrer inferrer, SequentialModalProgressTask progressTask) {
public AnnotateTask(Project project, SequentialModalProgressTask progressTask, UsageInfo[] infos) {
myProject = project;
myInfos = infos;
myNotNullManager = NullableNotNullManager.getInstance(myProject);
myInferrer = inferrer;
myTask = progressTask;
myTotal = myInferrer.getCount();
myTotal = infos.length;
}
@Override
@@ -53,7 +54,7 @@ class AnnotateTask implements SequentialTask {
indicator.setFraction(((double)myCount) / myTotal);
}
myInferrer.apply(myCount++, myProject, myNotNullManager);
NullityInferrer.apply(myProject, myNotNullManager, myInfos[myCount++]);
return isDone();
}
@@ -25,13 +25,14 @@ import com.intellij.codeInsight.daemon.impl.quickfix.LocateLibraryDialog;
import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix;
import com.intellij.history.LocalHistory;
import com.intellij.history.LocalHistoryAction;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
@@ -41,24 +42,35 @@ import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryUtil;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.ui.TitledSeparator;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.usages.*;
import com.intellij.util.Function;
import com.intellij.util.Processor;
import com.intellij.util.SequentialModalProgressTask;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class InferNullityAnnotationsAction extends BaseAnalysisAction {
@NonNls private static final String INFER_NULLITY_ANNOTATIONS = "Infer Nullity Annotations";
@NonNls private static final String ANNOTATE_LOCAL_VARIABLES = "annotate.local.variables";
private JCheckBox myAnnotateLocalVariablesCb;
public InferNullityAnnotationsAction() {
@@ -67,6 +79,9 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
@Override
protected void analyze(@NotNull final Project project, @NotNull final AnalysisScope scope) {
PropertiesComponent.getInstance().setValue(ANNOTATE_LOCAL_VARIABLES, String.valueOf(myAnnotateLocalVariablesCb.isSelected()));
final ProgressManager progressManager = ProgressManager.getInstance();
final int totalFiles = scope.getFileCount();
@@ -91,7 +106,7 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
}
progressIndicator.setFraction(((double)myFileCount) / totalFiles);
}
final Module module = ModuleUtil.findModuleForPsiElement(file);
final Module module = ModuleUtilCore.findModuleForPsiElement(file);
if (module != null && !processed.contains(module)) {
processed.add(module);
if (JavaPsiFacade.getInstance(project)
@@ -173,12 +188,32 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
return;
}
if (scope.checkScopeWritable(project)) return;
PsiDocumentManager.getInstance(project).commitAllDocuments();
final UsageInfo[] usageInfos = findUsages(project, scope);
if (usageInfos == null) return;
if (usageInfos.length < 5) {
SwingUtilities.invokeLater(applyRunnable(project, new Computable<UsageInfo[]>() {
@Override
public UsageInfo[] compute() {
return usageInfos;
}
}));
}
else {
showUsageView(project, usageInfos, scope);
}
}
private UsageInfo[] findUsages(final Project project,
final AnalysisScope scope) {
final NullityInferrer inferrer = new NullityInferrer(myAnnotateLocalVariablesCb.isSelected(), project);
final PsiManager psiManager = PsiManager.getInstance(project);
if (!progressManager.runProcessWithProgressSynchronously(new Runnable() {
final Runnable searchForUsages = new Runnable() {
@Override
public void run() {
final int totalFiles = scope.getFileCount();
scope.accept(new PsiElementVisitor() {
int myFileCount = 0;
@@ -191,9 +226,7 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
if (document == null || virtualFile.getFileType().isBinary()) return; //do not inspect binary files
final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
if (progressIndicator != null) {
if (virtualFile != null) {
progressIndicator.setText2(ProjectUtil.calcRelativeToProjectPath(virtualFile, project));
}
progressIndicator.setText2(ProjectUtil.calcRelativeToProjectPath(virtualFile, project));
progressIndicator.setFraction(((double)myFileCount) / totalFiles);
}
if (file instanceof PsiJavaFile) {
@@ -202,11 +235,22 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
}
});
}
}, INFER_NULLITY_ANNOTATIONS, true, project)) {
return;
};
if (ApplicationManager.getApplication().isDispatchThread()) {
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(searchForUsages, INFER_NULLITY_ANNOTATIONS, true, project)) {
return null;
}
} else {
searchForUsages.run();
}
final Runnable applyRunnable = new Runnable() {
final List<UsageInfo> usages = new ArrayList<UsageInfo>();
inferrer.collect(usages);
return usages.toArray(new UsageInfo[usages.size()]);
}
private static Runnable applyRunnable(final Project project, final Computable<UsageInfo[]> computable) {
return new Runnable() {
@Override
public void run() {
final LocalHistoryAction action = LocalHistory.getInstance().startAction(INFER_NULLITY_ANNOTATIONS);
@@ -214,11 +258,14 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
new WriteCommandAction(project, INFER_NULLITY_ANNOTATIONS) {
@Override
protected void run(Result result) throws Throwable {
if (!inferrer.nothingFoundMessage(project)) {
final UsageInfo[] infos = computable.compute();
if (infos.length > 0) {
final SequentialModalProgressTask progressTask = new SequentialModalProgressTask(project, INFER_NULLITY_ANNOTATIONS, false);
progressTask.setMinIterationTime(200);
progressTask.setTask(new AnnotateTask(project, inferrer, progressTask));
progressTask.setTask(new AnnotateTask(project, progressTask, infos));
ProgressManager.getInstance().run(progressTask);
} else {
NullityInferrer.nothingFoundMessage(project);
}
}
}.execute();
@@ -228,7 +275,6 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
}
}
};
SwingUtilities.invokeLater(applyRunnable);
}
private void restartAnalysis(final Project project, final AnalysisScope scope) {
@@ -241,11 +287,69 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
}
private void showUsageView(final Project project, final UsageInfo[] usageInfos, AnalysisScope scope) {
final UsageTarget[] targets = UsageTarget.EMPTY_ARRAY;
final Ref<Usage[]> convertUsagesRef = new Ref<Usage[]>();
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
convertUsagesRef.set(UsageInfo2UsageAdapter.convert(usageInfos));
}
});
}
}, "Preprocess usages", true, project)) return;
if (convertUsagesRef.isNull()) return;
final Usage[] usages = convertUsagesRef.get();
final UsageViewPresentation presentation = new UsageViewPresentation();
presentation.setTabText("Infer Nullity Preview");
presentation.setShowReadOnlyStatusAsRed(true);
presentation.setShowCancelButton(true);
presentation.setUsagesString(RefactoringBundle.message("usageView.usagesText"));
final UsageView usageView = UsageViewManager.getInstance(project).showUsages(targets, usages, presentation, rerunFactory(project, scope));
final Runnable refactoringRunnable = applyRunnable(project, new Computable<UsageInfo[]>() {
@Override
public UsageInfo[] compute() {
final Set<UsageInfo> infos = UsageViewUtil.getNotExcludedUsageInfos(usageView);
return infos.toArray(new UsageInfo[infos.size()]);
}
});
String canNotMakeString = "Cannot perform operation.\nThere were changes in code after usages have been found.\nPlease perform operation search again.";
usageView.addPerformOperationAction(refactoringRunnable, INFER_NULLITY_ANNOTATIONS, canNotMakeString, INFER_NULLITY_ANNOTATIONS, false);
}
private Factory<UsageSearcher> rerunFactory(final Project project, final AnalysisScope scope) {
return new Factory<UsageSearcher>() {
@Override
public UsageSearcher create() {
return new UsageInfoSearcherAdapter() {
@Override
protected UsageInfo[] findUsages() {
return InferNullityAnnotationsAction.this.findUsages(project, scope);
}
@Override
public void generate(@NotNull Processor<Usage> processor) {
processUsages(processor, project);
}
};
}
};
}
@Override
protected JComponent getAdditionalActionSettings(Project project, BaseAnalysisActionDialog dialog) {
final JPanel panel = new JPanel(new VerticalFlowLayout());
panel.add(new TitledSeparator());
myAnnotateLocalVariablesCb = new JCheckBox("Annotate local variables", false);
myAnnotateLocalVariablesCb = new JCheckBox("Annotate local variables", PropertiesComponent.getInstance().getBoolean(ANNOTATE_LOCAL_VARIABLES, false));
panel.add(myAnnotateLocalVariablesCb);
return panel;
}
@@ -17,7 +17,6 @@ package com.intellij.codeInspection.inferNullity;
import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.codeInsight.intention.AddAnnotationFix;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
@@ -27,6 +26,7 @@ import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Query;
import org.jetbrains.annotations.NotNull;
@@ -145,49 +145,40 @@ public class NullityInferrer {
public void apply(final Project project) {
final NullableNotNullManager manager = NullableNotNullManager.getInstance(project);
for (SmartPsiElementPointer<? extends PsiModifierListOwner> pointer : myNullableSet) {
annotateNullable(project, manager, pointer);
annotateNullable(project, manager, pointer.getElement());
}
for (SmartPsiElementPointer<? extends PsiModifierListOwner> pointer : myNotNullSet) {
annotateNotNull(project, manager, pointer);
annotateNotNull(project, manager, pointer.getElement());
}
nothingFoundMessage(project);
}
public boolean nothingFoundMessage(final Project project) {
if (myNullableSet.isEmpty() && myNotNullSet.isEmpty()) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
throw new RuntimeException(NOTHING_FOUND_TO_INFER);
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Messages.showInfoMessage(project, "No places found to infer @Nullable/@NotNull", "Infer Nullity Results");
}
});
return true;
throw new RuntimeException(NOTHING_FOUND_TO_INFER);
}
return false;
}
private void annotateNotNull(Project project,
NullableNotNullManager manager,
SmartPsiElementPointer<? extends PsiModifierListOwner> pointer) {
final PsiModifierListOwner element = pointer.getElement();
public static void nothingFoundMessage(final Project project) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Messages.showInfoMessage(project, "No places found to infer @Nullable/@NotNull", "Infer Nullity Results");
}
});
}
private static void annotateNotNull(Project project,
NullableNotNullManager manager,
final PsiModifierListOwner element) {
if (element != null) {
if (shouldIgnore(element)) return;
if (element instanceof PsiField && ((PsiField)element).hasInitializer() && element.hasModifierProperty(PsiModifier.FINAL)) return;
invoke(project, element, manager.getDefaultNotNull(), manager.getDefaultNullable());
}
}
private void annotateNullable(Project project,
NullableNotNullManager manager,
SmartPsiElementPointer<? extends PsiModifierListOwner> pointer) {
final PsiModifierListOwner element = pointer.getElement();
private static void annotateNullable(Project project,
NullableNotNullManager manager,
final PsiModifierListOwner element) {
if (element != null) {
if (shouldIgnore(element)) return;
invoke(project, element, manager.getDefaultNullable(), manager.getDefaultNotNull());
}
}
@@ -207,12 +198,11 @@ public class NullityInferrer {
return myNotNullSet.size() + myNullableSet.size();
}
public void apply(int i, Project project, NullableNotNullManager manager) {
if (i < myNullableSet.size()) {
annotateNullable(project, manager, myNullableSet.get(i));
} else {
i -= myNullableSet.size();
annotateNotNull(project, manager, myNotNullSet.get(i));
public static void apply(Project project, NullableNotNullManager manager, UsageInfo info) {
if (info instanceof NullableUsageInfo) {
annotateNullable(project, manager, (PsiModifierListOwner)info.getElement());
} else if (info instanceof NotNullUsageInfo) {
annotateNotNull(project, manager, (PsiModifierListOwner)info.getElement());
}
}
@@ -243,6 +233,33 @@ public class NullityInferrer {
numAnnotationsAdded++;
}
private static class NullableUsageInfo extends UsageInfo {
public NullableUsageInfo(@NotNull PsiElement element) {
super(element);
}
}
private static class NotNullUsageInfo extends UsageInfo {
private NotNullUsageInfo(@NotNull PsiElement element) {
super(element);
}
}
public void collect(List<UsageInfo> usages) {
collect(usages, true);
collect(usages, false);
}
private void collect(List<UsageInfo> usages, boolean nullable) {
final List<SmartPsiElementPointer<? extends PsiModifierListOwner>> set = nullable ? myNullableSet : myNotNullSet;
for (SmartPsiElementPointer<? extends PsiModifierListOwner> elementPointer : set) {
final PsiModifierListOwner element = elementPointer.getElement();
if (element != null && !shouldIgnore(element)) {
usages.add(nullable ? new NullableUsageInfo(element) : new NotNullUsageInfo(element));
}
}
}
private class ExpressionIsNeverNullVisitor extends JavaElementVisitor {
private boolean neverNull = true;
@@ -366,6 +366,10 @@ public class JavaSdkImpl extends JavaSdk {
sdkModificator.addRoot(VirtualFileManager.getInstance().findFileByUrl(url), JavadocOrderRootType.getInstance());
}
}
} else {
if (getVersion(sdk) == JavaSdkVersion.JDK_1_7) {
sdkModificator.addRoot(VirtualFileManager.getInstance().findFileByUrl("http://docs.oracle.com/javafx/2/api/"), JavadocOrderRootType.getInstance());
}
}
attachJdkAnnotations(sdkModificator);
sdkModificator.commitChanges();
@@ -33,6 +33,9 @@ public class AppMain {
private static final String PROPERTY_PORT_NUMBER = "idea.launcher.port";
private static final String PROPERTY_BINPATH = "idea.launcher.bin.path";
private static final String JAVAFX_LAUNCHER = "com.sun.javafx.application.LauncherImpl";
private static final String LAUNCH_APPLICATION_METHOD_NAME = "launchApplication";
private static native void triggerControlBreak();
static {
@@ -110,7 +113,18 @@ public class AppMain {
for (int j = 1; j < args.length; j++) {
parms[j - 1] = args[j];
}
Method m = Class.forName(mainClass).getMethod("main", new Class[]{parms.getClass()});
final Class appClass = Class.forName(mainClass);
Method m;
try {
m = appClass.getMethod("main", new Class[]{parms.getClass()});
}
catch (NoSuchMethodException e) {
if (!startJavaFXApplication(parms, appClass)) {
throw e;
}
return;
}
if (!Modifier.isStatic(m.getModifiers())) {
System.err.println("main method should be static");
return;
@@ -123,6 +137,19 @@ public class AppMain {
}
}
private static boolean startJavaFXApplication(String[] parms, Class appClass) throws NoSuchMethodException {
try {
//check in launch method for application class in the stack trace leads to this hack here
final Method launchApplication = Class.forName(JAVAFX_LAUNCHER).getMethod(LAUNCH_APPLICATION_METHOD_NAME,
new Class[]{appClass.getClass(), parms.getClass()});
launchApplication.invoke(null, new Object[] {appClass, parms});
return true;
}
catch (Throwable e) {
return false;
}
}
private static void ensureAccess(Object reflectionObject) {
// need to call setAccessible here in order to be able to launch package-local classes
// calling setAccessible() via reflection because the method is missing from java version 1.1.x
@@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.roots.libraries;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.projectRoots.JdkUtil;
import com.intellij.openapi.roots.LibraryOrderEntry;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.util.io.JarUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
@@ -35,47 +35,32 @@ import java.util.jar.JarFile;
import java.util.jar.Manifest;
public class JarVersionDetectionUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.libraries.JarVersionDetectionUtil");
private JarVersionDetectionUtil() {
}
private JarVersionDetectionUtil() { }
@Nullable
public static String detectJarVersion(@NotNull final String detectionClass, @NotNull Module module) {
try {
return detectJarVersion(getDetectionJar(detectionClass, module));
}
catch (IOException e) {
return null;
}
}
@Nullable
public static String detectJarVersion(@NotNull String detectionClass, @NotNull List<VirtualFile> files) {
final VirtualFile jar = LibrariesHelper.getInstance().findRootByClass(files, detectionClass);
if (jar != null && jar.getFileSystem() instanceof JarFileSystem) {
final VirtualFile manifestFile = jar.findFileByRelativePath(JarFile.MANIFEST_NAME);
if (manifestFile != null) {
try {
final InputStream input = manifestFile.getInputStream();
try {
return new Manifest(input).getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION);
}
finally {
input.close();
}
}
catch (IOException e) {
LOG.debug(e);
return null;
public static String detectJarVersion(@NotNull String detectionClass, @NotNull Module module) {
for (OrderEntry library : ModuleRootManager.getInstance(module).getOrderEntries()) {
if (library instanceof LibraryOrderEntry) {
VirtualFile jar = LibrariesHelper.getInstance().findJarByClass(((LibraryOrderEntry)library).getLibrary(), detectionClass);
if (jar != null && jar.getFileSystem() instanceof JarFileSystem) {
return JdkUtil.getJarMainAttribute(jar, Attributes.Name.IMPLEMENTATION_VERSION);
}
}
}
return null;
}
@Nullable
public static String detectJarVersion(com.intellij.openapi.vfs.JarFile zipFile) {
public static String detectJarVersion(@NotNull String detectionClass, @NotNull List<VirtualFile> files) {
VirtualFile jarRoot = LibrariesHelper.getInstance().findRootByClass(files, detectionClass);
return jarRoot != null && jarRoot.getFileSystem() instanceof JarFileSystem ?
JdkUtil.getJarMainAttribute(jarRoot, Attributes.Name.IMPLEMENTATION_VERSION) : null;
}
/** @deprecated use {@link JarUtil#getJarAttribute(File, Attributes.Name)} (to remove in IDEA 15) */
@SuppressWarnings("UnusedDeclaration")
public static String detectJarVersion(@Nullable com.intellij.openapi.vfs.JarFile zipFile) {
if (zipFile == null) {
return null;
}
@@ -94,40 +79,17 @@ public class JarVersionDetectionUtil {
}
}
@Nullable
private static com.intellij.openapi.vfs.JarFile getDetectionJar(final String detectionClass, Module module) throws IOException {
for (OrderEntry library : ModuleRootManager.getInstance(module).getOrderEntries()) {
if (library instanceof LibraryOrderEntry) {
VirtualFile file = LibrariesHelper.getInstance().findJarByClass(((LibraryOrderEntry)library).getLibrary(), detectionClass);
if (file != null && file.getFileSystem() instanceof JarFileSystem) {
return JarFileSystem.getInstance().getJarFile(file);
}
}
}
return null;
}
private static String getJarAttribute(@NotNull File jar, @NotNull String attributeName, @Nullable String entryName) throws IOException {
JarFile runJar = new JarFile(jar);
try {
Attributes attributes = entryName == null ? runJar.getManifest().getMainAttributes() : runJar.getManifest().getAttributes(entryName);
return attributes.getValue(attributeName);
}
finally {
runJar.close();
}
}
public static String getBundleVersion(@NotNull File jar) throws IOException {
return getJarAttribute(jar, "Bundle-Version", null);
return JarUtil.getJarAttribute(jar, new Attributes.Name("Bundle-Version"));
}
public static String getImplementationVersion(@NotNull File jar) throws IOException {
return getJarAttributeVersion(jar, Attributes.Name.IMPLEMENTATION_VERSION, null);
return JarUtil.getJarAttribute(jar, Attributes.Name.IMPLEMENTATION_VERSION);
}
public static String getJarAttributeVersion(@NotNull File jar, @NotNull Attributes.Name attributeName, @Nullable String entryName) throws IOException {
return getJarAttribute(jar, attributeName.toString(), entryName);
/** @deprecated use {@link JarUtil#getJarAttribute(File, Attributes.Name)} (to remove in IDEA 15) */
@SuppressWarnings("UnusedDeclaration")
public static String getJarAttributeVersion(@NotNull File jar, @NotNull Attributes.Name attribute, @Nullable String entryName) {
return entryName != null ? JarUtil.getJarAttribute(jar, entryName, attribute) : JarUtil.getJarAttribute(jar, attribute);
}
}
@@ -18,6 +18,7 @@ package com.intellij.execution.configurations;
import com.intellij.execution.configuration.EnvironmentVariablesComponent;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.HashMap;
@@ -26,7 +27,7 @@ import java.util.Map;
public class SimpleProgramParameters {
private final ParametersList myProgramParameters = new ParametersList();
private String myWorkingDirectory;
private Map<String, String> myEnv;
private Map<String, String> myEnv = new THashMap<String, String>();
private boolean myPassParentEnvs = true;
public String getWorkingDirectory() {
@@ -45,15 +46,12 @@ public class SimpleProgramParameters {
return myProgramParameters;
}
@NotNull
public Map<String, String> getEnv() {
return myEnv;
}
public String addEnv(String name, String value) {
if (myEnv == null) {
myEnv = new THashMap<String, String>();
}
return myEnv.put(name, value);
}
@@ -50,18 +50,16 @@ public class JdkUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.projectRoots.JdkUtil");
private static final String WRAPPER_CLASS = "com.intellij.rt.execution.CommandLineWrapper";
private JdkUtil() {
}
private JdkUtil() { }
/**
* @return the specified attribute of the JDK (examines rt.jar) or null if cannot determine the value
*/
@Nullable
public static String getJdkMainAttribute(@NotNull Sdk jdk, Attributes.Name attributeName) {
final VirtualFile homeDirectory = jdk.getHomeDirectory();
if (homeDirectory == null) {
return null;
}
public static String getJdkMainAttribute(@NotNull Sdk jdk, Attributes.Name attribute) {
VirtualFile homeDirectory = jdk.getHomeDirectory();
if (homeDirectory == null) return null;
VirtualFile rtJar = homeDirectory.findFileByRelativePath("jre/lib/rt.jar");
if (rtJar == null) {
rtJar = homeDirectory.findFileByRelativePath("lib/rt.jar");
@@ -72,6 +70,7 @@ public class JdkUtil {
if (rtJar == null) {
rtJar = homeDirectory.findFileByRelativePath("../Classes/classes.jar"); // for mac
}
if (rtJar == null) {
String versionString = jdk.getVersionString();
if (versionString != null) {
@@ -81,34 +80,29 @@ public class JdkUtil {
}
return versionString;
}
VirtualFile rtJarFileContent = JarFileSystem.getInstance().findFileByPath(rtJar.getPath() + JarFileSystem.JAR_SEPARATOR);
if (rtJarFileContent == null) {
return null;
}
com.intellij.openapi.vfs.JarFile manifestJarFile;
try {
manifestJarFile = JarFileSystem.getInstance().getJarFile(rtJarFileContent);
}
catch (IOException e) {
return null;
}
if (manifestJarFile == null) {
return null;
}
try {
com.intellij.openapi.vfs.JarFile.JarEntry entry = manifestJarFile.getEntry(JarFile.MANIFEST_NAME);
if (entry == null) {
return null;
VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(rtJar);
return jarRoot != null ? getJarMainAttribute(jarRoot, attribute) : null;
}
@Nullable
public static String getJarMainAttribute(@NotNull VirtualFile jarRoot, Attributes.Name attribute) {
VirtualFile manifestFile = jarRoot.findFileByRelativePath(JarFile.MANIFEST_NAME);
if (manifestFile != null) {
try {
InputStream stream = manifestFile.getInputStream();
try {
return new Manifest(stream).getMainAttributes().getValue(attribute);
}
finally {
stream.close();
}
}
catch (IOException e) {
LOG.debug(e);
}
InputStream is = manifestJarFile.getInputStream(entry);
Manifest manifest = new Manifest(is);
is.close();
Attributes attributes = manifest.getMainAttributes();
return attributes.getValue(attributeName);
}
catch (IOException e) {
// nothing
}
return null;
}
@@ -31,7 +31,6 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.psi.PsiElement;
import com.intellij.util.SystemProperties;
import com.intellij.util.io.URLUtil;
import com.intellij.util.io.UrlConnectionUtil;
import com.intellij.util.net.HttpConfigurable;
import org.jetbrains.annotations.NonNls;
@@ -42,17 +41,15 @@ import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.Future;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: May 2, 2003
* Time: 8:35:34 PM
* To change this template use Options | File Templates.
* @author db
* @since May 2, 2003
*/
public abstract class AbstractExternalFilter {
private static final boolean EXTRACT_IMAGES_FROM_JARS = SystemProperties.getBooleanProperty("extract.doc.images", true);
@@ -156,11 +153,10 @@ public abstract class AbstractExternalFilter {
boolean referenceUnpackedImage = true;
if (!unpackedImage.isFile()) {
referenceUnpackedImage = false;
JarFileSystem jarFileSystem = JarFileSystem.getInstance();
try {
JarFile jarFile = jarFileSystem.getJarFile(jarFileSystem.findFileByPath(jarPath + URLUtil.JAR_SEPARATOR));
if (jarFile != null) {
JarFile.JarEntry entry = jarFile.getEntry(imgPath);
JarFile jarFile = new JarFile(jarPath);
try {
ZipEntry entry = jarFile.getEntry(imgPath);
if (entry != null) {
FileUtilRt.createIfNotExists(unpackedImage);
FileOutputStream fOut = new FileOutputStream(unpackedImage);
@@ -176,9 +172,12 @@ public abstract class AbstractExternalFilter {
}
unpackedImage.deleteOnExit();
}
finally {
jarFile.close();
}
}
catch (IOException e) {
// Do nothing
LOG.debug(e);
}
}
if (referenceUnpackedImage) {
@@ -385,7 +384,7 @@ public abstract class AbstractExternalFilter {
if (useDt) {
boolean skip = false;
do {
if (StringUtil.toUpperCase(read).contains(H2) && !read.toUpperCase().contains("H2")) { // read=class name in <H2>
data.append(H2);
@@ -43,13 +43,12 @@ public class ProgramParametersConfigurator {
parameters.setWorkingDirectory(getWorkingDir(configuration, project, module));
parameters.setupEnvs(configuration.getEnvs(), configuration.isPassParentEnvs());
if (parameters.getEnv() != null) {
Map<String, String> expanded = new HashMap<String, String>();
for (Map.Entry<String, String> each : parameters.getEnv().entrySet()) {
expanded.put(each.getKey(), expandPath(each.getValue(), module, project));
}
parameters.setEnv(expanded);
Map<String, String> expanded = new HashMap<String, String>();
for (Map.Entry<String, String> each : parameters.getEnv().entrySet()) {
expanded.put(each.getKey(), expandPath(each.getValue(), module, project));
}
parameters.setEnv(expanded);
}
@Nullable
@@ -237,7 +237,7 @@ public abstract class BaseRefactoringProcessor implements Runnable {
Factory<UsageSearcher> factory = new Factory<UsageSearcher>() {
@Override
public UsageSearcher create() {
return new UsageSearcher() {
return new UsageInfoSearcherAdapter() {
@Override
public void generate(@NotNull final Processor<Usage> processor) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@@ -249,38 +249,12 @@ public abstract class BaseRefactoringProcessor implements Runnable {
refreshElements(elements);
}
});
final Ref<UsageInfo[]> refUsages = new Ref<UsageInfo[]>();
final Ref<Boolean> dumbModeOccurred = new Ref<Boolean>();
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
try {
refUsages.set(findUsages());
}
catch (IndexNotReadyException e) {
dumbModeOccurred.set(true);
}
}
});
if (!dumbModeOccurred.isNull()) {
DumbService.getInstance(myProject).showDumbModeNotification("Usage search is not available until indices are ready");
return;
}
final Usage[] usages = ApplicationManager.getApplication().runReadAction(new Computable<Usage[]>() {
@Override
public Usage[] compute() {
return UsageInfo2UsageAdapter.convert(refUsages.get());
}
});
processUsages(processor, myProject);
}
for (final Usage usage : usages) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
processor.process(usage);
}
});
}
@Override
protected UsageInfo[] findUsages() {
return BaseRefactoringProcessor.this.findUsages();
}
};
}
@@ -418,7 +392,7 @@ public abstract class BaseRefactoringProcessor implements Runnable {
final Runnable refactoringRunnable = new Runnable() {
@Override
public void run() {
Set<UsageInfo> usagesToRefactor = getUsageInfosToRefactor(usageView);
Set<UsageInfo> usagesToRefactor = UsageViewUtil.getNotExcludedUsageInfos(usageView);
final UsageInfo[] infos = usagesToRefactor.toArray(new UsageInfo[usagesToRefactor.size()]);
if (ensureElementsWritable(infos, viewDescriptor)) {
execute(infos);
@@ -436,19 +410,6 @@ public abstract class BaseRefactoringProcessor implements Runnable {
RefactoringBundle.message("usageView.doAction"), false);
}
private static Set<UsageInfo> getUsageInfosToRefactor(final UsageView usageView) {
Set<Usage> excludedUsages = usageView.getExcludedUsages();
Set<UsageInfo> usageInfos = new LinkedHashSet<UsageInfo>();
for (Usage usage : usageView.getUsages()) {
if (usage instanceof UsageInfo2UsageAdapter && !excludedUsages.contains(usage)) {
UsageInfo usageInfo = ((UsageInfo2UsageAdapter)usage).getUsageInfo();
usageInfos.add(usageInfo);
}
}
return usageInfos;
}
private void doRefactoring(@NotNull final Collection<UsageInfo> usageInfoSet) {
for (Iterator<UsageInfo> iterator = usageInfoSet.iterator(); iterator.hasNext();) {
UsageInfo usageInfo = iterator.next();
@@ -30,6 +30,9 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.refactoring.util.MoveRenameUsageInfo;
import com.intellij.refactoring.util.NonCodeUsageInfo;
import com.intellij.usages.Usage;
import com.intellij.usages.UsageInfo2UsageAdapter;
import com.intellij.usages.UsageView;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -163,4 +166,17 @@ public class UsageViewUtil {
Project project = info.getProject();
FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, file, offset), requestFocus);
}
public static Set<UsageInfo> getNotExcludedUsageInfos(final UsageView usageView) {
Set<Usage> excludedUsages = usageView.getExcludedUsages();
Set<UsageInfo> usageInfos = new LinkedHashSet<UsageInfo>();
for (Usage usage : usageView.getUsages()) {
if (usage instanceof UsageInfo2UsageAdapter && !excludedUsages.contains(usage)) {
UsageInfo usageInfo = ((UsageInfo2UsageAdapter)usage).getUsageInfo();
usageInfos.add(usageInfo);
}
}
return usageInfos;
}
}
@@ -26,6 +26,7 @@ import com.intellij.openapi.project.CacheUpdateRunner;
import com.intellij.openapi.project.DumbModeTask;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.CollectingContentIterator;
import com.intellij.openapi.roots.impl.PushedFilePropertiesUpdater;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
@@ -50,6 +51,8 @@ public class UnindexedFilesUpdater extends DumbModeTask {
}
private void updateUnindexedFiles(ProgressIndicator indicator) {
PushedFilePropertiesUpdater.getInstance(myProject).performPushTasks(indicator);
indicator.setIndeterminate(true);
indicator.setText(IdeBundle.message("progress.indexing.scanning"));
@@ -31,6 +31,7 @@ import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
@@ -40,6 +41,8 @@ import com.intellij.openapi.vfs.*;
import com.intellij.ui.GuiUtils;
import com.intellij.util.ArrayUtil;
import com.intellij.util.PathUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.URLUtil;
import com.intellij.util.io.ZipUtil;
import com.intellij.util.ui.OptionsDialog;
import org.jetbrains.annotations.Contract;
@@ -54,8 +57,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -186,21 +191,17 @@ public class BrowserLauncherAppless extends BrowserLauncher {
url = url.substring(0, sharpPos);
}
VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url);
if (file == null || !(file.getFileSystem() instanceof JarFileSystem)) return null;
Pair<String, String> pair = URLUtil.splitJarUrl(url);
if (pair == null) return null;
JarFileSystem jarFileSystem = (JarFileSystem)file.getFileSystem();
VirtualFile jarVirtualFile = jarFileSystem.getVirtualFileForJar(file);
if (jarVirtualFile == null) return null;
File jarFile = new File(FileUtil.toSystemDependentName(pair.first));
if (!jarFile.canRead()) return null;
String targetFilePath = file.getPath();
String targetFileRelativePath = StringUtil.substringAfter(targetFilePath, JarFileSystem.JAR_SEPARATOR);
LOG.assertTrue(targetFileRelativePath != null);
String jarUrl = StandardFileSystems.FILE_PROTOCOL_PREFIX + FileUtil.toSystemIndependentName(jarFile.getPath());
String jarLocationHash = jarFile.getName() + "." + Integer.toHexString(jarUrl.hashCode());
final File outputDir = new File(getExtractedFilesDir(), jarLocationHash);
String jarVirtualFileLocationHash = jarVirtualFile.getName() + Integer.toHexString(jarVirtualFile.getUrl().hashCode());
final File outputDir = new File(getExtractedFilesDir(), jarVirtualFileLocationHash);
final String currentTimestamp = String.valueOf(new File(jarVirtualFile.getPath()).lastModified());
final String currentTimestamp = String.valueOf(new File(jarFile.getPath()).lastModified());
final File timestampFile = new File(outputDir, ".idea.timestamp");
String previousTimestamp = null;
@@ -239,21 +240,21 @@ public class BrowserLauncherAppless extends BrowserLauncher {
return null;
}
@SuppressWarnings("ConstantConditions")
final ZipFile zipFile = jarFileSystem.getJarFile(file).getZipFile();
if (zipFile == null) {
return null;
}
ZipEntry entry = zipFile.getEntry(targetFileRelativePath);
if (entry == null) {
return null;
}
InputStream is = zipFile.getInputStream(entry);
boolean closeZip = true;
final ZipFile zipFile = new ZipFile(jarFile);
try {
ZipEntry entry = zipFile.getEntry(pair.second);
if (entry == null) {
return null;
}
InputStream is = zipFile.getInputStream(entry);
ZipUtil.extractEntry(entry, is, outputDir);
closeZip = false;
}
finally {
is.close();
if (closeZip) {
zipFile.close();
}
}
ApplicationManager.getApplication().invokeLater(new Runnable() {
@@ -266,8 +267,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
final int[] counter = new int[]{0};
class MyFilter implements FilenameFilter {
private final Set<File> myImportantDirs = new HashSet<File>(
Arrays.asList(outputDir, new File(outputDir, "resources")));
private final Set<File> myImportantDirs = ContainerUtil.newHashSet(outputDir, new File(outputDir, "resources"));
private final boolean myImportantOnly;
private MyFilter(boolean importantOnly) {
@@ -287,19 +287,23 @@ public class BrowserLauncherAppless extends BrowserLauncher {
}
try {
ZipUtil.extract(zipFile, outputDir, new MyFilter(true));
ZipUtil.extract(zipFile, outputDir, new MyFilter(false));
FileUtil.writeToFile(timestampFile, currentTimestamp.getBytes());
}
catch (IOException ignore) {
try {
ZipUtil.extract(zipFile, outputDir, new MyFilter(true));
ZipUtil.extract(zipFile, outputDir, new MyFilter(false));
FileUtil.writeToFile(timestampFile, currentTimestamp);
}
finally {
zipFile.close();
}
}
catch (IOException ignore) { }
}
}.queue();
}
});
}
return VfsUtilCore.pathToUrl(FileUtil.toSystemIndependentName(new File(outputDir, targetFileRelativePath).getPath())) + anchor;
return VfsUtilCore.pathToUrl(FileUtil.toSystemIndependentName(new File(outputDir, pair.second).getPath())) + anchor;
}
catch (IOException e) {
LOG.warn(e);
@@ -421,6 +425,15 @@ public class BrowserLauncherAppless extends BrowserLauncher {
@Nullable final Project project,
String[] additionalParameters) {
GeneralCommandLine commandLine = new GeneralCommandLine(command);
if (url != null && url.startsWith("jar:")) {
String files = extractFiles(url);
if (files == null) {
return false;
}
url = files;
}
if (url != null) {
commandLine.addParameter(url);
}
@@ -833,8 +833,20 @@ public class IdeEventQueue extends EventQueue {
return myKeyEventDispatcher;
}
/**
* Same as {@link #blockNextEvents(java.awt.event.MouseEvent, com.intellij.ide.IdeEventQueue.BlockMode)} with <code>blockMode</code> equal
* to <code>COMPLETE</code>.
*/
public void blockNextEvents(final MouseEvent e) {
myMouseEventDispatcher.blockNextEvents(e);
blockNextEvents(e, BlockMode.COMPLETE);
}
/**
* When <code>blockMode</code> is <code>COMPLETE</code>, blocks following related mouse events completely, when <code>blockMode</code> is
* <code>ACTIONS</code> only blocks performing actions bound to corresponding mouse shortcuts.
*/
public void blockNextEvents(final MouseEvent e, BlockMode blockMode) {
myMouseEventDispatcher.blockNextEvents(e, blockMode);
}
public boolean isSuspendMode() {
@@ -976,4 +988,11 @@ public class IdeEventQueue extends EventQueue {
myFrequentEventDetector.eventHappened();
super.postEvent(theEvent);
}
/**
* @see com.intellij.ide.IdeEventQueue#blockNextEvents(java.awt.event.MouseEvent, com.intellij.ide.IdeEventQueue.BlockMode)
*/
public enum BlockMode {
COMPLETE, ACTIONS
}
}
@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.ide.passwordSafe.ui.PasswordPromptComponent">
<grid id="27dc6" binding="myRootPanel" layout-manager="GridLayoutManager" row-count="6" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="549" height="186"/>
</constraints>
<properties/>
<border type="empty">
<size top="15" left="10" bottom="0" right="20"/>
</border>
<children>
<grid id="654f6" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="1" row-span="5" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="96e22" class="javax.swing.JLabel" binding="myMessageLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Message"/>
</properties>
</component>
<grid id="8cb22" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="3" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="empty">
<size top="10" left="10" bottom="0" right="10"/>
</border>
<children>
<component id="f016b" class="javax.swing.JCheckBox" binding="myRememberCheckBox" default-binding="true">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Remember"/>
</properties>
</component>
<grid id="d60a9" binding="myUserPanel" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="8d49c" class="javax.swing.JLabel" binding="myUserLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;User"/>
</properties>
</component>
<component id="70076" class="javax.swing.JTextField" binding="myUserTextField" default-binding="true">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="200" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
</children>
</grid>
<grid id="83777" binding="myPasswordPanel" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="ee2ea" class="javax.swing.JLabel" binding="myPasswordLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="5aff2"/>
<text value="&amp;Password"/>
</properties>
</component>
<component id="5aff2" class="javax.swing.JPasswordField" binding="myPasswordField" default-binding="true">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="200" height="-1"/>
</grid>
</constraints>
<properties>
<text value=""/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
</children>
</grid>
<component id="99da1" class="javax.swing.JLabel" binding="myIconLabel">
<constraints>
<grid row="0" column="0" row-span="3" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="icon"/>
</properties>
</component>
<vspacer id="4892f">
<constraints>
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
</children>
</grid>
</form>
@@ -0,0 +1,111 @@
/*
* Copyright 2000-2014 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.ide.passwordSafe.ui;
import com.intellij.ide.passwordSafe.config.PasswordSafeSettings;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ui.UIUtil;
import javax.swing.*;
/**
* @author gregsh
*/
public class PasswordPromptComponent {
private JPanel myRootPanel;
private JPanel myUserPanel;
private JPanel myPasswordPanel;
private JPasswordField myPasswordField;
private JCheckBox myRememberCheckBox;
private JLabel myMessageLabel;
private JLabel myPasswordLabel;
private JLabel myUserLabel;
private JTextField myUserTextField;
private JLabel myIconLabel;
public PasswordPromptComponent(PasswordSafeSettings.ProviderType type,
String message,
boolean showUserName,
String passwordPrompt,
String rememberPrompt) {
myIconLabel.setText("");
myIconLabel.setIcon(Messages.getWarningIcon());
myMessageLabel.setFont(UIUtil.getLabelFont(UIUtil.FontSize.SMALL));
myMessageLabel.setText(message);
setTargetProviderType(type);
setUserInputVisible(showUserName);
if (passwordPrompt != null) myPasswordLabel.setText(passwordPrompt);
if (rememberPrompt != null) myRememberCheckBox.setText(rememberPrompt);
}
public JComponent getComponent() {
return myRootPanel;
}
public JComponent getPreferredFocusedComponent() {
return myUserTextField.isShowing() && StringUtil.isEmpty(myUserTextField.getText()) ?
myUserTextField : myPasswordField;
}
private void setUserInputVisible(boolean visible) {
UIUtil.setEnabled(myUserPanel, visible, true);
myUserPanel.setVisible(visible);
}
private void setTargetProviderType(PasswordSafeSettings.ProviderType type) {
switch (type) {
case MASTER_PASSWORD:
myRememberCheckBox.setEnabled(true);
myRememberCheckBox.setSelected(true);
myRememberCheckBox.setToolTipText("The password will be stored between application sessions.");
break;
case MEMORY_ONLY:
myRememberCheckBox.setEnabled(true);
myRememberCheckBox.setSelected(true);
myRememberCheckBox.setToolTipText("The password will be stored only during this application session.");
break;
case DO_NOT_STORE:
myRememberCheckBox.setVisible(false);
myRememberCheckBox.setEnabled(false);
myRememberCheckBox.setSelected(false);
myRememberCheckBox.setToolTipText("The password storing is disabled.");
break;
default:
throw new AssertionError("Unknown policy type: " + type);
}
}
public String getUserName() {
return myUserTextField.getText();
}
public void setUserName(String text) {
myUserTextField.setText(text);
}
public char[] getPassword() {
return myPasswordField.getPassword();
}
public void setPassword(String text) {
myPasswordField.setText(text);
}
public boolean isRememberChecked() {
return myRememberCheckBox.isSelected();
}
}
@@ -1,56 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.ide.passwordSafe.ui.PasswordSafePromptDialog">
<grid id="27dc6" binding="myRootPanel" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="549" height="104"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="96e22" class="javax.swing.JLabel" binding="myMessageLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Message"/>
</properties>
</component>
<component id="ee2ea" class="javax.swing.JLabel" binding="myPromptLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="5aff2"/>
<text value="&amp;Password"/>
</properties>
</component>
<component id="5aff2" class="javax.swing.JPasswordField" binding="myPasswordField" default-binding="true">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="f016b" class="javax.swing.JCheckBox" binding="myRememberPasswordCheckBox" default-binding="true">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Remember"/>
</properties>
</component>
<hspacer id="2cfb">
<constraints>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<vspacer id="4892f">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
</children>
</grid>
</form>
@@ -25,12 +25,14 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.concurrent.atomic.AtomicReference;
/**
* The generic password dialog. Use it to ask a password from user with option to remember it.
@@ -38,54 +40,46 @@ import java.util.concurrent.atomic.AtomicReference;
public class PasswordSafePromptDialog extends DialogWrapper {
private static final Logger LOG = Logger.getInstance(PasswordSafePromptDialog.class.getName());
private JPasswordField myPasswordField;
private JCheckBox myRememberPasswordCheckBox;
private JPanel myRootPanel;
private JLabel myMessageLabel;
private JLabel myPromptLabel;
private final PasswordPromptComponent myComponent;
/**
* The private constructor. Note that it does not do init on dialog.
*
* @param project the project
* @param passwordSafe the passwordSafe instance
* @param title the dialog title
* @param message the message on the dialog
* @param type
*/
private PasswordSafePromptDialog(@Nullable Project project, @NotNull PasswordSafeImpl passwordSafe, String title, String message) {
private PasswordSafePromptDialog(@Nullable Project project, @NotNull String title, @NotNull PasswordPromptComponent component) {
super(project, true);
setTitle(title);
myMessageLabel.setText(message);
switch (passwordSafe.getSettings().getProviderType()) {
case MASTER_PASSWORD:
myRememberPasswordCheckBox.setEnabled(true);
myRememberPasswordCheckBox.setSelected(true);
myRememberPasswordCheckBox.setToolTipText("The password will be stored between application sessions.");
break;
case MEMORY_ONLY:
myRememberPasswordCheckBox.setEnabled(true);
myRememberPasswordCheckBox.setSelected(true);
myRememberPasswordCheckBox.setToolTipText("The password will be stored only during this application session.");
break;
case DO_NOT_STORE:
myRememberPasswordCheckBox.setEnabled(false);
myRememberPasswordCheckBox.setSelected(false);
myRememberPasswordCheckBox.setToolTipText("The password storing is disabled.");
break;
default:
LOG.error("Unknown policy type: " + passwordSafe.getSettings().getProviderType());
}
myComponent = component;
setResizable(false);
init();
}
public PasswordPromptComponent getComponent() {
return myComponent;
}
@Override
protected JComponent createCenterPanel() {
return myRootPanel;
return myComponent.getComponent();
}
@Override
public JComponent getPreferredFocusedComponent() {
return myPasswordField;
return myComponent.getPreferredFocusedComponent();
}
@Nullable
public static Pair<String, String> showUserPasswordDialog(Project project, String title, String message, String defUser) {
PasswordPromptComponent component = new PasswordPromptComponent(PasswordSafeSettings.ProviderType.DO_NOT_STORE, message, true, null, null);
component.setUserName(StringUtil.notNullize(defUser));
if (new PasswordSafePromptDialog(project, title, component).showAndGet()) {
return Pair.create(component.getUserName(), new String(component.getPassword()));
}
return null;
}
/**
@@ -206,28 +200,22 @@ public class PasswordSafePromptDialog extends DialogWrapper {
LOG.debug("Failed to retrieve or reset password", ex);
}
}
final AtomicReference<String> pw = new AtomicReference<String>(null);
final Ref<String> ref = Ref.create();
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
public void run() {
final PasswordSafePromptDialog d = new PasswordSafePromptDialog(project, ps, title, message);
if (promptLabel != null) {
d.myPromptLabel.setText(promptLabel);
}
if (checkboxLabel != null) {
d.myRememberPasswordCheckBox.setText(checkboxLabel);
}
d.init();
PasswordSafeSettings.ProviderType type = ps.getSettings().getProviderType();
final PasswordPromptComponent component = new PasswordPromptComponent(type, message, false, promptLabel, checkboxLabel);
PasswordSafePromptDialog d = new PasswordSafePromptDialog(project, title, component);
d.setErrorText(error);
d.show();
if (d.isOK()) {
String p = new String(d.myPasswordField.getPassword());
pw.set(p);
if (d.showAndGet()) {
ref.set(new String(component.getPassword()));
try {
if (d.myRememberPasswordCheckBox.isSelected()) {
ps.storePassword(project, requestor, key, p);
if (component.isRememberChecked()) {
ps.storePassword(project, requestor, key, ref.get());
}
else if (!ps.getSettings().getProviderType().equals(PasswordSafeSettings.ProviderType.DO_NOT_STORE)) {
ps.getMemoryProvider().storePassword(project, requestor, key, p);
else if (!type.equals(PasswordSafeSettings.ProviderType.DO_NOT_STORE)) {
ps.getMemoryProvider().storePassword(project, requestor, key, ref.get());
}
}
catch (PasswordSafeException e) {
@@ -239,7 +227,7 @@ public class PasswordSafePromptDialog extends DialogWrapper {
}
}
}, modalityState == null ? ModalityState.defaultModalityState() : modalityState);
return pw.get();
return ref.get();
}
}
@@ -306,6 +306,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
private VisualPosition myTargetMultiSelectionPosition;
private boolean myMultiSelectionInProgress;
private boolean myLastPressCreatedCaret;
// Set when the selection (normal or block one) initiated by mouse drag becomes noticeable (at least one character is selected).
// Reset on mouse press event.
private boolean myCurrentDragIsSubstantial;
private CaretImpl myPrimaryCaret;
@@ -4204,12 +4206,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (isColumnMode() || e.isAltDown()) {
if (myCaretModel.supportsMultipleCarets()) {
if (myLastMousePressedLocation != null && (myCurrentDragIsSubstantial || !newLogicalCaret.equals(myLastMousePressedLocation))) {
selectionModel.setBlockSelection(myLastMousePressedLocation, newLogicalCaret);
myCurrentDragIsSubstantial = true;
setBlockSelectionAndBlockActions(e, myLastMousePressedLocation, newLogicalCaret);
}
} else {
final LogicalPosition blockStart = selectionModel.hasBlockSelection() ? selectionModel.getBlockStart() : oldLogicalCaret;
selectionModel.setBlockSelection(blockStart, getCaretModel().getLogicalPosition());
setBlockSelectionAndBlockActions(e, blockStart, getCaretModel().getLogicalPosition());
}
}
else {
@@ -4270,10 +4271,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
}
if (oldVisLeadSelectionStart != null) {
selectionModel.setSelection(oldVisLeadSelectionStart, oldSelectionStart, newVisualCaret, newCaretOffset);
setSelectionAndBlockActions(e, oldVisLeadSelectionStart, oldSelectionStart, newVisualCaret, newCaretOffset);
}
else {
selectionModel.setSelection(oldSelectionStart, newCaretOffset);
setSelectionAndBlockActions(e, oldSelectionStart, newCaretOffset);
}
cancelAutoResetForMouseSelectionState();
}
@@ -4297,9 +4298,36 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
else {
myScrollingTimer.start(dx, dy);
onSubstantialDrag(e);
}
}
private void setSelectionAndBlockActions(@NotNull MouseEvent mouseDragEvent, int startOffset, int endOffset) {
mySelectionModel.setSelection(startOffset, endOffset);
if (myCurrentDragIsSubstantial || startOffset != endOffset) {
onSubstantialDrag(mouseDragEvent);
}
}
private void setSelectionAndBlockActions(@NotNull MouseEvent mouseDragEvent, VisualPosition startPosition, int startOffset, VisualPosition endPosition, int endOffset) {
mySelectionModel.setSelection(startPosition, startOffset, endPosition, endOffset);
if (myCurrentDragIsSubstantial || startOffset != endOffset || !Comparing.equal(startPosition, endPosition)) {
onSubstantialDrag(mouseDragEvent);
}
}
private void setBlockSelectionAndBlockActions(@NotNull MouseEvent mouseDragEvent, @NotNull LogicalPosition startPosition, @NotNull LogicalPosition endPosition) {
mySelectionModel.setBlockSelection(startPosition, endPosition);
if (myCurrentDragIsSubstantial || !startPosition.equals(endPosition)) {
onSubstantialDrag(mouseDragEvent);
}
}
private void onSubstantialDrag(@NotNull MouseEvent mouseDragEvent) {
IdeEventQueue.getInstance().blockNextEvents(mouseDragEvent, IdeEventQueue.BlockMode.ACTIONS);
myCurrentDragIsSubstantial = true;
}
private static class RepaintCursorCommand implements Runnable {
private long mySleepTime = 500;
private boolean myIsBlinkCaret = true;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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,6 +17,7 @@ package com.intellij.openapi.keymap.impl;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.ide.DataManager;
import com.intellij.ide.IdeEventQueue;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
@@ -55,9 +56,8 @@ import static java.awt.event.MouseEvent.*;
public final class IdeMouseEventDispatcher {
private final PresentationFactory myPresentationFactory = new PresentationFactory();
private final ArrayList<AnAction> myActions = new ArrayList<AnAction>(1);
private final Map<Container, Integer> myRootPane2BlockedId = new HashMap<Container, Integer>();
private final Map<Container, BlockState> myRootPane2BlockedId = new HashMap<Container, BlockState>();
private int myLastHorScrolledComponentHash = 0;
private MouseEvent myPreviousMouseEvent;
// Don't compare MouseEvent ids. Swing has wrong sequence of events: first is mouse_clicked(500)
// then mouse_pressed(501), mouse_released(502) etc. Here, mouse events sorted so we can compare
@@ -122,9 +122,6 @@ public final class IdeMouseEventDispatcher {
* to normal event dispatching.
*/
public boolean dispatchMouseEvent(MouseEvent e) {
MouseEvent previousEvent = myPreviousMouseEvent;
myPreviousMouseEvent = e;
Component c = e.getComponent();
//frame activation by mouse click
@@ -160,17 +157,18 @@ public final class IdeMouseEventDispatcher {
ignore = true;
}
if (e.getID() == MOUSE_RELEASED && previousEvent != null && previousEvent.getID() == MOUSE_DRAGGED) {
ignore = true; // we don't want to process action bindings on mouse release at the end of drag operation
}
final JRootPane root = findRoot(e);
final JRootPane root = findRoot(e);
if (root != null) {
final Integer lastId = myRootPane2BlockedId.get(root);
if (lastId != null) {
if (SWING_EVENTS_PRIORITY.indexOf(lastId) < SWING_EVENTS_PRIORITY.indexOf(e.getID())) {
myRootPane2BlockedId.put(root, e.getID());
return true;
BlockState blockState = myRootPane2BlockedId.get(root);
if (blockState != null) {
if (SWING_EVENTS_PRIORITY.indexOf(blockState.currentEventId) < SWING_EVENTS_PRIORITY.indexOf(e.getID())) {
blockState.currentEventId = e.getID();
if (blockState.blockMode == IdeEventQueue.BlockMode.COMPLETE) {
return true;
}
else {
ignore = true;
}
} else {
myRootPane2BlockedId.remove(root);
}
@@ -322,11 +320,11 @@ public final class IdeMouseEventDispatcher {
return c != null && "y.view.Graph2DView".equals(c.getClass().getName());
}
public void blockNextEvents(final MouseEvent e) {
public void blockNextEvents(final MouseEvent e, IdeEventQueue.BlockMode blockMode) {
final JRootPane root = findRoot(e);
if (root == null) return;
myRootPane2BlockedId.put(root, e.getID());
myRootPane2BlockedId.put(root, new BlockState(e.getID(), blockMode));
}
@Nullable
@@ -346,4 +344,14 @@ public final class IdeMouseEventDispatcher {
return root;
}
private static class BlockState {
private int currentEventId;
private final IdeEventQueue.BlockMode blockMode;
private BlockState(int id, IdeEventQueue.BlockMode mode) {
currentEventId = id;
blockMode = mode;
}
}
}
@@ -27,6 +27,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.progress.util.ProgressWrapper;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
@@ -40,6 +41,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class CacheUpdateRunner {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.project.CacheUpdateRunner");
private static final Key<Boolean> FAILED_TO_INDEX = Key.create("FAILED_TO_INDEX");
private static final int PROC_COUNT = Runtime.getRuntime().availableProcessors();
private final Project myProject;
private final Collection<CacheUpdater> myUpdaters;
@@ -251,9 +253,18 @@ public class CacheUpdateRunner {
myInnerIndicator.checkCanceled();
if (!myProject.isDisposed()) {
final VirtualFile file = fileContent.getVirtualFile();
if (file.isValid()) {
try {
myProgressUpdater.consume(file);
myProcessor.consume(fileContent);
if (file.isValid() && !file.isDirectory() && !Boolean.TRUE.equals(file.getUserData(FAILED_TO_INDEX))) {
myProcessor.consume(fileContent);
}
}
catch (ProcessCanceledException e) {
throw e;
}
catch (Throwable e) {
LOG.error("Error while indexing " + file.getPresentableUrl() + "\n" + "To reindex this file IDEA has to be restarted", e);
file.putUserData(FAILED_TO_INDEX, Boolean.TRUE);
}
}
}
@@ -21,7 +21,6 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
@@ -33,7 +32,6 @@ import java.util.*;
public class CacheUpdateSession {
private static final Logger LOG = Logger.getInstance("#" + CacheUpdateSession.class.getName());
private static final Key<Boolean> FAILED_TO_INDEX = Key.create(CacheUpdateSession.class.getSimpleName() + ".FAILED_TO_INDEX");
private final List<VirtualFile> myFilesToUpdate;
private final int myJobsToDo;
private final List<Pair<CacheUpdater, Collection<VirtualFile>>> myUpdatersWithFiles = new ArrayList<Pair<CacheUpdater, Collection<VirtualFile>>>();
@@ -94,13 +92,14 @@ public class CacheUpdateSession {
VirtualFile file = content.getVirtualFile();
boolean isValid = file.isValid() && !file.isDirectory();
Throwable exception = null;
while (true) {
Pair<CacheUpdater, Collection<VirtualFile>> pair = getPair(file);
if (pair == null) return;
if (pair == null) break;
CacheUpdater eachUpdater = pair.getFirst();
Collection<VirtualFile> eachFiles = pair.getSecond();
try {
if (isValid && !Boolean.TRUE.equals(file.getUserData(FAILED_TO_INDEX))) {
if (isValid && exception == null) {
eachUpdater.processFile(content);
}
}
@@ -108,11 +107,13 @@ public class CacheUpdateSession {
throw e;
}
catch (Throwable e) {
LOG.error("Error while indexing " + file.getPresentableUrl() + "\n" + "To reindex this file IDEA has to be restarted", e);
file.putUserData(FAILED_TO_INDEX, Boolean.TRUE);
exception = e;
}
removeFile(file, eachUpdater, eachFiles);
}
if (exception instanceof RuntimeException) throw (RuntimeException)exception;
if (exception instanceof Error) throw (Error)exception;
if (exception != null) throw new RuntimeException(exception);
}
private synchronized void removeFile(@NotNull VirtualFile file, @NotNull CacheUpdater eachUpdater, @NotNull Collection<VirtualFile> eachFiles) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.keymap.impl;
import com.intellij.ide.IdeEventQueue;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -24,7 +25,6 @@ import com.intellij.openapi.keymap.ex.KeymapManagerEx;
import com.intellij.testFramework.LightPlatformTestCase;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
public class IdeMouseEventDispatcherTest extends LightPlatformTestCase {
@@ -34,7 +34,7 @@ public class IdeMouseEventDispatcherTest extends LightPlatformTestCase {
private KeymapImpl keymap;
private Keymap mySavedKeymap;
private Component myEventSource;
private JFrame myEventSource;
private int myActionExecutionCount;
public void setUp() throws Exception {
@@ -49,12 +49,13 @@ public class IdeMouseEventDispatcherTest extends LightPlatformTestCase {
mySavedKeymap = KeymapManagerEx.getInstanceEx().getActiveKeymap();
KeymapManagerEx.getInstanceEx().setActiveKeymap(keymap);
myEventSource = new JPanel();
myEventSource = new JFrame();
myEventSource.setSize(1,1);
}
@Override
public void tearDown() throws Exception {
myEventSource.dispose();
KeymapManagerEx.getInstanceEx().getSchemesManager().removeScheme(keymap);
KeymapManagerEx.getInstanceEx().setActiveKeymap(mySavedKeymap);
ActionManager.getInstance().unregisterAction(OUR_TEST_ACTION);
@@ -70,11 +71,13 @@ public class IdeMouseEventDispatcherTest extends LightPlatformTestCase {
assertEquals(1, myActionExecutionCount);
}
public void testActionSuppressionAfterDrag() throws Exception {
public void testActionBlocking() throws Exception {
IdeMouseEventDispatcher dispatcher = new IdeMouseEventDispatcher();
assertFalse(dispatcher.dispatchMouseEvent(new MouseEvent(myEventSource, MouseEvent.MOUSE_PRESSED, 0, 0, 0, 0, 1, false, MouseEvent.BUTTON2)));
assertFalse(dispatcher.dispatchMouseEvent(new MouseEvent(myEventSource, MouseEvent.MOUSE_DRAGGED, 0, 0, 0, 0, 0, false, MouseEvent.BUTTON2)));
MouseEvent dragEvent = new MouseEvent(myEventSource, MouseEvent.MOUSE_DRAGGED, 0, 0, 0, 0, 0, false, MouseEvent.BUTTON2);
assertFalse(dispatcher.dispatchMouseEvent(dragEvent));
dispatcher.blockNextEvents(dragEvent, IdeEventQueue.BlockMode.ACTIONS);
assertFalse(dispatcher.dispatchMouseEvent(new MouseEvent(myEventSource, MouseEvent.MOUSE_RELEASED, 0, 0, 0, 0, 1, false, MouseEvent.BUTTON2)));
assertEquals(0, myActionExecutionCount);
}
@@ -440,14 +440,25 @@ public class PersistentMapTest extends TestCase {
TIntIntHashMap checkMap = new TIntIntHashMap(size);
Random r = new Random(1);
while(size != checkMap.size()) {
checkMap.put(r.nextInt(), size == 0 ? 0 : r.nextInt());
if (checkMap.size() == 0) {
checkMap.put(r.nextInt(), 0);
checkMap.put(r.nextInt(), 0);
checkMap.put(0, r.nextInt());
} else {
checkMap.put(r.nextInt(), r.nextInt());
}
}
long started = System.currentTimeMillis();
PersistentHashMap<Integer, Integer> map = null;
try {
map = new PersistentHashMap<Integer, Integer>(file, EnumeratorIntegerDescriptor.INSTANCE, EnumeratorIntegerDescriptor.INSTANCE);
map = new PersistentHashMap<Integer, Integer>(file, EnumeratorIntegerDescriptor.INSTANCE, EnumeratorIntegerDescriptor.INSTANCE) {
@Override
protected boolean wantCompactIntegralValues() {
return true;
}
};
final PersistentHashMap<Integer, Integer> mapFinal = map;
boolean result = checkMap.forEachEntry(new TIntIntProcedure() {
@@ -467,7 +478,12 @@ public class PersistentMapTest extends TestCase {
map.close();
System.out.println("Done:"+(System.currentTimeMillis() - started));
started = System.currentTimeMillis();
map = new PersistentHashMap<Integer, Integer>(file, EnumeratorIntegerDescriptor.INSTANCE, EnumeratorIntegerDescriptor.INSTANCE);
map = new PersistentHashMap<Integer, Integer>(file, EnumeratorIntegerDescriptor.INSTANCE, EnumeratorIntegerDescriptor.INSTANCE) {
@Override
protected boolean wantCompactIntegralValues() {
return true;
}
};
final PersistentHashMap<Integer, Integer> mapFinal2 = map;
result = checkMap.forEachEntry(new TIntIntProcedure() {
@Override
@@ -20,6 +20,7 @@
package com.intellij.openapi.roots.impl;
import com.intellij.ProjectTopics;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionException;
import com.intellij.openapi.extensions.Extensions;
@@ -27,10 +28,14 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbModeTask;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter;
import com.intellij.util.containers.ContainerUtil;
@@ -39,6 +44,8 @@ import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
public class PushedFilePropertiesUpdater {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.PushedFilePropertiesUpdater");
@@ -46,6 +53,7 @@ public class PushedFilePropertiesUpdater {
private final Project myProject;
private final FilePropertyPusher[] myPushers;
private final FilePropertyPusher[] myFilePushers;
private final Queue<DumbModeTask> myTasks = new ConcurrentLinkedQueue<DumbModeTask>();
public static PushedFilePropertiesUpdater getInstance(Project project) {
return project.getComponent(PushedFilePropertiesUpdater.class);
@@ -84,17 +92,19 @@ public class PushedFilePropertiesUpdater {
public void fileCreated(@NotNull final VirtualFileEvent event) {
final VirtualFile file = event.getFile();
final FilePropertyPusher[] pushers = file.isDirectory() ? myPushers : myFilePushers;
pushRecursively(file, project, pushers);
pushRecursively(file, pushers);
}
@Override
public void fileMoved(@NotNull final VirtualFileMoveEvent event) {
final VirtualFile file = event.getFile();
final FilePropertyPusher[] pushers = file.isDirectory() ? myPushers : myFilePushers;
if (pushers.length == 0) return;
for (FilePropertyPusher pusher : pushers) {
file.putUserData(pusher.getFileDataKey(), null);
}
pushRecursively(file, project, pushers);
// push synchronously to avoid entering dumb mode in the middle of a meaningful write action
doPushRecursively(file, pushers, ProjectRootManager.getInstance(myProject).getFileIndex());
}
}));
for (final FilePropertyPusher pusher : myPushers) {
@@ -106,7 +116,7 @@ public class PushedFilePropertiesUpdater {
@Override
public void pushRecursively(VirtualFile file, Project project) {
PushedFilePropertiesUpdater.this.pushRecursively(file, project, pusher);
PushedFilePropertiesUpdater.this.pushRecursively(file, pusher);
}
});
}
@@ -114,9 +124,19 @@ public class PushedFilePropertiesUpdater {
});
}
public void pushRecursively(final VirtualFile dir, final Project project, final FilePropertyPusher... pushers) {
private void pushRecursively(final VirtualFile dir, final FilePropertyPusher... pushers) {
if (pushers.length == 0) return;
ProjectRootManager.getInstance(project).getFileIndex().iterateContentUnderDirectory(dir, new ContentIterator() {
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
queueTask(new DumbModeTask() {
@Override
public void performInDumbMode(@NotNull final ProgressIndicator indicator) {
doPushRecursively(dir, pushers, fileIndex);
}
});
}
private void doPushRecursively(VirtualFile dir, final FilePropertyPusher[] pushers, ProjectFileIndex fileIndex) {
fileIndex.iterateContentUnderDirectory(dir, new ContentIterator() {
@Override
public boolean processFile(final VirtualFile fileOrDir) {
applyPushersToFile(fileOrDir, pushers, null);
@@ -125,6 +145,26 @@ public class PushedFilePropertiesUpdater {
});
}
private void queueTask(DumbModeTask task) {
myTasks.offer(task);
DumbService.getInstance(myProject).queueTask(new DumbModeTask() {
@Override
public void performInDumbMode(@NotNull ProgressIndicator indicator) {
performPushTasks(indicator);
}
});
}
public void performPushTasks(ProgressIndicator indicator) {
while (true) {
DumbModeTask task = myTasks.poll();
if (task == null) {
break;
}
task.performInDumbMode(indicator);
}
}
private static <T> T findPusherValuesUpwards(Project project, VirtualFile dir, FilePropertyPusher<T> pusher, T moduleValue) {
final T value = pusher.getImmediateValue(project, dir);
if (value != null) return value;
@@ -147,44 +187,69 @@ public class PushedFilePropertiesUpdater {
}
public void pushAll(final FilePropertyPusher... pushers) {
ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
if (indicator != null) {
indicator.pushState();
indicator.setText("Initializing file system cache...");
}
Module[] modules = ModuleManager.getInstance(myProject).getModules();
for (int i1 = 0; i1 < modules.length; i1++) {
if (indicator != null) {
indicator.setFraction((double) i1 / modules.length);
queueTask(new DumbModeTask() {
@Override
public void performInDumbMode(@NotNull ProgressIndicator indicator) {
doPushAll(pushers);
}
Module module = modules[i1];
final Object[] moduleValues = new Object[pushers.length];
for (int i = 0; i < moduleValues.length; i++) {
moduleValues[i] = pushers[i].getImmediateValue(module);
}
final ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
final ModuleFileIndex index = rootManager.getFileIndex();
for (VirtualFile root : rootManager.getContentRoots()) {
index.iterateContentUnderDirectory(root, new ContentIterator() {
@Override
public boolean processFile(final VirtualFile fileOrDir) {
applyPushersToFile(fileOrDir, pushers, moduleValues);
return true;
}
});
}
}
if (indicator != null) {
indicator.popState();
}
});
}
private void applyPushersToFile(VirtualFile fileOrDir, FilePropertyPusher[] pushers, Object[] moduleValues) {
private void doPushAll(final FilePropertyPusher[] pushers) {
Module[] modules = ApplicationManager.getApplication().runReadAction(new Computable<Module[]>() {
@Override
public Module[] compute() {
return ModuleManager.getInstance(myProject).getModules();
}
});
for (final Module module : modules) {
Runnable iteration = ApplicationManager.getApplication().runReadAction(new Computable<Runnable>() {
@Override
public Runnable compute() {
if (module.isDisposed()) return EmptyRunnable.INSTANCE;
ProgressManager.checkCanceled();
final Object[] moduleValues = new Object[pushers.length];
for (int i = 0; i < moduleValues.length; i++) {
moduleValues[i] = pushers[i].getImmediateValue(module);
}
final ModuleFileIndex fileIndex = ModuleRootManager.getInstance(module).getFileIndex();
return new Runnable() {
@Override
public void run() {
fileIndex.iterateContent(new ContentIterator() {
@Override
public boolean processFile(final VirtualFile fileOrDir) {
applyPushersToFile(fileOrDir, pushers, moduleValues);
return true;
}
});
}
};
}
});
iteration.run();
}
}
private void applyPushersToFile(final VirtualFile fileOrDir, final FilePropertyPusher[] pushers, final Object[] moduleValues) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
ProgressManager.checkCanceled();
if (!fileOrDir.isValid()) return;
doApplyPushersToFile(fileOrDir, pushers, moduleValues);
}
});
}
private void doApplyPushersToFile(VirtualFile fileOrDir, FilePropertyPusher[] pushers, Object[] moduleValues) {
FilePropertyPusher<Object> pusher = null;
try {
final boolean isDir = fileOrDir.isDirectory();
for (int i = 0, pushersLength = pushers.length; i < pushersLength; i++) {
//noinspection unchecked
pusher = pushers[i];
if (!isDir && (pusher.pushDirectoriesOnly() || !pusher.acceptsFile(fileOrDir))) continue;
else if (isDir && !pusher.acceptsDirectory(fileOrDir, myProject)) continue;
@@ -36,9 +36,10 @@ public class CloudNotifier {
showMessage(message, messageType, null);
}
public void showMessage(String message, MessageType messageType, @Nullable NotificationListener listener) {
public Notification showMessage(String message, MessageType messageType, @Nullable NotificationListener listener) {
NotificationGroup notificationGroup = NotificationGroup.balloonGroup(myNotificationDisplayId);
Notification notification = notificationGroup.createNotification("", message, messageType.toNotificationType(), listener);
notification.notify(null);
return notification;
}
}
@@ -75,6 +75,8 @@ import java.util.regex.Pattern;
*/
@SuppressWarnings("UseOfSystemOutOrSystemErr")
public abstract class UsefulTestCase extends TestCase {
public static final boolean IS_UNDER_TEAMCITY = System.getenv("TEAMCITY_VERSION") != null;
public static final String IDEA_MARKER_CLASS = "com.intellij.openapi.components.impl.stores.IdeaProjectStoreImpl";
public static final String TEMP_DIR_MARKER = "unitTest_";
@@ -643,7 +645,7 @@ public abstract class UsefulTestCase extends TestCase {
String actualText = StringUtil.convertLineSeparators(actual.trim());
Assert.assertEquals(expectedText, actualText);
}
public static void assertExists(File file){
assertTrue("File should exists " + file, file.exists());
}
@@ -0,0 +1,65 @@
/*
* Copyright 2000-2014 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.usages;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Ref;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
public abstract class UsageInfoSearcherAdapter implements UsageSearcher {
protected void processUsages(final @NotNull Processor<Usage> processor, Project project) {
final Ref<UsageInfo[]> refUsages = new Ref<UsageInfo[]>();
final Ref<Boolean> dumbModeOccurred = new Ref<Boolean>();
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
try {
refUsages.set(findUsages());
}
catch (IndexNotReadyException e) {
dumbModeOccurred.set(true);
}
}
});
if (!dumbModeOccurred.isNull()) {
DumbService.getInstance(project).showDumbModeNotification("Usage search is not available until indices are ready");
return;
}
final Usage[] usages = ApplicationManager.getApplication().runReadAction(new Computable<Usage[]>() {
@Override
public Usage[] compute() {
return UsageInfo2UsageAdapter.convert(refUsages.get());
}
});
for (final Usage usage : usages) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
processor.process(usage);
}
});
}
}
protected abstract UsageInfo[] findUsages();
}
@@ -15,13 +15,22 @@
*/
package com.intellij.openapi.util.io;
import com.intellij.openapi.diagnostic.Logger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class JarUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.util.io.JarUtil");
/**
* Returns true if the given .jar file exists and contains the given class.
*/
@@ -56,4 +65,74 @@ public class JarUtil {
return false;
}
/**
* Returns attribute value from a manifest main section,
* or null if missing or a file does not contain a manifest.
*/
@Nullable
public static String getJarAttribute(@NotNull File file, @NotNull Attributes.Name attribute) {
return getJarAttributeImpl(file, null, attribute);
}
/**
* Returns attribute value from a given manifest section,
* or null if missing or a file does not contain a manifest.
*/
@Nullable
public static String getJarAttribute(@NotNull File file, @NotNull String entryName, @NotNull Attributes.Name attribute) {
return getJarAttributeImpl(file, entryName, attribute);
}
private static String getJarAttributeImpl(@NotNull File file, @Nullable String entryName, @NotNull Attributes.Name attribute) {
if (file.canRead()) {
try {
JarFile jarFile = new JarFile(file);
try {
Manifest manifest = jarFile.getManifest();
if (manifest != null) {
Attributes attributes = entryName != null ? manifest.getAttributes(entryName) : manifest.getMainAttributes();
return attributes.getValue(attribute);
}
}
finally {
jarFile.close();
}
}
catch (IOException e) {
LOG.debug(e);
}
}
return null;
}
/**
* Loads archive entry as Java properties.
* Returns loaded instance, or null if requested entry is missed or invalid.
*/
@Nullable
public static Properties loadProperties(@NotNull File file, @NotNull String entryName) {
if (file.canRead()) {
try {
ZipFile zipFile = new ZipFile(file);
try {
ZipEntry entry = zipFile.getEntry(entryName);
if (entry != null) {
Properties properties = new Properties();
properties.load(zipFile.getInputStream(entry));
return properties;
}
}
finally {
zipFile.close();
}
}
catch (IOException e) {
LOG.debug(e);
}
}
return null;
}
}
@@ -1699,6 +1699,13 @@ public class StringUtil extends StringUtilRt {
return -1;
}
@Nullable
public static String substringBefore(@NotNull String text, @NotNull String subString) {
int i = text.indexOf(subString);
if (i == -1) return null;
return text.substring(0, i);
}
@Nullable
public static String substringAfter(@NotNull String text, @NotNull String subString) {
int i = text.indexOf(subString);
@@ -62,6 +62,7 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
private final int myParentValueRefOffset;
@NotNull private final byte[] myRecordBuffer;
@NotNull private final byte[] mySmallRecordBuffer;
private final boolean myIntMapping;
private final boolean myCanReEnumerate;
private int myLargeIndexWatermarkId; // starting with this id we store offset in adjacent file in long format
private boolean myIntAddressForNewRecord;
@@ -112,6 +113,8 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
myAppendCache = createAppendCache(keyDescriptor);
final PersistentEnumeratorBase.RecordBufferHandler<PersistentEnumeratorBase> recordHandler = myEnumerator.getRecordHandler();
myParentValueRefOffset = recordHandler.getRecordBuffer(myEnumerator).length;
myIntMapping = valueExternalizer instanceof IntInlineKeyDescriptor && wantCompactIntegralValues();
myRecordBuffer = new byte[myParentValueRefOffset + 8];
mySmallRecordBuffer = new byte[myParentValueRefOffset + 4];
@@ -180,6 +183,10 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
}
}
protected boolean wantCompactIntegralValues() {
return false;
}
private SLRUCache<Key, BufferExposingByteArrayOutputStream> createAppendCache(final KeyDescriptor<Key> keyDescriptor) {
final EqualityPolicy<Key> hashingStrategy = new EqualityPolicy<Key>() {
@Override
@@ -306,14 +313,18 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
myEnumerator.markDirty(true);
myAppendCache.remove(key);
final int id = enumerate(key);
if (myIntMapping) {
myEnumerator.myStorage.putInt(id + myParentValueRefOffset, (Integer)value);
return;
}
final BufferExposingByteArrayOutputStream bytes = new BufferExposingByteArrayOutputStream();
AppendStream appenderStream = ourFlyweightAppenderStream.getValue();
appenderStream.setOut(bytes);
myValueExternalizer.save(appenderStream, value);
appenderStream.setOut(null);
final int id = enumerate(key);
long oldheader = readValueId(id);
if (oldheader != NULL_ADDR) {
myLiveAndGarbageKeysCounter++;
@@ -357,6 +368,7 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
};
protected void doAppendData(Key key, @NotNull ValueDataAppender appender) throws IOException {
assert !myIntMapping;
myEnumerator.markDirty(true);
AppendStream appenderStream = ourFlyweightAppenderStream.getValue();
@@ -413,11 +425,15 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
if (id == PersistentEnumerator.NULL_ID) {
return null;
}
if (myIntMapping) {
return (Value)(Integer)myEnumerator.myStorage.getInt(id + myParentValueRefOffset);
}
final long oldHeader = readValueId(id);
if (oldHeader == PersistentEnumerator.NULL_ID) {
return null;
}
PersistentHashMapValueStorage.ReadResult readResult = myValueStorage.readBytes(oldHeader);
if (readResult.offset != oldHeader) {
myEnumerator.markDirty(true);
@@ -454,6 +470,7 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
if (id == PersistentEnumerator.NULL_ID) {
return false;
}
if(myIntMapping) return true;
return readValueId(id) != NULL_ADDR;
}
finally {
@@ -475,6 +492,7 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
if (id == PersistentEnumerator.NULL_ID) {
return;
}
assert !myIntMapping; // removal isn't supported
myEnumerator.markDirty(true);
final long record = readValueId(id);
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2014 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.
@@ -30,6 +30,7 @@ import com.siyeh.ig.DelegatingFix;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.MethodUtils;
import com.siyeh.ig.psiutils.ParenthesesUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -79,7 +80,7 @@ public class StringConcatenationInspectionBase extends BaseInspection {
protected InspectionGadgetsFix[] buildFixes(Object... infos) {
final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)infos[0];
final Collection<InspectionGadgetsFix> result = new ArrayList();
final PsiElement parent = polyadicExpression.getParent();
final PsiElement parent = ParenthesesUtils.getParentSkipParentheses(polyadicExpression);
if (parent instanceof PsiVariable) {
final PsiVariable variable = (PsiVariable)parent;
final InspectionGadgetsFix fix = createAddAnnotationFix(variable);
@@ -98,6 +99,22 @@ public class StringConcatenationInspectionBase extends BaseInspection {
}
}
}
else if (parent instanceof PsiExpressionList) {
final PsiElement grandParent = parent.getParent();
if (grandParent instanceof PsiMethodCallExpression) {
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)grandParent;
final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
if (qualifierExpression instanceof PsiReferenceExpression) {
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)qualifierExpression;
final PsiElement target = referenceExpression.resolve();
if (target instanceof PsiModifierListOwner) {
final PsiModifierListOwner modifierListOwner = (PsiModifierListOwner)target;
result.add(createAddAnnotationFix(modifierListOwner));
}
}
}
}
final PsiExpression[] operands = polyadicExpression.getOperands();
for (PsiExpression operand : operands) {
final PsiModifierListOwner element1 = getAnnotatableElement(operand);
@@ -15,6 +15,7 @@
*/
package com.siyeh.ig.junit;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.psi.*;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
@@ -65,7 +66,7 @@ public class TestCaseWithConstructorInspection extends BaseInspection {
return;
}
final PsiClass aClass = method.getContainingClass();
if (!TestUtils.isJUnitTestClass(aClass)) {
if (aClass == null || !TestUtils.isJUnitTestClass(aClass) || AnnotationUtil.isAnnotated(aClass, "org.junit.runner.RunWith", true)) {
return;
}
final PsiCodeBlock body = method.getBody();
@@ -19,16 +19,14 @@ import com.intellij.lang.ant.AntBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.io.JarUtil;
import com.intellij.util.config.*;
import com.intellij.util.containers.Convertor;
import com.intellij.util.lang.UrlClassLoader;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.Comparator;
import java.util.Properties;
@@ -162,28 +160,10 @@ public class AntInstallation {
}
private static Properties loadProperties(File antJar) throws MalformedURLException, ConfigurationException {
Properties properties = new Properties();
InputStream stream = null;
try {
stream = UrlClassLoader.build().urls(antJar.toURI().toURL()).allowUnescaped().noPreload().get().getResourceAsStream(VERSION_RESOURCE);
properties.load(stream);
}
catch (MalformedURLException e) {
throw e;
}
catch (IOException e) {
Properties properties = JarUtil.loadProperties(antJar, VERSION_RESOURCE);
if (properties == null) {
throw new ConfigurationException(AntBundle.message("cant.read.from.ant.jar.error.message", antJar.getAbsolutePath()));
}
finally {
if (stream != null) {
try {
stream.close();
}
catch (IOException e) {
LOG.error(e);
}
}
}
return properties;
}
@@ -204,7 +184,7 @@ public class AntInstallation {
private static void registerProperties(ExternalizablePropertyContainer container) {
container.registerProperty((StringProperty)NAME);
container.registerProperty(HOME_DIR);
container.registerProperty(CLASS_PATH, "classpathItem", SinglePathEntry.EXTERNALIZER);
container.registerProperty(CLASS_PATH, "classpathItem", AntClasspathEntry.EXTERNALIZER);
container.registerProperty((StringProperty)VERSION);
}
}
@@ -53,7 +53,7 @@ public abstract class AbstractFileProcessor {
private final String message;
private final String title;
protected abstract Runnable preprocessFile(PsiFile psifile) throws IncorrectOperationException;
protected abstract Runnable preprocessFile(PsiFile file, boolean allowReplacement) throws IncorrectOperationException;
protected AbstractFileProcessor(Project project, String title, String message) {
myProject = project;
@@ -124,7 +124,7 @@ public abstract class AbstractFileProcessor {
@Override
public void run() {
try {
resultRunnable[0] = preprocessFile(file);
resultRunnable[0] = preprocessFile(file, true);
}
catch (IncorrectOperationException incorrectoperationexception) {
logger.error(incorrectoperationexception);
@@ -168,7 +168,7 @@ public abstract class AbstractFileProcessor {
if (pfile.isWritable()) {
try {
runnables[i] = preprocessFile(pfile);
runnables[i] = preprocessFile(pfile, true);
}
catch (IncorrectOperationException incorrectoperationexception) {
logger.error(incorrectoperationexception);
@@ -18,6 +18,8 @@ package com.maddyhome.idea.copyright.actions;
import com.intellij.analysis.AnalysisScope;
import com.intellij.analysis.BaseAnalysisAction;
import com.intellij.analysis.BaseAnalysisActionDialog;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
@@ -27,19 +29,26 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.ui.TitledSeparator;
import com.intellij.util.SequentialModalProgressTask;
import com.intellij.util.SequentialTask;
import com.maddyhome.idea.copyright.CopyrightManager;
import com.maddyhome.idea.copyright.pattern.FileUtil;
import com.maddyhome.idea.copyright.util.FileTypeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
public class UpdateCopyrightAction extends BaseAnalysisAction {
public static final String UPDATE_EXISTING_COPYRIGHTS = "update.existing.copyrights";
private JCheckBox myUpdateExistingCopyrightsCb;
protected UpdateCopyrightAction() {
super(UpdateCopyrightProcessor.TITLE, UpdateCopyrightProcessor.TITLE);
}
@@ -107,8 +116,20 @@ public class UpdateCopyrightAction extends BaseAnalysisAction {
return true;
}
@Nullable
@Override
protected JComponent getAdditionalActionSettings(Project project, BaseAnalysisActionDialog dialog) {
final JPanel panel = new JPanel(new VerticalFlowLayout());
panel.add(new TitledSeparator());
myUpdateExistingCopyrightsCb = new JCheckBox("Update existing copyrights",
PropertiesComponent.getInstance().getBoolean(UPDATE_EXISTING_COPYRIGHTS, true));
panel.add(myUpdateExistingCopyrightsCb);
return panel;
}
@Override
protected void analyze(@NotNull final Project project, @NotNull final AnalysisScope scope) {
PropertiesComponent.getInstance().setValue(UPDATE_EXISTING_COPYRIGHTS, String.valueOf(myUpdateExistingCopyrightsCb.isSelected()));
if (scope.checkScopeWritable(project)) return;
final List<Runnable> preparations = new ArrayList<Runnable>();
Task.Backgroundable task = new Task.Backgroundable(project, "Prepare Copyright...", true) {
@@ -120,7 +141,7 @@ public class UpdateCopyrightAction extends BaseAnalysisAction {
if (indicator.isCanceled()) {
return;
}
preparations.add(new UpdateCopyrightProcessor(project, ModuleUtilCore.findModuleForPsiElement(file), file).preprocessFile(file));
preparations.add(new UpdateCopyrightProcessor(project, ModuleUtilCore.findModuleForPsiElement(file), file).preprocessFile(file, myUpdateExistingCopyrightsCb.isSelected()));
}
});
}
@@ -31,6 +31,7 @@ import com.maddyhome.idea.copyright.CopyrightManager;
import com.maddyhome.idea.copyright.CopyrightProfile;
import com.maddyhome.idea.copyright.psi.UpdateCopyright;
import com.maddyhome.idea.copyright.psi.UpdateCopyrightFactory;
import com.maddyhome.idea.copyright.psi.UpdatePsiFileCopyright;
import com.maddyhome.idea.copyright.util.FileTypeUtil;
public class UpdateCopyrightProcessor extends AbstractFileProcessor
@@ -62,7 +63,7 @@ public class UpdateCopyrightProcessor extends AbstractFileProcessor
setup(project, module);
}
protected Runnable preprocessFile(final PsiFile file) throws IncorrectOperationException
protected Runnable preprocessFile(final PsiFile file, final boolean allowReplacement) throws IncorrectOperationException
{
VirtualFile vfile = file.getVirtualFile();
if (vfile == null) return EmptyRunnable.getInstance();
@@ -92,8 +93,11 @@ public class UpdateCopyrightProcessor extends AbstractFileProcessor
{
try
{
if (update instanceof UpdatePsiFileCopyright) {
((UpdatePsiFileCopyright)update).complete(allowReplacement);
} else {
update.complete();
}
}
catch (Exception e)
{
@@ -72,13 +72,17 @@ public abstract class UpdatePsiFileCopyright extends AbstractUpdateCopyright {
@Override
public void complete() throws Exception {
complete(true);
}
public void complete(boolean allowReplacement) throws Exception {
if (file == null) {
logger.info("No file for root: " + getRoot());
return;
}
if (accept()) {
processActions();
processActions(allowReplacement);
}
}
@@ -315,7 +319,7 @@ public abstract class UpdatePsiFileCopyright extends AbstractUpdateCopyright {
return element == null ? null : element.getNextSibling();
}
protected void processActions() throws IncorrectOperationException {
protected void processActions(final boolean allowReplacement) throws IncorrectOperationException {
new WriteCommandAction.Simple(file.getProject(), "Update copyright") {
@Override
protected void run() throws Throwable {
@@ -334,10 +338,10 @@ public abstract class UpdatePsiFileCopyright extends AbstractUpdateCopyright {
}
break;
case CommentAction.ACTION_REPLACE:
doc.replaceString(start, end, getCommentText("", ""));
if (allowReplacement) doc.replaceString(start, end, getCommentText("", ""));
break;
case CommentAction.ACTION_DELETE:
doc.deleteString(start, end);
if (allowReplacement) doc.deleteString(start, end);
break;
}
}
@@ -116,7 +116,7 @@ public class CloudGitChooseAccountStep<DC extends CloudDeploymentNameConfigurati
return super.validate();
}
private void createRunConfiguration(Module module, String applicationName) {
public void createRunConfiguration(Module module, String applicationName) {
DC deploymentConfiguration = myDetector.createDeploymentConfiguration();
boolean defaultName = module.getName().equals(applicationName);
@@ -19,9 +19,9 @@ import com.intellij.appengine.sdk.AppEngineSdk;
import com.intellij.appengine.util.AppEngineUtil;
import com.intellij.execution.configurations.ParametersList;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.roots.libraries.JarVersionDetectionUtil;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.JarUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
@@ -140,12 +140,7 @@ public class AppEngineSdkImpl implements AppEngineSdk {
@Override
@Nullable
public String getVersion() {
try {
return JarVersionDetectionUtil.getJarAttributeVersion(getToolsApiJarFile(), Attributes.Name.SPECIFICATION_VERSION, "com/google/appengine/tools/info/");
}
catch (IOException e) {
return null;
}
return JarUtil.getJarAttribute(getToolsApiJarFile(), "com/google/appengine/tools/info/", Attributes.Name.SPECIFICATION_VERSION);
}
private File getCachedWhiteListFile() {
@@ -32,6 +32,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
@@ -53,11 +54,7 @@ public abstract class AbstractModelBuilderTest {
public static final String GRADLE_v1_11 = "1.11";
public static final String GRADLE_v1_12 = "1.12-20140327133732+0000";
public static final Pattern TEST_METHOD_NAME_PATTERN;
static {
TEST_METHOD_NAME_PATTERN = Pattern.compile("(.*)\\[(\\d*)\\]");
}
public static final Pattern TEST_METHOD_NAME_PATTERN = Pattern.compile("(.*)\\[(\\d*)\\]");
private static File ourTempDir;
@@ -74,11 +71,12 @@ public abstract class AbstractModelBuilderTest {
@Parameterized.Parameters
public static Collection<Object[]> data() {
Object[][] data = new Object[][]{
Object[][] data = {
{AbstractModelBuilderTest.GRADLE_v1_9},
{AbstractModelBuilderTest.GRADLE_v1_10},
{AbstractModelBuilderTest.GRADLE_v1_11},
{AbstractModelBuilderTest.GRADLE_v1_12}};
{AbstractModelBuilderTest.GRADLE_v1_12}
};
return Arrays.asList(data);
}
@@ -94,29 +92,23 @@ public abstract class AbstractModelBuilderTest {
}
testDir = new File(ourTempDir, methodName);
testDir.mkdirs();
FileUtil.ensureExists(testDir);
FileUtil.writeToFile(
new File(testDir, GradleConstants.DEFAULT_SCRIPT_NAME),
FileUtil.loadTextAndClose(getClass().getResourceAsStream(
String.format("/%s/%s", methodName, GradleConstants.DEFAULT_SCRIPT_NAME))
)
FileUtil.loadTextAndClose(getClass().getResourceAsStream("/" + methodName + "/" + GradleConstants.DEFAULT_SCRIPT_NAME))
);
FileUtil.writeToFile(
new File(testDir, GradleConstants.SETTINGS_FILE_NAME),
FileUtil.loadTextAndClose(getClass().getResourceAsStream(
String.format("/%s/%s", methodName, GradleConstants.SETTINGS_FILE_NAME))
)
FileUtil.loadTextAndClose(getClass().getResourceAsStream("/" + methodName + "/" + GradleConstants.SETTINGS_FILE_NAME))
);
GradleConnector connector = GradleConnector.newConnector();
DefaultGradleConnector gradleConnector = (DefaultGradleConnector)connector;
gradleConnector.useGradleVersion(gradleVersion);
gradleConnector.forProjectDirectory(testDir);
gradleConnector.daemonMaxIdleTime(1, TimeUnit.SECONDS);
ProjectConnection connection = gradleConnector.connect();
connector.useGradleVersion(gradleVersion);
connector.forProjectDirectory(testDir);
((DefaultGradleConnector)connector).daemonMaxIdleTime(1, TimeUnit.SECONDS);
ProjectConnection connection = connector.connect();
final ProjectImportAction projectImportAction = new ProjectImportAction(false);
projectImportAction.addExtraProjectModelClasses(getModels());
@@ -130,16 +122,18 @@ public abstract class AbstractModelBuilderTest {
@After
public void tearDown() throws Exception {
FileUtil.delete(testDir);
if (testDir != null) {
FileUtil.delete(testDir);
}
}
protected abstract Set<Class> getModels();
private static void ensureTempDirCreated() {
private static void ensureTempDirCreated() throws IOException {
if (ourTempDir != null) return;
ourTempDir = new File(FileUtil.getTempDirectory(), "gradleTests");
FileUtil.delete(ourTempDir);
ourTempDir.mkdirs();
FileUtil.ensureExists(ourTempDir);
}
}
+3
View File
@@ -540,6 +540,9 @@
<projectService serviceInterface="org.jetbrains.plugins.groovy.compiler.GroovyCompilerConfiguration"
serviceImplementation="org.jetbrains.plugins.groovy.compiler.GroovyCompilerConfiguration"/>
<applicationService serviceInterface="org.jetbrains.plugins.groovy.lang.resolve.KnownRecursionManager"
serviceImplementation="org.jetbrains.plugins.groovy.lang.resolve.KnownRecursionManager"/>
<psi.referenceContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.providers.GroovyReferenceContributor"/>
<resolveScopeProvider implementation="org.jetbrains.plugins.groovy.lang.resolve.GroovyResolveScopeProvider"/>
@@ -55,9 +55,7 @@ import org.jetbrains.plugins.groovy.mvc.*;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -238,12 +236,7 @@ public class GriffonFramework extends MvcFramework {
return params;
}
Map<String, String> env = params.getEnv();
if (env == null) {
env = new HashMap<String, String>();
params.setEnv(env);
}
env.put(getSdkHomePropertyName(), FileUtil.toSystemDependentName(sdkRoot.getPath()));
params.addEnv(getSdkHomePropertyName(), FileUtil.toSystemDependentName(sdkRoot.getPath()));
final VirtualFile lib = sdkRoot.findChild("lib");
if (lib != null) {
@@ -16,9 +16,7 @@
package org.jetbrains.plugins.groovy.lang.psi.impl;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiType;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
@@ -26,15 +24,11 @@ import org.jetbrains.annotations.NotNull;
/**
* @author ven
*/
public class GrTupleTypeImpl extends GrTupleType {
public class GrImmediateTupleType extends GrTupleType {
private final PsiType[] myComponentTypes;
public GrTupleTypeImpl(PsiType[] componentTypes, JavaPsiFacade facade, GlobalSearchScope scope) {
this(componentTypes, facade, scope, LanguageLevel.JDK_1_5);
}
public GrTupleTypeImpl(PsiType[] componentTypes, JavaPsiFacade facade, GlobalSearchScope scope, LanguageLevel languageLevel) {
super(scope, facade, languageLevel);
public GrImmediateTupleType(@NotNull PsiType[] componentTypes, @NotNull JavaPsiFacade facade, @NotNull GlobalSearchScope scope) {
super(scope, facade);
myComponentTypes = componentTypes;
}
@@ -46,12 +40,13 @@ public class GrTupleTypeImpl extends GrTupleType {
return true;
}
@Override
@NotNull
public PsiClassType setLanguageLevel(@NotNull final LanguageLevel languageLevel) {
return new GrTupleTypeImpl(myComponentTypes, myFacade, myScope, languageLevel);
@Override
protected PsiType[] inferComponents() {
return myComponentTypes;
}
@NotNull
@Override
public PsiType[] getComponentTypes() {
return myComponentTypes;
@@ -16,8 +16,8 @@
package org.jetbrains.plugins.groovy.lang.psi.impl;
import com.intellij.openapi.util.AtomicNotNullLazyValue;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.VolatileNotNullLazyValue;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.JavaPsiFacade;
@@ -41,7 +41,7 @@ import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.
public abstract class GrMapType extends GrLiteralClassType {
private final String myJavaClassName;
private final AtomicNotNullLazyValue<PsiType[]> myParameters = new AtomicNotNullLazyValue<PsiType[]>() {
private final VolatileNotNullLazyValue<PsiType[]> myParameters = new VolatileNotNullLazyValue<PsiType[]>() {
@NotNull
@Override
protected PsiType[] compute() {
@@ -15,8 +15,8 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.impl;
import com.intellij.openapi.util.AtomicNotNullLazyValue;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.VolatileNotNullLazyValue;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiElement;
@@ -43,7 +43,7 @@ public class GrMapTypeFromNamedArgs extends GrMapType {
private final Map<String, GrExpression> myStringEntries;
private final List<Pair<GrExpression, GrExpression>> myOtherEntries;
private final AtomicNotNullLazyValue<List<Pair<PsiType, PsiType>>> myTypesOfOtherEntries = new AtomicNotNullLazyValue<List<Pair<PsiType, PsiType>>>() {
private final VolatileNotNullLazyValue<List<Pair<PsiType, PsiType>>> myTypesOfOtherEntries = new VolatileNotNullLazyValue<List<Pair<PsiType, PsiType>>>() {
@NotNull
@Override
protected List<Pair<PsiType, PsiType>> compute() {
@@ -56,7 +56,7 @@ public class GrMapTypeFromNamedArgs extends GrMapType {
}
};
private final AtomicNotNullLazyValue<Map<String, PsiType>> myTypesOfStringEntries = new AtomicNotNullLazyValue<Map<String, PsiType>>() {
private final VolatileNotNullLazyValue<Map<String, PsiType>> myTypesOfStringEntries = new VolatileNotNullLazyValue<Map<String,PsiType>>() {
@NotNull
@Override
protected Map<String, PsiType> compute() {
@@ -16,12 +16,13 @@
package org.jetbrains.plugins.groovy.lang.psi.impl;
import com.intellij.openapi.util.AtomicNotNullLazyValue;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.VolatileNotNullLazyValue;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiType;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
@@ -31,7 +32,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt
* @author ven
*/
public abstract class GrTupleType extends GrLiteralClassType {
private final AtomicNotNullLazyValue<PsiType[]> myParameters = new AtomicNotNullLazyValue<PsiType[]>() {
private final VolatileNotNullLazyValue<PsiType[]> myParameters = new VolatileNotNullLazyValue<PsiType[]>() {
@NotNull
@Override
protected PsiType[] compute() {
@@ -43,6 +44,14 @@ public abstract class GrTupleType extends GrLiteralClassType {
}
};
private final VolatileNotNullLazyValue<PsiType[]> myComponents = new VolatileNotNullLazyValue<PsiType[]>() {
@NotNull
@Override
protected PsiType[] compute() {
return inferComponents();
}
};
public GrTupleType(@NotNull GlobalSearchScope scope, @NotNull JavaPsiFacade facade) {
this(scope, facade, LanguageLevel.JDK_1_5);
}
@@ -122,5 +131,17 @@ public abstract class GrTupleType extends GrLiteralClassType {
return super.isAssignableFrom(type);
}
public abstract PsiType[] getComponentTypes();
@NotNull
public PsiType[] getComponentTypes() {
return myComponents.getValue();
}
@NotNull
protected abstract PsiType[] inferComponents();
@NotNull
@Override
public PsiClassType setLanguageLevel(@NotNull LanguageLevel languageLevel) {
return new GrImmediateTupleType(getComponentTypes(), myFacade, getResolveScope());
}
}
@@ -1,55 +0,0 @@
/*
* Copyright 2000-2014 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 org.jetbrains.plugins.groovy.lang.psi.impl;
import com.intellij.openapi.util.AtomicNotNullLazyValue;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiType;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
/**
* Created by Max Medvedev on 06/04/14
*/
public abstract class GrTupleTypeWithLazyComponents extends GrTupleType {
private final AtomicNotNullLazyValue<PsiType[]> myComponents = new AtomicNotNullLazyValue<PsiType[]>() {
@NotNull
@Override
protected PsiType[] compute() {
return inferComponents();
}
};
protected abstract PsiType[] inferComponents();
public GrTupleTypeWithLazyComponents(@NotNull GlobalSearchScope scope, @NotNull JavaPsiFacade facade) {
super(scope, facade);
}
@Override
public PsiType[] getComponentTypes() {
return myComponents.getValue();
}
@NotNull
@Override
public PsiClassType setLanguageLevel(@NotNull LanguageLevel languageLevel) {
return new GrTupleTypeImpl(getComponentTypes(), myFacade, getResolveScope(), languageLevel);
}
}
@@ -209,11 +209,15 @@ public class GroovyPsiManager {
}
}
if (!type.isValid()) {
LOG.error("Type is invalid: " + type + "; element: " + element + " of class " + element.getClass());
error(element, type);
}
return UNKNOWN_TYPE == type ? null : type;
}
private static void error(PsiElement element, PsiType type) {
LOG.error("Type is invalid: " + type + "; element: " + element + " of class " + element.getClass());
}
@Nullable
public GrTypeDefinition getArrayClass(@NotNull PsiType type) {
final String typeText = type.getCanonicalText();
@@ -37,7 +37,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleTypeWithLazyComponents;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrExpressionImpl;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
@@ -211,7 +211,8 @@ public class GrListOrMapImpl extends GrExpressionImpl implements GrListOrMap {
}
}
return new GrTupleTypeWithLazyComponents(scope, facade) {
return new GrTupleType(scope, facade) {
@NotNull
@Override
protected PsiType[] inferComponents() {
return ContainerUtil.map(initializers, new Function<GrExpression, PsiType>() {
@@ -17,6 +17,7 @@
package org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.tree.IElementType;
@@ -49,6 +50,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.params.GrParameterListImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightVariable;
import org.jetbrains.plugins.groovy.lang.resolve.KnownRecursionManager;
import org.jetbrains.plugins.groovy.lang.resolve.MethodTypeInferencer;
import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
@@ -335,7 +337,12 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock
@Nullable
public PsiType getReturnType() {
return TypeInferenceHelper.getCurrentContext().getExpressionType(this, ourTypesCalculator);
return KnownRecursionManager.getInstance().run(this, new Computable<PsiType>() {
@Override
public PsiType compute() {
return TypeInferenceHelper.getCurrentContext().getExpressionType(GrClosableBlockImpl.this, ourTypesCalculator);
}
}, getAllParameters());
}
@Override
@@ -519,7 +519,7 @@ public class TypesUtil {
components3[i] = getLeastUpperBound(c1, c2, manager);
}
}
return new GrTupleTypeImpl(components3, JavaPsiFacade.getInstance(manager.getProject()), tuple1.getScope().intersectWith(tuple2.getResolveScope()));
return new GrImmediateTupleType(components3, JavaPsiFacade.getInstance(manager.getProject()), tuple1.getScope().intersectWith(tuple2.getResolveScope()));
}
else if (checkEmptyListAndList(type1, type2)) {
return genNewListBy(type2, manager);
@@ -841,7 +841,8 @@ public class TypesUtil {
}
public static PsiType getTupleByAnnotationArrayInitializer(final GrAnnotationArrayInitializer value) {
return new GrTupleTypeWithLazyComponents(value.getResolveScope(), JavaPsiFacade.getInstance(value.getProject())) {
return new GrTupleType(value.getResolveScope(), JavaPsiFacade.getInstance(value.getProject())) {
@NotNull
@Override
protected PsiType[] inferComponents() {
final GrAnnotationMemberValue[] initializers = value.getInitializers();
@@ -37,8 +37,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrRefere
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrImmediateTupleType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleTypeImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrExpressionImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
@@ -218,7 +218,7 @@ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProp
}
if (candidates.length != 1) {
final GrTupleType tupleType = new GrTupleTypeImpl(argTypes, JavaPsiFacade.getInstance(getProject()), resolveScope);
final GrTupleType tupleType = new GrImmediateTupleType(argTypes, JavaPsiFacade.getInstance(getProject()), resolveScope);
final GroovyResolveResult[] tupleCandidates = ResolveUtil.getMethodCandidates(thisType, name, invoked, tupleType);
if (incompleteCode) {
candidates = ArrayUtil.mergeArrays(candidates, tupleCandidates, new ArrayFactory<GroovyResolveResult>() {
@@ -17,6 +17,7 @@
package org.jetbrains.plugins.groovy.lang.psi.impl.statements.params;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.search.LocalSearchScope;
@@ -48,6 +49,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt
import org.jetbrains.plugins.groovy.lang.psi.stubs.GrParameterStub;
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureParameterEnhancer;
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrVariableEnhancer;
import org.jetbrains.plugins.groovy.lang.resolve.KnownRecursionManager;
/**
* @author: Dmitry.Krasilschikov
@@ -100,7 +102,12 @@ public class GrParameterImpl extends GrVariableBaseImpl<GrParameterStub> impleme
return TypesUtil.createTypeByFQClassName(CommonClassNames.JAVA_LANG_THROWABLE, this);
}
return GrVariableEnhancer.getEnhancedType(this);
return KnownRecursionManager.getInstance().run(this, new Computable<PsiType>() {
@Override
public PsiType compute() {
return GrVariableEnhancer.getEnhancedType(GrParameterImpl.this);
}
}, getDeclarationScope());
}
@@ -0,0 +1,77 @@
/*
* Copyright 2000-2014 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 org.jetbrains.plugins.groovy.lang.resolve;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.util.Computable;
import com.intellij.util.containers.ContainerUtil;
import java.util.Set;
/**
* Created by Max Medvedev on 10/04/14
*/
public class KnownRecursionManager {
private final ThreadLocal<ThreadInfo> myThreads = new ThreadLocal<ThreadInfo>() {
@Override
protected ThreadInfo initialValue() {
return new ThreadInfo();
}
};
public <T> T run(Object key, Computable<T> computable, Object... stopAt) {
try {
if (!startInference(key, stopAt)) {
return null;
}
return computable.compute();
}
finally {
try {
finishInference(key);
}
catch (Throwable e) {
//noinspection ThrowFromFinallyBlock
throw new RuntimeException("exception in finishInference", e);
}
}
}
private boolean startInference(Object key, Object[] stopAt) {
ThreadInfo info = myThreads.get();
for (Object o : stopAt) {
if (info.myObjects.contains(o)) return false;
}
if (!info.myObjects.add(key)) return false;
return true;
}
private void finishInference(Object key) {
ThreadInfo info = myThreads.get();
info.myObjects.remove(key);
}
public static KnownRecursionManager getInstance() {
return ServiceManager.getService(KnownRecursionManager.class);
}
private static class ThreadInfo {
private final Set<Object> myObjects = ContainerUtil.newLinkedHashSet();
}
}
@@ -425,13 +425,7 @@ public abstract class MvcFramework {
if (sdk != null && sdk.getSdkType() instanceof JavaSdkType) {
String path = StringUtil.trimEnd(sdk.getHomePath(), File.separator);
if (StringUtil.isNotEmpty(path)) {
Map<String, String> env = params.getEnv();
if (env == null) {
env = new HashMap<String, String>();
params.setEnv(env);
}
env.put("JAVA_HOME", FileUtil.toSystemDependentName(path));
params.addEnv("JAVA_HOME", FileUtil.toSystemDependentName(path));
}
}
}
@@ -254,12 +254,8 @@ public abstract class MvcRunConfiguration extends ModuleBasedConfiguration<RunCo
protected void addEnvVars(final JavaParameters params) {
Map<String, String> envVars = new HashMap<String, String>(envs);
Map<String, String> oldEnv = params.getEnv();
if (oldEnv != null) {
envVars.putAll(oldEnv);
}
envVars.putAll(params.getEnv());
params.setupEnvs(envVars, passParentEnv);
MvcFramework.addJavaHome(params, myModule);
@@ -52,6 +52,7 @@
<completion.contributor implementationClass="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxCompletionContributor" language="XML" order="before xmlNonFirst"/>
<manifest.parser.provider implementation="org.jetbrains.plugins.javaFX.manifest.JavaFxManifestHeaderParsers"/>
<projectTemplate projectType="Java FX" templatePath="resources/projectTemplates/Java/JavaFX Application.zip" category="true"/>
<javaMainMethodProvider implementation="org.jetbrains.plugins.javaFX.JavaFXApplicationMainMethodProvider"/>
</extensions>
<actions>
@@ -0,0 +1,34 @@
package org.jetbrains.plugins.javaFX;
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiMethodUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames;
public class JavaFXApplicationMainMethodProvider implements JavaMainMethodProvider {
@NonNls public static final String LAUNCH_MAIN = "launch";
@Override
public boolean isApplicable(PsiClass clazz) {
return InheritanceUtil.isInheritor(clazz, true, JavaFxCommonClassNames.JAVAFX_APPLICATION_APPLICATION);
}
@Override
public boolean hasMainMethod(PsiClass clazz) {
return InheritanceUtil.isInheritor(clazz, true, JavaFxCommonClassNames.JAVAFX_APPLICATION_APPLICATION);
}
@Override
public PsiMethod findMainInClass(PsiClass clazz) {
final PsiMethod[] launches = clazz.findMethodsByName(LAUNCH_MAIN, true);
for (PsiMethod launchMethod : launches) {
if (PsiMethodUtil.isMainMethod(launchMethod)) {
return launchMethod;
}
}
return null;
}
}
@@ -21,6 +21,7 @@ import com.intellij.execution.ExecutionException;
import com.intellij.execution.JavaExecutionUtil;
import com.intellij.execution.Location;
import com.intellij.execution.configurations.RunConfigurationModule;
import com.intellij.execution.junit2.PsiMemberParameterizedLocation;
import com.intellij.execution.junit2.TestProxy;
import com.intellij.execution.junit2.info.MethodLocation;
import com.intellij.execution.junit2.info.TestInfo;
@@ -72,6 +73,13 @@ public class TestMethods extends TestMethod {
final GlobalSearchScope searchScope = myConfiguration.getConfigurationModule().getSearchScope();
for (AbstractTestProxy failedTest : myFailedTests) {
Location location = failedTest.getLocation(project, searchScope);
if (location instanceof PsiMemberParameterizedLocation) {
final PsiElement element = location.getPsiElement();
if (element instanceof PsiMethod) {
location = MethodLocation.elementInClass(((PsiMethod)element),
((PsiMemberParameterizedLocation)location).getContainingClass());
}
}
if (!(location instanceof MethodLocation)) continue;
PsiElement psiElement = location.getPsiElement();
LOG.assertTrue(psiElement instanceof PsiMethod);
@@ -85,7 +85,7 @@ public class MavenJUnitPatcher extends JUnitPatcher {
for (Element element : environmentVariables.getChildren()) {
String variableName = element.getName();
if (javaParameters.getEnv() == null || !javaParameters.getEnv().containsKey(variableName)) {
if (!javaParameters.getEnv().containsKey(variableName)) {
String value = resolveSurefireProperties(element.getValue());
if (isResolved(value)) {
javaParameters.addEnv(variableName, value);
@@ -24,10 +24,12 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.roots.libraries.JarVersionDetectionUtil;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.util.io.JarUtil;
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.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
@@ -48,47 +50,31 @@ import org.testng.TestNG;
import org.testng.annotations.*;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.jar.Attributes;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Hani Suleiman Date: Jul 20, 2005 Time: 1:37:36 PM
* @author Hani Suleiman
* @since Jul 20, 2005
*/
public class TestNGUtil
{
public class TestNGUtil {
private static final Logger LOGGER = Logger.getInstance("TestNG Runner");
public static final String TESTNG_GROUP_NAME = "TestNG";
public static boolean hasDocTagsSupport = hasDocTagsSupport();
private static boolean hasDocTagsSupport() {
final String testngJarPath = PathUtil.getJarPathForClass(Test.class);
if (testngJarPath != null) {
final VirtualFile testngjar = LocalFileSystem.getInstance().findFileByPath(testngJarPath);
if (testngjar != null ) {
try {
final VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(testngjar);
if (jarRoot != null) {
final JarFile zipFile = JarFileSystem.getInstance().getJarFile(jarRoot);
final String version = JarVersionDetectionUtil.detectJarVersion(zipFile);
if (version != null && version.compareTo("5.12") > 0) {
return false;
}
}
}
catch (IOException e) {
return true;
}
}
}
return true;
String testngJarPath = PathUtil.getJarPathForClass(Test.class);
String version = JarUtil.getJarAttribute(new File(testngJarPath), Attributes.Name.IMPLEMENTATION_VERSION);
return version == null || StringUtil.compareVersionNumbers(version, "5.12") <= 0;
}
public static final String TEST_ANNOTATION_FQN = Test.class.getName();
public static final String FACTORY_ANNOTATION_FQN = Factory.class.getName();
public static final String[] CONFIG_ANNOTATIONS_FQN = {
@SuppressWarnings("deprecation") public static final String[] CONFIG_ANNOTATIONS_FQN = {
Configuration.class.getName(),
Factory.class.getName(),
ObjectFactory.class.getName(),
@@ -119,9 +105,10 @@ public class TestNGUtil
"testng.after-suite",
"testng.after-test"
};
static final List<String> junitAnnotions =
private static final List<String> JUNIT_ANNOTATIONS =
Arrays.asList("org.junit.Test", "org.junit.Before", "org.junit.BeforeClass", "org.junit.After", "org.junit.AfterClass");
private static final Logger LOG = Logger.getInstance("#" + TestNGUtil.class.getName());
@NonNls
private static final String SUITE_TAG_NAME = "suite";
@@ -501,7 +488,7 @@ public class TestNGUtil
}
public static boolean containsJunitAnnotions(PsiMethod method) {
return method != null && AnnotationUtil.isAnnotated(method, junitAnnotions);
return method != null && AnnotationUtil.isAnnotated(method, JUNIT_ANNOTATIONS);
}
public static boolean inheritsJUnitTestCase(PsiClass psiClass) {