import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.PomNamedTarget;
+import com.intellij.pom.java.LanguageLevel;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
public class PostHighlightingPass extends ProgressableTextEditorHighlightingPass {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.PostHighlightingPass");
private static final Key<Long> LAST_POST_PASS_TIMESTAMP = Key.create("LAST_POST_PASS_TIMESTAMP");
+ private final LanguageLevel myLanguageLevel;
private RefCountHolder myRefCountHolder;
private final PsiFile myFile;
@Nullable private final Editor myEditor;
myEndOffset = file.getTextLength();
myCurrentEntryIndex = -1;
+ myLanguageLevel = PsiUtil.getLanguageLevel(file);
}
static boolean isUpToDate(@NotNull PsiFile file) {
//parameter is defined by functional interface
final PsiElement declarationScope = parameter.getDeclarationScope();
if (declarationScope instanceof PsiMethod &&
- myRefCountHolder.isReferencedByMethodReference((PsiMethod)declarationScope)) {
+ myRefCountHolder.isReferencedByMethodReference((PsiMethod)declarationScope, myLanguageLevel)) {
return null;
}
String message = JavaErrorMessages.message("parameter.is.not.used", identifier.getText());
/*
- * 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.
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.UserDataHolderEx;
+import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiMatcherImpl;
import com.intellij.psi.util.PsiMatchers;
return usedStatus == Boolean.TRUE;
}
- public boolean isReferencedByMethodReference(@NotNull PsiMethod method) {
- if (!PsiUtil.isLanguageLevel8OrHigher(method)) return false;
+ public boolean isReferencedByMethodReference(@NotNull PsiMethod method, @NotNull LanguageLevel languageLevel) {
+ if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) return false;
List<PsiReference> array;
synchronized (myLocalRefsMap) {
return true;
}
- public boolean isReferencedForRead(@NotNull PsiElement element) {
- LOG.assertTrue(element instanceof PsiVariable);
+ public boolean isReferencedForRead(@NotNull PsiVariable variable) {
List<PsiReference> array;
synchronized (myLocalRefsMap) {
- array = myLocalRefsMap.getKeysByValue(element);
+ array = myLocalRefsMap.getKeysByValue(variable);
}
if (array == null) return false;
for (PsiReference ref : array) {
return false;
}
- public boolean isReferencedForWrite(@NotNull PsiElement element) {
- LOG.assertTrue(element instanceof PsiVariable);
+ public boolean isReferencedForWrite(@NotNull PsiVariable variable) {
List<PsiReference> array;
synchronized (myLocalRefsMap) {
- array = myLocalRefsMap.getKeysByValue(element);
+ array = myLocalRefsMap.getKeysByValue(variable);
}
if (array == null) return false;
for (PsiReference ref : array) {
return null;
}
- static HighlightInfo checkDuplicateAnnotations(@NotNull PsiAnnotation annotationToCheck) {
+ static HighlightInfo checkDuplicateAnnotations(@NotNull PsiAnnotation annotationToCheck, @NotNull LanguageLevel languageLevel) {
PsiAnnotationOwner owner = annotationToCheck.getOwner();
if (owner == null) return null;
}
}
else if (isAnnotationRepeatedTwice(owner, annotationType.getQualifiedName())) {
- if (!PsiUtil.isLanguageLevel8OrHigher(annotationToCheck)) {
+ if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
String description = JavaErrorMessages.message("annotation.duplicate.annotation");
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(element).descriptionAndTooltip(description).create();
}
if (targetParametersNum == 0) {
if (PsiTreeUtil.getParentOfType(referenceParameterList, PsiCall.class) != null &&
typeParameterListOwner instanceof PsiMethod &&
- javaSdkVersion.isAtLeast(JavaSdkVersion.JDK_1_7)) {
+ (javaSdkVersion.isAtLeast(JavaSdkVersion.JDK_1_7) || hasSuperMethodsWithTypeParams((PsiMethod)typeParameterListOwner))) {
description = null;
}
else {
return null;
}
+ private static boolean hasSuperMethodsWithTypeParams(PsiMethod method) {
+ for (PsiMethod superMethod : method.findDeepestSuperMethods()) {
+ if (superMethod.hasTypeParameters()) return true;
+ }
+ return false;
+ }
+
private static PsiType detectExpectedType(PsiReferenceParameterList referenceParameterList) {
final PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(referenceParameterList, PsiNewExpression.class);
LOG.assertTrue(newExpression != null);
if (methodCandidate2 != null) {
return null;
}
+ if (element != null && !resolveResult.isAccessible()) {
+ description = HighlightUtil.buildProblemWithAccessDescription(referenceToMethod, resolveResult);
+ elementToHighlight = referenceToMethod.getReferenceNameElement();
+ }
+ else if (element != null && !resolveResult.isStaticsScopeCorrect()) {
+ description = HighlightUtil.buildProblemWithStaticDescription(element);
+ elementToHighlight = referenceToMethod.getReferenceNameElement();
+ }
else {
- if (element != null && !resolveResult.isAccessible()) {
- description = HighlightUtil.buildProblemWithAccessDescription(referenceToMethod, resolveResult);
- elementToHighlight = referenceToMethod.getReferenceNameElement();
- }
- else if (element != null && !resolveResult.isStaticsScopeCorrect()) {
- description = HighlightUtil.buildProblemWithStaticDescription(element);
+ String methodName = referenceToMethod.getReferenceName() + buildArgTypesList(list);
+ description = JavaErrorMessages.message("cannot.resolve.method", methodName);
+ if (candidates.length == 0) {
elementToHighlight = referenceToMethod.getReferenceNameElement();
+ highlightInfoType = HighlightInfoType.WRONG_REF;
}
else {
- String methodName = referenceToMethod.getReferenceName() + buildArgTypesList(list);
- description = JavaErrorMessages.message("cannot.resolve.method", methodName);
- if (candidates.length == 0) {
- elementToHighlight = referenceToMethod.getReferenceNameElement();
- highlightInfoType = HighlightInfoType.WRONG_REF;
- }
- else {
- return null;
- }
+ return null;
}
- toolTip = XmlStringUtil.escapeString(description);
}
+ toolTip = XmlStringUtil.escapeString(description);
HighlightInfo info =
HighlightInfo.newHighlightInfo(highlightInfoType).range(elementToHighlight).description(description).escapedToolTip(toolTip).create();
- if (methodCandidate2 == null) {
- registerMethodCallIntentions(info, methodCall, list, resolveHelper);
- }
- if (!resolveResult.isAccessible() && resolveResult.isStaticsScopeCorrect() && methodCandidate2 != null) {
- HighlightUtil.registerAccessQuickFixAction((PsiMember)element, referenceToMethod, info, resolveResult.getCurrentFileResolveScope());
- }
+ registerMethodCallIntentions(info, methodCall, list, resolveHelper);
if (element != null && !resolveResult.isStaticsScopeCorrect()) {
HighlightUtil.registerStaticProblemQuickFixAction(element, info, referenceToMethod);
}
}
@Nullable
- static HighlightInfo checkMethodCanHaveBody(PsiMethod method, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
+ static HighlightInfo checkMethodCanHaveBody(@NotNull PsiMethod method, @NotNull LanguageLevel languageLevel) {
PsiClass aClass = method.getContainingClass();
boolean hasNoBody = method.getBody() == null;
boolean isInterface = aClass != null && aClass.isInterface();
else if (isInterface) {
if (!isExtension && !isStatic) {
description = JavaErrorMessages.message("interface.methods.cannot.have.body");
- if (PsiUtil.isLanguageLevel8OrHigher(method)) {
+ if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
additionalFixes.add(QUICK_FIX_FACTORY.createModifierListFix(method, PsiModifier.DEFAULT, true, false));
additionalFixes.add(QUICK_FIX_FACTORY.createModifierListFix(method, PsiModifier.STATIC, true, false));
}
}
return createIncompatibleReturnTypeMessage(currentMethod, otherSuperMethod, otherSuperReturnType,
currentType, JavaErrorMessages.message("unrelated.overriding.methods.return.types"),
- false ? currentMethod.getReturnTypeElement().getTextRange() : TextRange.EMPTY_RANGE);
+ TextRange.EMPTY_RANGE);
}
return null;
}
if (aClass.equals(containingClass)) continue; //to be checked at method level
if (aClass.isInterface() && !containingClass.isInterface()) continue;
- HighlightInfo highlightInfo = null;
+ HighlightInfo highlightInfo;
if (allAbstracts) {
superSignatures = new ArrayList<HierarchicalMethodSignature>(superSignatures);
superSignatures.add(signature);
@Nullable
- static HighlightInfo checkIntersectionInTypeCast(@NotNull PsiTypeCastExpression expression) {
+ static HighlightInfo checkIntersectionInTypeCast(@NotNull PsiTypeCastExpression expression, @NotNull LanguageLevel languageLevel) {
final PsiTypeElement castTypeElement = expression.getCastType();
if (castTypeElement == null) return null;
PsiType castType = castTypeElement.getType();
if (isIntersection(castTypeElement, castType)) {
- if (PsiUtil.isLanguageLevel8OrHigher(expression)) {
+ if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
final PsiTypeElement[] conjuncts = PsiTreeUtil.getChildrenOfType(castTypeElement, PsiTypeElement.class);
if (conjuncts != null) {
final List<PsiTypeElement> conjList = new ArrayList<PsiTypeElement>(Arrays.asList(conjuncts));
}
@Nullable
- public static HighlightInfo checkUnderscore(@NotNull PsiIdentifier identifier, @NotNull PsiVariable variable) {
- if ("_".equals(variable.getName()) && PsiUtil.isLanguageLevel8OrHigher(variable)) {
+ public static HighlightInfo checkUnderscore(@NotNull PsiIdentifier identifier, @NotNull PsiVariable variable, @NotNull LanguageLevel languageLevel) {
+ if ("_".equals(variable.getName()) && languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
if (variable instanceof PsiParameter && ((PsiParameter)variable).getDeclarationScope() instanceof PsiLambdaExpression) {
String message = JavaErrorMessages.message("underscore.lambda.identifier");
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(identifier).descriptionAndTooltip(message).create();
@Nullable
static HighlightInfo checkThisOrSuperExpressionInIllegalContext(@NotNull PsiExpression expr,
- @Nullable PsiJavaCodeReferenceElement qualifier) {
+ @Nullable PsiJavaCodeReferenceElement qualifier,
+ @NotNull LanguageLevel languageLevel) {
if (expr instanceof PsiSuperExpression) {
final PsiElement parent = expr.getParent();
if (!(parent instanceof PsiReferenceExpression)) {
if (aClass == null) return null;
if (!InheritanceUtil.hasEnclosingInstanceInScope(aClass, expr, false, false) &&
- !resolvesToImmediateSuperInterface(expr, qualifier, aClass)) {
+ !resolvesToImmediateSuperInterface(expr, qualifier, aClass, languageLevel)) {
return HighlightClassUtil.reportIllegalEnclosingUsage(expr, null, aClass, expr);
}
private static boolean resolvesToImmediateSuperInterface(@NotNull PsiExpression expr,
@Nullable PsiJavaCodeReferenceElement qualifier,
- @NotNull PsiClass aClass) {
- if (!(expr instanceof PsiSuperExpression) || qualifier == null || !PsiUtil.isLanguageLevel8OrHigher(expr)) return false;
+ @NotNull PsiClass aClass,
+ @NotNull LanguageLevel languageLevel) {
+ if (!(expr instanceof PsiSuperExpression) || qualifier == null || !languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) return false;
final PsiType superType = expr.getType();
if (!(superType instanceof PsiClassType)) return false;
final PsiClass superClass = ((PsiClassType)superType).resolve();
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkAnnotationType(annotation));
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkMissingAttributes(annotation));
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkTargetAnnotationDuplicates(annotation));
- if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkDuplicateAnnotations(annotation));
+ if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkDuplicateAnnotations(annotation, myLanguageLevel));
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkForeignInnerClassesUsed(annotation));
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkFunctionalInterface(annotation, myLanguageLevel));
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkRepeatableAnnotation(annotation));
}
}
- myHolder.add(HighlightUtil.checkUnderscore(identifier, variable));
+ myHolder.add(HighlightUtil.checkUnderscore(identifier, variable, myLanguageLevel));
}
else if (parent instanceof PsiClass) {
PsiClass aClass = (PsiClass)parent;
PsiElement parent = list.getParent();
if (parent instanceof PsiMethod) {
PsiMethod method = (PsiMethod)parent;
- if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodCanHaveBody(method, myLanguageLevel,myFile));
+ if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodCanHaveBody(method, myLanguageLevel));
MethodSignatureBackedByPsiMethod methodSignature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY);
if (!method.isConstructor()) {
try {
@Override
public void visitSuperExpression(PsiSuperExpression expr) {
- myHolder.add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier()));
+ myHolder.add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier(), myLanguageLevel));
if (!myHolder.hasErrorResults()) visitExpression(expr);
}
@Override
public void visitThisExpression(PsiThisExpression expr) {
- myHolder.add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier()));
+ myHolder.add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier(), myLanguageLevel));
if (!myHolder.hasErrorResults()) {
myHolder.add(HighlightUtil.checkMemberReferencedBeforeConstructorCalled(expr, null, myFile));
}
public void visitTypeCastExpression(PsiTypeCastExpression typeCast) {
super.visitTypeCastExpression(typeCast);
try {
- if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIntersectionInTypeCast(typeCast));
+ if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIntersectionInTypeCast(typeCast, myLanguageLevel));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkInconvertibleTypeCast(typeCast));
}
catch (IndexNotReadyException ignore) {
@Override
public void visitConditionalExpression(PsiConditionalExpression expression) {
super.visitConditionalExpression(expression);
- if (PsiUtil.isLanguageLevel8OrHigher(expression) && PsiPolyExpressionUtil.isPolyExpression(expression)) {
+ if (myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) && PsiPolyExpressionUtil.isPolyExpression(expression)) {
final PsiExpression thenExpression = expression.getThenExpression();
final PsiExpression elseExpression = expression.getElseExpression();
if (thenExpression != null && elseExpression != null) {
/*
- * Copyright 2000-2011 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.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
-import com.intellij.codeInsight.intention.IntentionAction;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.util.RefactoringChangeUtil;
-import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
for (CandidateInfo candidate : candidates) {
PsiMethod method = (PsiMethod)candidate.getElement();
PsiSubstitutor substitutor = candidate.getSubstitutor();
- assert method != null;
PsiParameter[] parameters = method.getParameterList().getParameters();
if (expressions.length != parameters.length) {
continue;
PsiType paramType = parameters[0].getType();
if (InheritanceUtil.isInheritor(paramType, CommonClassNames.JAVA_UTIL_COLLECTION)) {
PsiType qualifierType = qualifier.getType();
- if (qualifierType != null && !qualifierType.isAssignableFrom(argType)) {
+ if (qualifierType != null) {
final PsiType itemType = JavaGenericsUtil.getCollectionItemType(argType, calleeMethod.getResolveScope());
- return InspectionsBundle.message("inspection.suspicious.collections.method.calls.problem.descriptor",
- PsiFormatUtil.formatType(qualifierType, 0, PsiSubstitutor.EMPTY),
- PsiFormatUtil.formatType(itemType, 0, PsiSubstitutor.EMPTY));
+ final PsiType qualifierItemType = JavaGenericsUtil.getCollectionItemType(qualifierType, calleeMethod.getResolveScope());
+ if (qualifierItemType != null && itemType != null && !qualifierItemType.isAssignableFrom(itemType)) {
+ return InspectionsBundle.message("inspection.suspicious.collections.method.calls.problem.descriptor",
+ PsiFormatUtil.formatType(qualifierType, 0, PsiSubstitutor.EMPTY),
+ PsiFormatUtil.formatType(itemType, 0, PsiSubstitutor.EMPTY));
+ }
}
return null;
}
}
}
}
+ getRefManager().fireNodeMarkedReferenced(psiWhat, psiFrom, false);
}
}
import com.intellij.analysis.AnalysisScope;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInspection.*;
-import com.intellij.codeInspection.ex.JobDescriptor;
-import com.intellij.codeInspection.reference.RefManager;
-import com.intellij.codeInspection.reference.RefModule;
+import com.intellij.codeInspection.reference.*;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.progress.util.AbstractProgressIndicatorBase;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
+import com.intellij.openapi.roots.impl.DirectoryIndex;
+import com.intellij.openapi.roots.impl.DirectoryInfo;
import com.intellij.openapi.roots.libraries.Library;
-import com.intellij.openapi.roots.libraries.LibraryUtil;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.packageDependencies.BackwardDependenciesBuilder;
-import com.intellij.psi.PsiCompiledElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiRecursiveElementVisitor;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.GlobalSearchScopesCore;
-import com.intellij.psi.search.scope.packageSet.NamedScope;
-import com.intellij.psi.search.scope.packageSet.PackageSetFactory;
-import com.intellij.psi.search.scope.packageSet.ParsingException;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.Function;
-import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.*;
public class UnusedLibrariesInspection extends GlobalInspectionTool {
- private static final Logger LOG = Logger.getInstance("#" + UnusedLibrariesInspection.class.getName());
- private final JobDescriptor BACKWARD_ANALYSIS = new JobDescriptor(InspectionsBundle.message("unused.library.backward.analysis.job.description"));
+
+ @Override
+ public boolean isGraphNeeded() {
+ return true;
+ }
@Nullable
@Override
- public JobDescriptor[] getAdditionalJobs() {
- return new JobDescriptor[]{BACKWARD_ANALYSIS};
+ public RefGraphAnnotator getAnnotator(@NotNull RefManager refManager) {
+ return new UnusedLibraryGraphAnnotator(refManager);
}
+ @Nullable
@Override
- public void runInspection(@NotNull AnalysisScope scope,
- @NotNull InspectionManager manager,
- @NotNull final GlobalInspectionContext globalContext,
- @NotNull ProblemDescriptionsProcessor problemProcessor) {
- final Project project = manager.getProject();
- final ArrayList<VirtualFile> libraryRoots = new ArrayList<VirtualFile>();
- if (scope.getScopeType() == AnalysisScope.PROJECT) {
- ContainerUtil.addAll(libraryRoots, LibraryUtil.getLibraryRoots(project, false, false));
- }
- else {
- final Set<Module> modules = new HashSet<Module>();
- scope.accept(new PsiRecursiveElementVisitor() {
- @Override
- public void visitFile(PsiFile file) {
- if (!(file instanceof PsiCompiledElement)) {
- final VirtualFile virtualFile = file.getVirtualFile();
- if (virtualFile != null) {
- final Module module = ModuleUtilCore.findModuleForFile(virtualFile, project);
- if (module != null) {
- modules.add(module);
- }
+ public CommonProblemDescriptor[] checkElement(@NotNull RefEntity refEntity,
+ @NotNull AnalysisScope scope,
+ @NotNull InspectionManager manager,
+ @NotNull GlobalInspectionContext globalContext,
+ @NotNull ProblemDescriptionsProcessor processor) {
+ if (refEntity instanceof RefModule) {
+ final RefModule refModule = (RefModule)refEntity;
+ final Module module = refModule.getModule();
+ if (module.isDisposed()) return CommonProblemDescriptor.EMPTY_ARRAY;
+ final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
+ final Set<VirtualFile> usedRoots = refModule.getUserData(UnusedLibraryGraphAnnotator.USED_LIBRARY_ROOTS);
+
+ final List<CommonProblemDescriptor> result = new ArrayList<CommonProblemDescriptor>();
+ for (OrderEntry entry : moduleRootManager.getOrderEntries()) {
+ if (entry instanceof LibraryOrderEntry && !((LibraryOrderEntry)entry).isExported()) {
+ if (usedRoots == null) {
+ String message = InspectionsBundle.message("unused.library.problem.descriptor", entry.getPresentableName());
+ result.add(manager.createProblemDescriptor(message, new RemoveUnusedLibrary(refModule, entry, null)));
+ } else {
+ final Set<VirtualFile> files = new HashSet<VirtualFile>(Arrays.asList(((LibraryOrderEntry)entry).getRootFiles(OrderRootType.CLASSES)));
+ files.removeAll(usedRoots);
+ if (!files.isEmpty()) {
+ final String unusedLibraryRoots = StringUtil.join(files, new Function<VirtualFile, String>() {
+ @Override
+ public String fun(final VirtualFile file) {
+ return file.getPresentableName();
+ }
+ }, ",");
+ String message =
+ InspectionsBundle.message("unused.library.roots.problem.descriptor", unusedLibraryRoots, entry.getPresentableName());
+ processor.addProblemElement(refModule,
+ manager.createProblemDescriptor(message, new RemoveUnusedLibrary(refModule, entry, files)));
}
}
}
- });
- ContainerUtil.addAll(libraryRoots, LibraryUtil.getLibraryRoots(modules.toArray(new Module[modules.size()]), false, false));
- }
- if (libraryRoots.isEmpty()) {
- return;
- }
-
- GlobalSearchScope searchScope;
- try {
- @NonNls final String libsName = "libs";
- NamedScope libScope = new NamedScope(libsName, PackageSetFactory.getInstance().compile("lib:*..*"));
- searchScope = GlobalSearchScopesCore.filterScope(project, libScope);
- }
- catch (ParsingException e) {
- //can't be
- LOG.error(e);
- return;
- }
- final AnalysisScope analysisScope = new AnalysisScope(searchScope, project);
- analysisScope.setSearchInLibraries(true);
- final BackwardDependenciesBuilder builder = new BackwardDependenciesBuilder(project, analysisScope);
-
- final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
-
- BACKWARD_ANALYSIS.setTotalAmount(builder.getTotalFileCount());
- ProgressIndicator progress = new AbstractProgressIndicatorBase() {
- @Override
- public void setFraction(final double fraction) {
- super.setFraction(fraction);
- int nextAmount = (int)(fraction * BACKWARD_ANALYSIS.getTotalAmount());
- if (nextAmount > BACKWARD_ANALYSIS.getDoneAmount() && nextAmount < BACKWARD_ANALYSIS.getTotalAmount()) {
- BACKWARD_ANALYSIS.setDoneAmount(nextAmount);
- globalContext.incrementJobDoneAmount(BACKWARD_ANALYSIS, getText2());
- }
}
- @Override
- public boolean isCanceled() {
- return progressIndicator != null && progressIndicator.isCanceled() || super.isCanceled();
- }
- };
- ProgressManager.getInstance().executeProcessUnderProgress(new Runnable() {
- @Override
- public void run() {
- builder.analyze();
- }
- }, progress);
- BACKWARD_ANALYSIS.setDoneAmount(BACKWARD_ANALYSIS.getTotalAmount());
- final Map<PsiFile, Set<PsiFile>> dependencies = builder.getDependencies();
- for (PsiFile file : dependencies.keySet()) {
- final VirtualFile virtualFile = file.getVirtualFile();
- LOG.assertTrue(virtualFile != null);
- for (Iterator<VirtualFile> i = libraryRoots.iterator(); i.hasNext();) {
- if (VfsUtilCore.isAncestor(i.next(), virtualFile, false)) {
- i.remove();
- }
- }
- }
- if (libraryRoots.isEmpty()) {
- return;
- }
- ProjectFileIndex projectIndex = ProjectRootManager.getInstance(project).getFileIndex();
- Map<OrderEntry, Set<VirtualFile>> unusedLibs = new HashMap<OrderEntry, Set<VirtualFile>>();
- for (VirtualFile libraryRoot : libraryRoots) {
- final List<OrderEntry> orderEntries = projectIndex.getOrderEntriesForFile(libraryRoot);
- for (OrderEntry orderEntry : orderEntries) {
- Set<VirtualFile> files = unusedLibs.get(orderEntry);
- if (files == null) {
- files = new HashSet<VirtualFile>();
- unusedLibs.put(orderEntry, files);
- }
- files.add(libraryRoot);
- }
- }
- final RefManager refManager = globalContext.getRefManager();
- for (OrderEntry orderEntry : unusedLibs.keySet()) {
- if (!(orderEntry instanceof LibraryOrderEntry)) continue;
- final RefModule refModule = refManager.getRefModule(orderEntry.getOwnerModule());
- final Set<VirtualFile> files = unusedLibs.get(orderEntry);
- final VirtualFile[] roots = ((LibraryOrderEntry)orderEntry).getRootFiles(OrderRootType.CLASSES);
- if (files.size() < roots.length) {
- final String unusedLibraryRoots = StringUtil.join(files, new Function<VirtualFile, String>() {
- @Override
- public String fun(final VirtualFile file) {
- return file.getPresentableName();
- }
- }, ",");
- String message =
- InspectionsBundle.message("unused.library.roots.problem.descriptor", unusedLibraryRoots, orderEntry.getPresentableName());
- problemProcessor.addProblemElement(refModule,
- manager.createProblemDescriptor(message, new RemoveUnusedLibrary(refModule, orderEntry, files)));
- }
- else {
- String message = InspectionsBundle.message("unused.library.problem.descriptor", orderEntry.getPresentableName());
- problemProcessor.addProblemElement(refModule,
- manager.createProblemDescriptor(message, new RemoveUnusedLibrary(refModule, orderEntry, null)));
- }
+ return result.isEmpty() ? null : result.toArray(new CommonProblemDescriptor[result.size()]);
}
+ return null;
}
+
@Override
public boolean isEnabledByDefault() {
return false;
});
}
}
+
+ private static class UnusedLibraryGraphAnnotator extends RefGraphAnnotator {
+ public static final Key<Set<VirtualFile>> USED_LIBRARY_ROOTS = Key.create("inspection.dependencies");
+ private final DirectoryIndex myDirectoryIndex;
+ private RefManager myManager;
+
+ public UnusedLibraryGraphAnnotator(RefManager manager) {
+ myManager = manager;
+ myDirectoryIndex = DirectoryIndex.getInstance(manager.getProject());
+ }
+
+ @Override
+ public void onMarkReferenced(PsiElement what, PsiElement from, boolean referencedFromClassInitializer) {
+ if (what != null && from != null){
+ final VirtualFile virtualFile = PsiUtilCore.getVirtualFile(what);
+ final VirtualFile containingDir = virtualFile != null ? virtualFile.getParent() : null;
+ if (containingDir != null) {
+ final DirectoryInfo infoForDirectory = myDirectoryIndex.getInfoForDirectory(containingDir);
+ final VirtualFile libraryClassRoot = infoForDirectory != null ? infoForDirectory.getLibraryClassRoot() : null;
+ if (libraryClassRoot != null) {
+ final Module fromModule = ModuleUtilCore.findModuleForPsiElement(from);
+ if (fromModule != null){
+ final RefModule refModule = myManager.getRefModule(fromModule);
+ if (refModule != null) {
+ Set<VirtualFile> modules = refModule.getUserData(USED_LIBRARY_ROOTS);
+ if (modules == null){
+ modules = new HashSet<VirtualFile>();
+ refModule.putUserData(USED_LIBRARY_ROOTS, modules);
+ }
+ modules.add(libraryClassRoot);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
/*
- * 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.
for (CandidateInfo candidate : methodCandidates) {
PsiMethod method = (PsiMethod)candidate.getElement();
PsiSubstitutor substitutor = candidate.getSubstitutor();
- assert method != null;
PsiParameter[] params = method.getParameterList().getParameters();
if (params.length <= index) continue;
PsiParameter param = params[index];
/*
- * 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.
private static void addSuperSignatureElements(final PsiClass parent, boolean implemented, CompletionResultSet result, Set<MethodSignature> addedSignatures) {
for (CandidateInfo candidate : OverrideImplementExploreUtil.getMethodsToOverrideImplement(parent, implemented)) {
PsiMethod baseMethod = (PsiMethod)candidate.getElement();
- assert baseMethod != null;
PsiClass baseClass = baseMethod.getContainingClass();
PsiSubstitutor substitutor = candidate.getSubstitutor();
if (!baseMethod.isConstructor() && baseClass != null && addedSignatures.add(baseMethod.getSignature(substitutor))) {
!TypeConversionUtil.erasure(substitutedBoundType).isAssignableFrom(TypeConversionUtil.erasure(originalBound)) &&
!TypeConversionUtil.erasure(substitutedBoundType).isAssignableFrom(originalBound)) { //erasure is essential to avoid infinite recursion
if (wildcardType.isExtends()) {
- final PsiType glb = GenericsUtil.getGreatestLowerBound(wildcardType.getBound(), substitutedBoundType);
+ final PsiType bound = wildcardType.getBound();
+ if (bound instanceof PsiArrayType && substitutedBoundType instanceof PsiArrayType &&
+ !bound.isAssignableFrom(substitutedBoundType) && !substitutedBoundType.isAssignableFrom(bound)) {
+ continue;
+ }
+ final PsiType glb = GenericsUtil.getGreatestLowerBound(bound, substitutedBoundType);
if (glb != null) {
substituted = PsiWildcardType.createExtends(manager, glb);
}
StringBuilder buffer = new StringBuilder();
appendMirrorText(0, buffer);
- LOG.error("Mirror wasn't set for " + this + " in " + getContainingFile() + ", expected text '" + buffer + "'");
+ LOG.warn("Mirror wasn't set for " + this + " in " + getContainingFile() + ", expected text '" + buffer + "'");
return buffer.toString();
}
@NotNull PsiElement place) {
assert isValid();
- // TODO den remove
- boolean allowCaching = true;
-
- if (allowCaching && processor instanceof ClassResolverProcessor && isPhysical() &&
+ if (processor instanceof ClassResolverProcessor &&
+ isPhysical() &&
(getUserData(PsiFileEx.BATCH_REFERENCE_PROCESSING) == Boolean.TRUE || myResolveCache.hasUpToDateValue())) {
final ClassResolverProcessor hint = (ClassResolverProcessor)processor;
String name = hint.getName(state);
/*
- * 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.
ProgressManager.checkCanceled();
final CandidateInfo conflict = iterator.next();
final PsiMethod method = (PsiMethod)conflict.getElement();
- if (method != null) {
- final PsiParameter[] methodParameters = method.getParameterList().getParameters();
- if (methodParameters.length == 0) continue;
- final PsiParameter param = i < methodParameters.length ? methodParameters[i] : methodParameters[methodParameters.length - 1];
- final PsiType paramType = param.getType();
- // http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.1
- // A lambda expression or a method reference expression is potentially compatible with a type variable if the type variable is a type parameter of the candidate method.
- final PsiClass paramClass = PsiUtil.resolveClassInType(paramType);
- if (paramClass instanceof PsiTypeParameter && ((PsiTypeParameter)paramClass).getOwner() == method) continue;
- if (!lambdaExpression.isAcceptable(((MethodCandidateInfo)conflict).getSubstitutor(false).substitute(paramType), lambdaExpression.hasFormalParameterTypes())) {
- iterator.remove();
- }
+ final PsiParameter[] methodParameters = method.getParameterList().getParameters();
+ if (methodParameters.length == 0) continue;
+ final PsiParameter param = i < methodParameters.length ? methodParameters[i] : methodParameters[methodParameters.length - 1];
+ final PsiType paramType = param.getType();
+ // http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.1
+ // A lambda expression or a method reference expression is potentially compatible with a type variable if the type variable is a type parameter of the candidate method.
+ final PsiClass paramClass = PsiUtil.resolveClassInType(paramType);
+ if (paramClass instanceof PsiTypeParameter && ((PsiTypeParameter)paramClass).getOwner() == method) continue;
+ if (!lambdaExpression.isAcceptable(((MethodCandidateInfo)conflict).getSubstitutor(false).substitute(paramType), lambdaExpression.hasFormalParameterTypes())) {
+ iterator.remove();
}
}
}
ProgressManager.checkCanceled();
CandidateInfo info = conflicts.get(i);
PsiMethod method = (PsiMethod)info.getElement();
- assert method != null;
if (!method.hasModifierProperty(PsiModifier.STATIC) && superMethods.contains(method)) {
conflicts.remove(i);
continue;
}
PsiMethod existingMethod = (PsiMethod)existing.getElement();
- assert existingMethod != null;
PsiClass existingClass = existingMethod.getContainingClass();
if (class1 != null && existingClass != null &&
class1.isInterface() && CommonClassNames.JAVA_LANG_OBJECT.equals(existingClass.getQualifiedName())) { //prefer interface methods to methods from Object
for (CandidateInfo conflict : conflicts) {
ProgressManager.checkCanceled();
PsiMethod method = (PsiMethod)conflict.getElement();
- if (method != objectVararg && method != null && method.isVarArgs()) {
+ if (method != objectVararg && method.isVarArgs()) {
final int paramsCount = method.getParameterList().getParametersCount();
final PsiType type = method.getParameterList().getParameters()[paramsCount - 1].getType();
final PsiType componentType = ((PsiArrayType)type).getComponentType();
@Nullable
private static PsiType getFunctionalType(int functionalTypeIdx, CandidateInfo candidateInfo) {
final PsiMethod psiMethod = (PsiMethod)candidateInfo.getElement();
- LOG.assertTrue(psiMethod != null);
+ LOG.assertTrue(true);
final PsiParameter[] methodParameters = psiMethod.getParameterList().getParameters();
if (methodParameters.length == 0) return null;
final PsiParameter param = functionalTypeIdx < methodParameters.length ? methodParameters[functionalTypeIdx] : methodParameters[methodParameters.length - 1];
/*
- * Copyright 2000-2009 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.
for (int i = 1; i < uncheckedResult.length; i++) {
final CandidateInfo candidate = uncheckedResult[i];
final PsiElement otherElement = candidate.getElement();
- if (otherElement == null) continue;
if (!(otherElement instanceof PsiField)) {
if (otherElement instanceof PsiLocalVariable) {
--- /dev/null
+class Test {
+ Runnable r = new Runnable() {
+ <error descr="Modifier 'private' not allowed here">private</error> class Foo {}
+ @Override
+ public void run() {
+
+ }
+ };
+}
+
--- /dev/null
+
+class FirstClass {
+ public FirstClass(int i) {
+ }
+
+ public FirstClass() {
+ this(Point.FOO);
+ }
+
+ public class Point {
+ public static final int FOO = 0;
+ }
+}
--- /dev/null
+abstract class A {
+ abstract <T> void foo();
+}
+
+abstract class B extends A {
+ void foo()
+ {
+ this.<Integer>foo();
+ }
+}
+
+abstract class C {
+ void foo()
+ {
+ this.<error descr="Method 'foo()' does not have type parameters"><Integer></error>foo();
+ }
+}
\ No newline at end of file
--- /dev/null
+abstract class A<T, S extends T>
+{
+ abstract S bar();
+ void foo(A<Runnable[], ? extends Cloneable[]> a){
+ <error descr="Incompatible types. Found: 'java.lang.Cloneable[]', required: 'java.lang.Runnable[]'">Runnable[] x = a.bar();</error>
+ }
+}
+
+abstract class AB<T, S extends T>
+{
+ abstract S bar();
+ void foo(AB<Runnable, ? extends Cloneable> a){
+ Runnable x = a.bar();
+ }
+}
+
+abstract class AC<T, S>
+{
+ abstract S bar();
+ void foo(AC<Runnable[], ? extends Cloneable[]> a){
+ <error descr="Incompatible types. Found: 'java.lang.Cloneable[]', required: 'java.lang.Runnable[]'">Runnable[] x = a.bar();</error>
+ }
+}
+
--- /dev/null
+import java.util.List;
+import java.util.Set;
+
+class Clazz {
+ void foo(List<String> l, Set<String> s) {
+ l.removeAll(s);
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>testSimple_0.iml</file>
+ <problem_class>Unused library</problem_class>
+ <description>Unused library 'JUnit'</description>
+ </problem>
+
+</problems>
+
--- /dev/null
+class Test {
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<problems/>
+
--- /dev/null
+import junit.framework.TestCase;
+public class MyTest extends TestCase {}
public void testIDEA57388() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
public void testIDEA125800() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
public void testIDEA125816() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
+ public void testIDEA57338() { doTest(LanguageLevel.JDK_1_6, JavaSdkVersion.JDK_1_6, false); }
+ public void testIDEA67600() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
//jdk should propagate LL 1.4 but actually it provides LL 1.7?!
public void testCastObjectToIntJdk14() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_4, false); }
public void testEnumInitializers() { doTest(false, false); }
public void testEnumSynthetics() { doTest(false, false); }
public void testIDEA79251() { doTest(false, false); }
+ public void testIDEA65473() { doTest(false, false); }
+ public void testIDEA61415() { doTest(false, false); }
public void testAgentPremain() {
doTest(false, false);
}
public void testConcurrentHashMap() throws Exception { doTest(); }
public void testRemoveAllCall() throws Exception { doTest(); }
+ public void testSetList() throws Exception { doTest(); }
public void testUseDfa() throws Exception { doTest(); }
public void testWildcard() throws Exception { doTest(); }
public void testIgnoreConvertible() throws Exception {
--- /dev/null
+/*
+ * 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.
+ */
+
+/*
+ * Created by IntelliJ IDEA.
+ * User: max
+ * Date: Apr 11, 2002
+ * Time: 6:50:50 PM
+ * To change template for new class use
+ * Code Style | Class Templates options (Tools | IDE Options).
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
+import com.intellij.codeInspection.magicConstant.MagicConstantInspection;
+import com.intellij.codeInspection.unusedLibraries.UnusedLibrariesInspection;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkModificator;
+import com.intellij.openapi.roots.AnnotationOrderRootType;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.testFramework.InspectionTestCase;
+import com.intellij.testFramework.PlatformTestUtil;
+import com.intellij.testFramework.PsiTestUtil;
+
+public class UnusedLibraryInspectionTest extends InspectionTestCase {
+ @Override
+ protected String getTestDataPath() {
+ return JavaTestUtil.getJavaTestDataPath() + "/inspection/unusedLibrary";
+ }
+
+ @Override
+ protected void setupRootModel(String testDir, VirtualFile[] sourceDir, String sdkName) {
+ super.setupRootModel(testDir, sourceDir, sdkName);
+ PsiTestUtil.addLibrary(getModule(), "JUnit", getTestDataPath() + "/junit.jar");
+ }
+
+ private void doTest() throws Exception {
+ doTest("/" + getTestName(true), new UnusedLibrariesInspection());
+ }
+
+ public void testSimple() throws Exception { doTest(); }
+}
#include <pthread.h>
#include <sys/mount.h>
+#define PRIVATE_DIR "/private/"
+#define PRIVATE_LEN 9
+
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+static bool report_private = true;
static void reportEvent(char *event, char *path) {
int len = 0;
}
pthread_mutex_lock(&lock);
-
- fputs(event, stdout);
- fputc('\n', stdout);
- if (path != NULL) {
- fwrite(path, len, 1, stdout);
+ if (report_private || strncasecmp(path, PRIVATE_DIR, PRIVATE_LEN) != 0) {
+ fputs(event, stdout);
fputc('\n', stdout);
+ if (path != NULL) {
+ fwrite(path, len, 1, stdout);
+ fputc('\n', stdout);
+ }
+ fflush(stdout);
}
-
- fflush(stdout);
pthread_mutex_unlock(&lock);
}
static void ParseRoots() {
CFMutableArrayRef roots = CFArrayCreateMutable(NULL, 0, NULL);
+ bool has_private_root = false;
while (TRUE) {
fscanf(stdin, "%s", command);
if (strcmp(command, "#") == 0 || feof(stdin)) break;
char* path = command[0] == '|' ? command + 1 : command;
CFArrayAppendValue(roots, strdup(path));
+ if (strcmp(path, "/") == 0 || strncasecmp(path, PRIVATE_DIR, PRIVATE_LEN) == 0) {
+ has_private_root = true;
+ }
}
+ pthread_mutex_lock(&lock);
+ report_private = has_private_root;
+ pthread_mutex_unlock(&lock);
+
PrintMountedFileSystems(roots);
for (int i = 0; i < CFArrayGetCount(roots); i++) {
*/
package com.intellij.codeInspection.reference;
+import com.intellij.psi.PsiElement;
+
/**
* Callback which gets called while a reference graph is being built during a global
* inspection run.
onMarkReferenced(refWhat, refFrom, referencedFromClassInitializer);
}
+
+ /**
+ * Called when 'what' element doesn't belong to the selected scope.
+ * @param what the referenced element
+ * @param from the referencing element
+ * @param referencedFromClassInitializer if true, <code>refFrom</code> is a class and the reference
+ * has been found in its initializer block.
+ */
+ public void onMarkReferenced(PsiElement what,
+ PsiElement from,
+ boolean referencedFromClassInitializer) {}
+
}
/*
- * 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.
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.scope.packageSet.*;
+import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.List;
+
public class GlobalSearchScopesCore {
@NotNull
public static GlobalSearchScope projectProductionScope(@NotNull Project project) {
//noinspection HardCodedStringLiteral
return "directory scope: " + myDirectory + "; withSubdirs:"+myWithSubdirectories;
}
+
+ @Override
+ public int hashCode() {
+ return myDirectory.hashCode() *31 + (myWithSubdirectories?1:0);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof DirectoryScope &&
+ myDirectory.equals(((DirectoryScope)obj).myDirectory) &&
+ myWithSubdirectories == ((DirectoryScope)obj).myWithSubdirectories;
+ }
+
+ @NotNull
+ @Override
+ public GlobalSearchScope uniteWith(@NotNull GlobalSearchScope scope) {
+ if (equals(scope)) return this;
+ if (scope instanceof DirectoryScope) {
+ DirectoryScope other = (DirectoryScope)scope;
+ VirtualFile otherDirectory = other.myDirectory;
+ if (myWithSubdirectories && VfsUtilCore.isAncestor(myDirectory, otherDirectory, false)) return this;
+ if (other.myWithSubdirectories && VfsUtilCore.isAncestor(otherDirectory, myDirectory, false)) return other;
+ BitSet newWithSubdirectories = new BitSet();
+ newWithSubdirectories.set(0, myWithSubdirectories);
+ newWithSubdirectories.set(1, other.myWithSubdirectories);
+ return new DirectoriesScope(getProject(), new VirtualFile[]{myDirectory,otherDirectory}, newWithSubdirectories);
+ }
+ return super.uniteWith(scope);
+ }
+ }
+
+ static class DirectoriesScope extends GlobalSearchScope {
+ private final VirtualFile[] myDirectories;
+ private final BitSet myWithSubdirectories;
+
+ private DirectoriesScope(@NotNull Project project, @NotNull VirtualFile[] directories, @NotNull BitSet withSubdirectories) {
+ super(project);
+ myWithSubdirectories = withSubdirectories;
+ myDirectories = directories;
+ }
+
+ @Override
+ public boolean contains(@NotNull VirtualFile file) {
+ VirtualFile parent = file.getParent();
+ return parent != null && in(parent);
+ }
+
+ private boolean in(@NotNull VirtualFile parent) {
+ for (int i = 0; i < myDirectories.length; i++) {
+ VirtualFile directory = myDirectories[i];
+ boolean withSubdirectories = myWithSubdirectories.get(i);
+ if (withSubdirectories ? VfsUtilCore.isAncestor(directory, parent, false) : directory.equals(parent)) return true;
+ }
+ return false;
+ }
+
+ @Override
+ public int compare(@NotNull VirtualFile file1, @NotNull VirtualFile file2) {
+ return 0;
+ }
+
+ @Override
+ public boolean isSearchInModuleContent(@NotNull Module aModule) {
+ return true;
+ }
+
+ @Override
+ public boolean isSearchInLibraries() {
+ return false;
+ }
+
+ public String toString() {
+ //noinspection HardCodedStringLiteral
+ return "Directories scope: " + Arrays.asList(myDirectories);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 1;
+ for (int i = 0; i < myDirectories.length; i++) {
+ VirtualFile directory = myDirectories[i];
+ boolean withSubdirectories = myWithSubdirectories.get(i);
+ result = result*31 + directory.hashCode() *31 + (withSubdirectories?1:0);
+ }
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof DirectoriesScope &&
+ Arrays.equals(myDirectories, ((DirectoriesScope)obj).myDirectories) &&
+ myWithSubdirectories.equals(((DirectoriesScope)obj).myWithSubdirectories);
+ }
+
+ @NotNull
+ @Override
+ public GlobalSearchScope uniteWith(@NotNull GlobalSearchScope scope) {
+ if (equals(scope)) {
+ return this;
+ }
+ if (scope instanceof DirectoryScope) {
+ if (in(((DirectoryScope)scope).myDirectory)) {
+ return this;
+ }
+ VirtualFile[] newDirectories = ArrayUtil.append(myDirectories, ((DirectoryScope)scope).myDirectory, VirtualFile.class);
+ BitSet newWithSubdirectories = (BitSet)myWithSubdirectories.clone();
+ newWithSubdirectories.set(myDirectories.length, ((DirectoryScope)scope).myWithSubdirectories);
+ return new DirectoriesScope(getProject(), newDirectories, newWithSubdirectories);
+ }
+ if (scope instanceof DirectoriesScope) {
+ DirectoriesScope other = (DirectoriesScope)scope;
+ List<VirtualFile> newDirectories = new ArrayList<VirtualFile>(myDirectories.length + other.myDirectories.length);
+ newDirectories.addAll(Arrays.asList(other.myDirectories));
+ BitSet newWithSubdirectories = (BitSet)myWithSubdirectories.clone();
+ VirtualFile[] directories = other.myDirectories;
+ for (int i = 0; i < directories.length; i++) {
+ VirtualFile otherDirectory = directories[i];
+ if (!in(otherDirectory)) {
+ newWithSubdirectories.set(newDirectories.size(), other.myWithSubdirectories.get(i));
+ newDirectories.add(otherDirectory);
+ }
+ }
+ return new DirectoriesScope(getProject(), newDirectories.toArray(new VirtualFile[newDirectories.size()]), newWithSubdirectories);
+ }
+ return super.uniteWith(scope);
+ }
}
}
}
}
+ public void fireNodeMarkedReferenced(PsiElement what,
+ PsiElement from,
+ boolean referencedFromClassInitializer) {
+ for (RefGraphAnnotator annotator : myGraphAnnotators) {
+ annotator.onMarkReferenced(what, from, referencedFromClassInitializer);
+ }
+ }
+
public void fireBuildReferences(RefElement refElement) {
for (RefGraphAnnotator annotator : myGraphAnnotators) {
annotator.onReferencesBuild(refElement);
myPsiFile = psiFile;
myCodeInsightSettings = CodeInsightSettings.getInstance();
- // myFileType = myPsiFile == null ? null : myPsiFile.getFileType();
}
static void lookForInjectedAndMatchBracesInOtherThread(@NotNull final Editor editor,
@NotNull final Alarm alarm,
@NotNull final Processor<BraceHighlightingHandler> processor) {
ApplicationManagerEx.getApplicationEx().assertIsDispatchThread();
- final Project project = editor.getProject();
- if (project == null || project.isDisposed()) return;
+ if (!isValidEditor(editor)) return;
if (!PROCESSED_EDITORS.add(editor)) {
// Skip processing if that is not really necessary.
// Assuming to be in EDT here.
return;
}
final int offset = editor.getCaretModel().getOffset();
+ final Project project = editor.getProject();
final PsiFile psiFile = PsiUtilBase.getPsiFileInEditor(editor, project);
+ if (!isValidFile(psiFile)) return;
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
injected = psiFile == null ||
psiFile instanceof PsiCompiledElement ||
psiFile instanceof PsiBinaryFile ||
- isReallyDisposed(editor, project)
+ !isValidEditor(editor) ||
+ !isValidFile(psiFile)
? null : getInjectedFileIfAny(editor, project, offset, psiFile, alarm);
}
catch (RuntimeException e) {
@Override
public void run() {
try {
- if (!isReallyDisposed(editor, project)) {
+ if (isValidEditor(editor) && isValidFile(injected)) {
Editor newEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injected);
BraceHighlightingHandler handler = new BraceHighlightingHandler(project, newEditor, alarm, injected);
processor.process(handler);
});
}
- private static boolean isReallyDisposed(@NotNull Editor editor, @NotNull Project project) {
+ private static boolean isValidFile(PsiFile file) {
+ return file != null && file.isValid() && !file.getProject().isDisposed();
+ }
+
+ private static boolean isValidEditor(@NotNull Editor editor) {
Project editorProject = editor.getProject();
- return editorProject == null ||
- editorProject.isDisposed() || project.isDisposed() || !editor.getComponent().isShowing() || editor.isViewer();
+ return editorProject != null && !editorProject.isDisposed() && !editor.isDisposed() && editor.getComponent().isShowing() && !editor.isViewer();
}
@NotNull
return !myNotRequiringContentIndices.contains(indexId);
}
+ private @Nullable IndexableFileSet getIndexableSetForFile(VirtualFile file) {
+ for (IndexableFileSet set : myIndexableSets) {
+ if (set.isInSet(file)) {
+ return set;
+ }
+ }
+ return null;
+ }
+
+
private abstract static class InvalidationTask implements Runnable {
private final VirtualFile mySubj;
}
}
});
- // the file is for sure not a dir and it was previously indexed by at least one index
- if (!isTooLarge(file)) scheduleForUpdate(file);
+ // the file is for sure not a dir and it was previously indexed by at least one index AND it belongs to some update set
+ if (!isTooLarge(file) && getIndexableSetForFile(file) != null) scheduleForUpdate(file);
}
}
else if (!fileIndexedStatesToUpdate.isEmpty()) { // file was removed, its data should be (lazily) wiped for every index
}
}
else {
- for (IndexableFileSet set : myIndexableSets) {
- if (set.isInSet(file)) {
- processor.process(file);
- break;
- }
- }
+ if (getIndexableSetForFile(file) != null) processor.process(file);
}
}
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.Couple;
+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;
url = url.substring(0, sharpPos);
}
- Couple<String> pair = URLUtil.splitJarUrl(url);
+ Pair<String, String> pair = URLUtil.splitJarUrl(url);
if (pair == null) return null;
File jarFile = new File(FileUtil.toSystemDependentName(pair.first));
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.mac.foundation.Foundation;
import com.intellij.ui.mac.foundation.ID;
+import com.intellij.util.concurrency.FutureResult;
import com.sun.jna.IntegerType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
/**
* <p>This class is used to workaround the problem with getting clipboard contents (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4818143).
@Nullable
private static Transferable getContentsSafe() {
- final Ref<Transferable> result = new Ref<Transferable>();
+ final FutureResult<Transferable> result = new FutureResult<Transferable>();
Foundation.executeOnMainThread(new Runnable() {
@Override
result.set(transferable);
}
}
- }, true, true);
+ }, true, false);
- return result.get();
+ try {
+ return result.get(10, TimeUnit.MILLISECONDS);
+ }
+ catch (Exception ignored) {
+ return null;
+ }
}
@Nullable
/*
- * 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.
import com.intellij.execution.util.ExecUtil;
import com.intellij.ide.DataManager;
import com.intellij.ide.IdeBundle;
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationListener;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import javax.swing.event.HyperlinkEvent;
import javax.swing.filechooser.FileSystemView;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
+import java.net.URL;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ShowFilePathAction extends AnAction {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.ShowFilePathAction");
+ public static final NotificationListener FILE_SELECTING_LISTENER = new NotificationListener.Adapter() {
+ @Override
+ protected void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent e) {
+ URL url = e.getURL();
+ if (url != null) openFile(new File(url.getPath()));
+ notification.expire();
+ }
+ };
+
private static NotNullLazyValue<Boolean> canUseNautilus = new NotNullLazyValue<Boolean>() {
@NotNull
@Override
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.util.Couple;
+import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.Nullable;
public class DuplicateAction extends EditorAction {
@Nullable
static Couple<Integer> duplicateLinesRange(Editor editor, Document document, VisualPosition rangeStart, VisualPosition rangeEnd) {
- Couple<LogicalPosition> lines = EditorUtil.calcSurroundingRange(editor, rangeStart, rangeEnd);
+ Pair<LogicalPosition, LogicalPosition> lines = EditorUtil.calcSurroundingRange(editor, rangeStart, rangeEnd);
int offset = editor.getCaretModel().getOffset();
LogicalPosition lineStart = lines.first;
import com.intellij.openapi.editor.impl.IterationState;
import com.intellij.openapi.fileEditor.impl.text.TextEditorImpl;
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
-import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.TextRange;
* @see #getNotFoldedLineEndOffset(com.intellij.openapi.editor.Editor, int)
*/
@SuppressWarnings("AssignmentToForLoopParameter")
- public static Couple<LogicalPosition> calcSurroundingRange(@NotNull Editor editor,
- @NotNull VisualPosition start,
- @NotNull VisualPosition end) {
+ public static Pair<LogicalPosition, LogicalPosition> calcSurroundingRange(@NotNull Editor editor,
+ @NotNull VisualPosition start,
+ @NotNull VisualPosition end) {
final Document document = editor.getDocument();
final FoldingModel foldingModel = editor.getFoldingModel();
for (
int line = first.line, offset = document.getLineStartOffset(line);
offset >= 0;
- offset = document.getLineStartOffset(line))
- {
+ offset = document.getLineStartOffset(line)) {
final FoldRegion foldRegion = foldingModel.getCollapsedRegionAtOffset(offset);
if (foldRegion == null) {
first = new LogicalPosition(line, 0);
for (
int line = second.line, offset = document.getLineEndOffset(line);
offset <= document.getTextLength();
- offset = document.getLineEndOffset(line))
- {
+ offset = document.getLineEndOffset(line)) {
final FoldRegion foldRegion = foldingModel.getCollapsedRegionAtOffset(offset);
if (foldRegion == null) {
second = new LogicalPosition(line + 1, 0);
if (second.line >= document.getLineCount()) {
second = editor.offsetToLogicalPosition(document.getTextLength());
}
- return Couple.of(first, second);
+ return Pair.create(first, second);
}
/**
}
});
}
- private final TransferToPooledThreadQueue<Collection<VirtualFile>> reDetectQueue = new TransferToPooledThreadQueue<Collection<VirtualFile>>("file type re-detect", Condition.FALSE, -1, new Processor<Collection<VirtualFile>>() {
+
+ private final TransferToPooledThreadQueue<Collection<VirtualFile>> reDetectQueue = new TransferToPooledThreadQueue<Collection<VirtualFile>>("File type re-detect", Condition.FALSE, -1, new Processor<Collection<VirtualFile>>() {
@Override
public boolean process(Collection<VirtualFile> files) {
- ((FileTypeManagerImpl)getInstance()).reDetect(files);
+ reDetect(files);
return true;
}
});
private boolean shouldBeSavedToFile(final FileType fileType) {
if (!(fileType instanceof JDOMExternalizable) || !shouldSave(fileType)) return false;
- if (myDefaultTypes.contains(fileType) && !isDefaultModified(fileType)) return false;
- return true;
+ return !myDefaultTypes.contains(fileType) || isDefaultModified(fileType);
}
@Override
private static boolean isUpToDate(File executable) {
long length = SystemInfo.isWindows ? 71208 :
- SystemInfo.isMac ? 13924 :
+ SystemInfo.isMac ? 13984 :
SystemInfo.isLinux ? SystemInfo.isAMD64 ? 29155 : 22791 :
-1;
return length < 0 || length == executable.length();
action.CaptureMemorySnapShot.description=Capture memory snapshot
action.CaptureCPUUsageData.text=Start CPU Usage Profiling
action.CaptureCPUUsageData.description=Capture CPU usage data
+stop.capture.cpu.usage.data.action.name=Stop CPU Usage Profiling
action.CaptureAllocations.text=Capture Allocations
action.CaptureAllocations.description=Capture memory allocations data
+stop.capture.allocations.data.action.name=Stop Capturing Allocations
action.ContextHelp.text=Conte_xt Help
action.ContextHelp.description=Show context help
action.RunConfiguration.text=Select Run/Debug Configuration
group.ShowRecentFindUsagesGroup.text=Recent Find Usages
group.ShowRecentFindUsagesGroup.description=Choose and re-run recent find usages
-stop.capture.cpu.usage.data.action.name=Stop CPU Usage Profiling
-stop.capture.cpu.usage.data.action.description=Stop capturing CPU usage data
-stop.capture.allocations.usage.data.action.name=Capture allocations data, now capturing
-stop.capture.allocations.usage.data.action.description=Stop capturing allocations data
-
action.IntegrateFiles.text=Integrate
action.IntegrateFiles.description=Integrate selected files or directories
action.Vcs.IntegrateProject.text=Inte_grate Project
format.file.size.kbytes={0}Kb
format.file.size.mbytes={0}Mb
-profiling.captured.cpu.snapshot.message.text=Captured CPU snapshot: ''{0}'' is placed in user home directory.
-profiling.captured.allocations.snapshot.message.text=Captured allocations snapshot: ''{0}'' is placed in user home directory.
-information.dialog.title=Information
-captured.memory.snapshot.placed.in.user.home.directory.message.text=Captured memory snapshot: ''{0}'' is placed in user home directory.
+profiling.capture.snapshot.success=Captured snapshot ''{0}'' is placed in user home directory. <a href="{1}">Show in {2}</a>.
+profiling.capture.snapshot.error=Failed to capture snapshot: {0}
cannot.undo.dialog.title=Cannot Undo
cannot.undo.error.other.affected.files.changed.message=Following files affected by this action have been already changed:
select.xsd.schema.dialog.title=Select XSD Schema
emmet.title=Emmet
-emmet.configuration.title=Emmet (Zen Coding)
+emmet.configuration.title=Emmet
emmet.enable.label=&Enable XML Emmet
emmet.enable.bem.filter=Enable &BEM filter by default
emmet.enable.preview=Enable &abbreviation preview
emmet.expand.abbreviation.with=Expand &abbreviation with
-zen.coding.enter.abbreviation.dialog.label=Please enter an abbreviation
-zen.coding.incorrect.abbreviation.error=Incorrect abbreviation
title.cannot.create.html.file=Cannot create HTML file
new.html.file.action=HTML File
--- /dev/null
+/*
+ * 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.psi.search;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.testFramework.PlatformTestCase;
+
+public class GlobalSearchScopeTest extends PlatformTestCase {
+ public void testUniteDirectorySearchScopeDoesNotSOE() throws Exception {
+ VirtualFile genRoot = getVirtualFile(createTempDir("genSrcRoot"));
+ VirtualFile srcRoot = getVirtualFile(createTempDir("srcRoot"));
+ VirtualFile child = srcRoot.createChildDirectory(this, "child");
+ GlobalSearchScope childScope = GlobalSearchScopesCore.directoryScope(getProject(), child, true);
+
+ GlobalSearchScope directoryScope = GlobalSearchScopesCore.directoryScope(getProject(), srcRoot, true);
+ GlobalSearchScope scope = GlobalSearchScope.EMPTY_SCOPE.uniteWith(directoryScope);
+ assertSame(scope, directoryScope);
+ scope = scope.uniteWith(directoryScope);
+ assertSame(scope, directoryScope);
+
+ scope = scope.uniteWith(childScope);
+ assertSame(scope, directoryScope);
+
+ GlobalSearchScope s = childScope;
+ int N = 1000;
+ VirtualFile[] d = new VirtualFile[N];
+ for (int i=0; i< N;i++) {
+ d[i] = srcRoot.createChildDirectory(this, "d"+i);
+ GlobalSearchScope united = s.uniteWith(GlobalSearchScopesCore.directoryScope(getProject(), d[i], true));
+ assertNotSame(s, united);
+ s = united;
+ assertTrue(s instanceof GlobalSearchScopesCore.DirectoriesScope);
+ }
+ for (VirtualFile file : d) {
+ VirtualFile f = createChildData(file, "f");
+ assertTrue(s.contains(f));
+ }
+ assertFalse(s.contains(genRoot));
+
+ assertSame(s.uniteWith(childScope), s);
+ assertSame(s.uniteWith(s), s);
+ }
+}
\ No newline at end of file
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.notification.NotificationGroup;
import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
+import javax.swing.tree.TreePath;
import java.awt.*;
import java.util.List;
return null;
}
+ public static boolean isMultipleSelectionImpossible(DataContext dataContext) {
+ final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext);
+ if (component instanceof JTree) {
+ final TreePath[] selectionPaths = ((JTree)component).getSelectionPaths();
+ if (selectionPaths == null || selectionPaths.length <= 1) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public static Navigatable getOpenFileDescriptor(final AbstractTestProxy testProxy, final TestFrameworkRunningModel model) {
final TestConsoleProperties testConsoleProperties = model.getProperties();
return getOpenFileDescriptor(testProxy, testConsoleProperties,
System.arraycopy(array, 0, result, 0, Math.min(oldSize, newSize));
return result;
}
+ @NotNull
+ public static boolean[] realloc(@NotNull boolean[] array, final int newSize) {
+ if (newSize == 0) {
+ return EMPTY_BOOLEAN_ARRAY;
+ }
+
+ final int oldSize = array.length;
+ if (oldSize == newSize) {
+ return array;
+ }
+
+ boolean[] result = new boolean[newSize];
+ System.arraycopy(array, 0, result, 0, Math.min(oldSize, newSize));
+ return result;
+ }
@NotNull
public static int[] realloc(@NotNull int[] array, final int newSize) {
array[array.length - 1] = value;
return array;
}
+ @NotNull
+ public static boolean[] append(@NotNull boolean[] array, boolean value) {
+ array = realloc(array, array.length + 1);
+ array[array.length - 1] = value;
+ return array;
+ }
@NotNull
public static char[] realloc(@NotNull char[] array, final int newSize) {
*/
package com.intellij.util.io;
-import com.intellij.openapi.util.Couple;
+import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
@NotNull
private static InputStream openJarStream(@NotNull URL url) throws IOException {
- Couple<String> paths = splitJarUrl(url.getFile());
+ Pair<String, String> paths = splitJarUrl(url.getFile());
if (paths == null) {
throw new MalformedURLException(url.getFile());
}
* E.g. "jar:file:///path/to/jar.jar!/resource.xml" is converted into ["/path/to/jar.jar", "resource.xml"].
*/
@Nullable
- public static Couple<String> splitJarUrl(@NotNull String url) {
+ public static Pair<String, String> splitJarUrl(@NotNull String url) {
int pivot = url.indexOf(JAR_SEPARATOR);
if (pivot < 0) return null;
}
}
- return Couple.of(jarPath, resourcePath);
+ return Pair.create(jarPath, resourcePath);
}
@NotNull
<orderEntry type="module" module-name="lang-impl" />
<orderEntry type="module" module-name="idea-ui" />
<orderEntry type="module" module-name="openapi" />
+ <orderEntry type="module" module-name="vcs-impl" />
</component>
</module>
package com.intellij.remoteServer.util;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vcs.AbstractVcsHelper;
import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.changes.*;
import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.remoteServer.agent.util.CloudGitApplication;
import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
import com.intellij.remoteServer.runtime.deployment.DeploymentTask;
import com.intellij.util.ArrayUtil;
import com.intellij.util.concurrency.Semaphore;
+import git4idea.GitPlatformFacade;
import git4idea.GitUtil;
import git4idea.actions.GitInit;
import git4idea.commands.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
/**
private static final Logger LOG = Logger.getInstance("#" + CloudGitDeploymentRuntime.class.getName());
+ private static final String COMMIT_MESSAGE = "Deploy";
+
private final GitRepositoryManager myGitRepositoryManager;
private final Git myGit;
+ private final AbstractVcsHelper myVcsHelper;
private final VirtualFile myContentRoot;
private final File myRepositoryRootFile;
private final String myDefaultRemoteName;
+ private final ChangeListManagerEx myChangeListManager;
private String myRemoteName;
private final String myCloudName;
LOG.assertTrue(contentRoot != null, "Repository root is not found");
myContentRoot = contentRoot;
- myGitRepositoryManager = GitUtil.getRepositoryManager(getProject());
+ Project project = getProject();
+ myGitRepositoryManager = GitUtil.getRepositoryManager(project);
myGit = ServiceManager.getService(Git.class);
if (myGit == null) {
throw new ServerRuntimeException("Can't initialize GIT");
}
+ GitPlatformFacade gitPlatformFacade = ServiceManager.getService(GitPlatformFacade.class);
+ myVcsHelper = gitPlatformFacade.getVcsHelper(project);
+ myChangeListManager = gitPlatformFacade.getChangeListManager(project);
}
@Override
public CloudGitApplication deploy() throws ServerRuntimeException {
CloudGitApplication application = findOrCreateApplication();
+ deployApplication(application);
+ return application;
+ }
+
+ private void deployApplication(CloudGitApplication application) throws ServerRuntimeException {
+ boolean firstDeploy = findRepository() == null;
+
GitRepository repository = findOrCreateRepository();
addOrResetGitRemote(application, repository);
- add();
- commit();
+
+ if (firstDeploy) {
+ add();
+ commit();
+ return;
+ }
+
+ final LocalChangeList activeChangeList = myChangeListManager.getDefaultChangeList();
+ if (activeChangeList == null) {
+ add();
+ commit();
+ return;
+ }
+
+ Collection<Change> changes = activeChangeList.getChanges();
+ final List<Change> relevantChanges = new ArrayList<Change>();
+ for (Change change : changes) {
+ if (isRelevant(change.getBeforeRevision()) || isRelevant(change.getAfterRevision())) {
+ relevantChanges.add(change);
+ }
+ }
+ if (relevantChanges.isEmpty()) {
+ Integer showCommitDialogChoice = runOnEdt(new Computable<Integer>() {
+
+ @Override
+ public Integer compute() {
+ return Messages.showYesNoCancelDialog(getProject(),
+ "Active changelist does not contain a relevant change.\n"
+ + "Do you want to show commit dialog anyway?\n\n"
+ + "Yes - show commit dialog\n"
+ + "No - push immediately\n"
+ + "Cancel - interrupt deploy",
+ "Deploy",
+ Messages.getWarningIcon());
+ }
+ });
+ if (showCommitDialogChoice == Messages.YES) {
+ relevantChanges.addAll(changes);
+ }
+ else if (showCommitDialogChoice == Messages.NO) {
+ pushApplication(application);
+ return;
+ }
+ else {
+ throw new ServerRuntimeException("Deploy interrupted");
+ }
+ }
+
+ final Semaphore commitSemaphore = new Semaphore();
+ commitSemaphore.down();
+
+ final Ref<Boolean> commitSucceeded = new Ref<Boolean>(false);
+ Boolean commitStarted = runOnEdt(new Computable<Boolean>() {
+
+ @Override
+ public Boolean compute() {
+ return myVcsHelper.commitChanges(relevantChanges, activeChangeList, COMMIT_MESSAGE,
+ new CommitResultHandler() {
+
+ @Override
+ public void onSuccess(@NotNull String commitMessage) {
+ commitSucceeded.set(true);
+ commitSemaphore.up();
+ }
+
+ @Override
+ public void onFailure() {
+ commitSemaphore.up();
+ }
+ });
+ }
+ });
+ if (commitStarted != null && commitStarted) {
+ commitSemaphore.waitFor();
+ if (!commitSucceeded.get()) {
+ repository.update();
+ throw new ServerRuntimeException("Commit failed");
+ }
+ }
+ else {
+ getLoggingHandler().println("Commit canceled");
+ }
+
repository.update();
pushApplication(application);
- return application;
+ }
+
+ private boolean isRelevant(ContentRevision contentRevision) throws ServerRuntimeException {
+ if (contentRevision == null) {
+ return false;
+ }
+ GitRepository repository = getRepository();
+ VirtualFile affectedFile = contentRevision.getFile().getVirtualFile();
+ return affectedFile != null && VfsUtilCore.isAncestor(repository.getRoot(), affectedFile, false);
+ }
+
+ private static <T> T runOnEdt(final Computable<T> computable) {
+ final Ref<T> result = new Ref<T>();
+ ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+
+ @Override
+ public void run() {
+ result.set(computable.compute());
+ }
+ }, ModalityState.any());
+ return result.get();
}
public void undeploy() throws ServerRuntimeException {
GitSimpleHandler handler = new GitSimpleHandler(getProject(), myContentRoot, GitCommand.COMMIT);
handler.setSilent(false);
handler.setStdoutSuppressed(false);
- handler.addParameters("-m", "Deploy");
+ handler.addParameters("-m", COMMIT_MESSAGE);
handler.endOptions();
handler.run();
}
package git4idea.util;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.Couple;
+import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.changes.Change;
import git4idea.GitCommit;
import git4idea.repo.GitRepository;
private static final Logger LOG = Logger.getInstance(GitCommitCompareInfo.class);
- private final Map<GitRepository, Couple<List<GitCommit>>> myInfo = new HashMap<GitRepository, Couple<List<GitCommit>>>();
+ private final Map<GitRepository, Pair<List<GitCommit>, List<GitCommit>>> myInfo = new HashMap<GitRepository, Pair<List<GitCommit>, List<GitCommit>>>();
private final Map<GitRepository, Collection<Change>> myTotalDiff = new HashMap<GitRepository, Collection<Change>>();
private final InfoType myInfoType;
myInfoType = infoType;
}
- public void put(@NotNull GitRepository repository, @NotNull Couple<List<GitCommit>> commits) {
+ public void put(@NotNull GitRepository repository, @NotNull Pair<List<GitCommit>, List<GitCommit>> commits) {
myInfo.put(repository, commits);
}
}
@NotNull
- private Couple<List<GitCommit>> getCompareInfo(@NotNull GitRepository repo) {
- Couple<List<GitCommit>> pair = myInfo.get(repo);
+ private Pair<List<GitCommit>, List<GitCommit>> getCompareInfo(@NotNull GitRepository repo) {
+ Pair<List<GitCommit>, List<GitCommit>> pair = myInfo.get(repo);
if (pair == null) {
LOG.error("Compare info not found for repository " + repo);
- return Couple.of(Collections.<GitCommit>emptyList(), Collections.<GitCommit>emptyList());
+ return Pair.create(Collections.<GitCommit>emptyList(), Collections.<GitCommit>emptyList());
}
return pair;
}
return Collections.emptyList();
}
+ @NotNull
+ @Override
+ public List<String> getExtraCommandLineArgs() {
+ return Collections.emptyList();
+ }
+
@NotNull
@Override
public ExternalSystemException getUserFriendlyError(@NotNull Throwable error,
return Collections.emptyList();
}
+ @NotNull
+ @Override
+ public List<String> getExtraCommandLineArgs() {
+ return Collections.emptyList();
+ }
+
@NotNull
@Override
public ExternalSystemException getUserFriendlyError(@NotNull Throwable error,
final ProjectImportAction projectImportAction = new ProjectImportAction(resolverCtx.isPreviewMode());
final List<KeyValue<String, String>> extraJvmArgs = new ArrayList<KeyValue<String, String>>();
+ final List<String> commandLineArgs = ContainerUtil.newArrayList();
+
for (GradleProjectResolverExtension resolverExtension = projectResolverChain;
resolverExtension != null;
resolverExtension = resolverExtension.getNext()) {
projectImportAction.addExtraProjectModelClasses(resolverExtension.getExtraProjectModelClasses());
// collect extra JVM arguments provided by gradle project resolver extensions
extraJvmArgs.addAll(resolverExtension.getExtraJvmArgs());
+ // collect extra command-line arguments
+ commandLineArgs.addAll(resolverExtension.getExtraCommandLineArgs());
}
final ParametersList parametersList = new ParametersList();
BuildActionExecuter<ProjectImportAction.AllModels> buildActionExecutor = resolverCtx.getConnection().action(projectImportAction);
- final List<String> commandLineArgs = ContainerUtil.newArrayList();
// TODO [vlad] remove the check
if (!GradleEnvironment.DISABLE_ENHANCED_TOOLING_API) {
File initScript = GradleExecutionHelper.generateInitScript(isBuildSrcProject);
@NotNull
List<KeyValue<String, String>> getExtraJvmArgs();
+ @NotNull
+ List<String> getExtraCommandLineArgs();
+
@NotNull
ExternalSystemException getUserFriendlyError(@NotNull Throwable error, @NotNull String projectPath, @Nullable String buildFilePath);
@Nullable final PsiType classToDelegate) {
if (classToDelegate == null) return true;
- if (state.get(ClassHint.RESOLVE_CONTEXT) == null) {
- state = state.put(ClassHint.RESOLVE_CONTEXT, this);
- }
-
return ResolveUtil.processAllDeclarationsSeparately(classToDelegate, processor, nonCodeProcessor,
state.put(ClassHint.RESOLVE_CONTEXT, this), place);
}
serviceImplementation="org.zmlx.hg4idea.HgRememberedInputs"/>
<projectService serviceInterface="org.zmlx.hg4idea.HgProjectSettings"
serviceImplementation="org.zmlx.hg4idea.HgProjectSettings"/>
+ <projectService serviceInterface="org.zmlx.hg4idea.provider.update.HgUpdateConfigurationSettings"
+ serviceImplementation="org.zmlx.hg4idea.provider.update.HgUpdateConfigurationSettings"/>
<projectService serviceInterface="org.zmlx.hg4idea.HgRootsHandler"
serviceImplementation="org.zmlx.hg4idea.HgRootsHandler" />
</extensions>
import java.util.Set;
import static org.zmlx.hg4idea.HgErrorHandler.ensureSuccess;
+import static org.zmlx.hg4idea.provider.update.HgUpdateType.MERGE;
+import static org.zmlx.hg4idea.provider.update.HgUpdateType.ONLY_UPDATE;
public class HgRegularUpdater implements HgUpdater {
@NotNull private final Project project;
@NotNull private final VirtualFile repoRoot;
- @NotNull private final UpdateConfiguration updateConfiguration;
+ @NotNull private final HgUpdateConfigurationSettings updateConfiguration;
- public HgRegularUpdater(@NotNull Project project, @NotNull VirtualFile repository, @NotNull UpdateConfiguration configuration) {
+ public HgRegularUpdater(@NotNull Project project, @NotNull VirtualFile repository, @NotNull HgUpdateConfigurationSettings configuration) {
this.project = project;
this.repoRoot = repository;
this.updateConfiguration = configuration;
}
- private boolean shouldMerge() {
- return updateConfiguration.shouldMerge();
- }
-
- private boolean shouldCommitAfterMerge() {
- return updateConfiguration.shouldCommitAfterMerge();
- }
-
public boolean update(final UpdatedFiles updatedFiles, ProgressIndicator indicator, List<VcsException> warnings)
throws VcsException {
indicator.setText(HgVcsMessages.message("hg4idea.progress.updating", repoRoot.getPath()));
// throw new VcsException("working dir not at branch tip (use \"Update to...\" to check out branch tip)");
// }
- HgCommandExitCode pullResult = pull(repoRoot, indicator);
- if (pullResult == HgCommandExitCode.ERROR) {
- return false;
+ if (updateConfiguration.shouldPull()) {
+ HgCommandExitCode pullResult = pull(repoRoot, indicator);
+ if (pullResult == HgCommandExitCode.ERROR) {
+ return false;
+ }
}
List<HgRevisionNumber> parentsBeforeUpdate = new HgWorkingCopyRevisionsCommand(project).parents(repoRoot);
List<HgRevisionNumber> pulledBranchHeads = determinePulledBranchHeads(branchHeadsBeforePull, branchHeadsAfterPull);
List<HgRevisionNumber> remainingOriginalBranchHeads =
determingRemainingOriginalBranchHeads(branchHeadsBeforePull, branchHeadsAfterPull);
+ HgUpdateType updateType = updateConfiguration.getUpdateType();
- if (branchHeadsAfterPull.size() > 1) {
+ if (branchHeadsAfterPull.size() > 1 && updateType != ONLY_UPDATE) {
// merge strategy
- if (shouldMerge()) {
+ if (updateType == MERGE) {
abortOnLocalChanges();
abortOnMultiplePulledHeads(pulledBranchHeads);
abortOnMultipleLocalHeads(remainingOriginalBranchHeads);
HgCommandResult mergeResult = doMerge(indicator);
- if (shouldCommitAfterMerge()) {
+ if (updateConfiguration.shouldCommitAfterMerge()) {
commitOrWarnAboutConflicts(warnings, mergeResult);
}
}
--- /dev/null
+/*
+ * 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.zmlx.hg4idea.provider.update;
+
+import com.intellij.openapi.components.PersistentStateComponent;
+import com.intellij.openapi.components.State;
+import com.intellij.openapi.components.Storage;
+import com.intellij.openapi.components.StoragePathMacros;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+@State(
+ name = "HgUpdateConfigurationSettings",
+ storages = @Storage(file = StoragePathMacros.WORKSPACE_FILE)
+)
+public class HgUpdateConfigurationSettings implements PersistentStateComponent<HgUpdateConfigurationSettings.State> {
+
+
+ private State myState = new State();
+
+ public static class State {
+ public boolean shouldPull = true;
+ @NotNull public HgUpdateType updateType = HgUpdateType.ONLY_UPDATE;
+ public boolean shouldCommitAfterMerge = false;
+ }
+
+ public void setShouldPull(boolean shouldPull) {
+ myState.shouldPull = shouldPull;
+ }
+
+ public void setUpdateType(@NotNull HgUpdateType updateType) {
+ myState.updateType = updateType;
+ }
+
+ public void setShouldCommitAfterMerge(boolean shouldCommitAfterMerge) {
+ myState.shouldCommitAfterMerge = shouldCommitAfterMerge;
+ }
+
+ public boolean shouldPull() {
+ return myState.shouldPull;
+ }
+
+ public HgUpdateType getUpdateType() {
+ return myState.updateType;
+ }
+
+ public boolean shouldCommitAfterMerge() {
+ return myState.updateType == HgUpdateType.MERGE && myState.shouldCommitAfterMerge;
+ }
+
+ @Nullable
+ @Override
+ public HgUpdateConfigurationSettings.State getState() {
+ return myState;
+ }
+
+ @Override
+ public void loadState(HgUpdateConfigurationSettings.State state) {
+ myState = state;
+ }
+}
\ No newline at end of file
// limitations under the License.
package org.zmlx.hg4idea.provider.update;
+import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.progress.ProgressIndicator;
public class HgUpdateEnvironment implements UpdateEnvironment {
private final Project project;
- private final HgUpdater.UpdateConfiguration updateConfiguration = new HgUpdater.UpdateConfiguration();
+ private final HgUpdateConfigurationSettings updateConfiguration;
public HgUpdateEnvironment(Project project) {
this.project = project;
+ updateConfiguration = ServiceManager.getService(project, HgUpdateConfigurationSettings.class);
}
public void fillGroups(UpdatedFiles updatedFiles) {
}
public static class UpdateConfigurable implements Configurable {
- private final HgUpdater.UpdateConfiguration updateConfiguration;
+ private final HgUpdateConfigurationSettings updateConfiguration;
protected HgUpdateDialog updateDialog;
- public UpdateConfigurable(HgUpdater.UpdateConfiguration updateConfiguration) {
+ public UpdateConfigurable(HgUpdateConfigurationSettings updateConfiguration) {
this.updateConfiguration = updateConfiguration;
}
}
public JComponent createComponent() {
- updateDialog = new HgUpdateDialog();
- return updateDialog.createCenterPanel();
+ updateDialog = new HgUpdateDialog(updateConfiguration);
+ return updateDialog.getContentPanel();
}
public boolean isModified() {
--- /dev/null
+/*
+ * 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.zmlx.hg4idea.provider.update;
+
+/**
+ * The type of update to perform
+ */
+public enum HgUpdateType {
+
+
+ /**
+ * Try to update without merge, fails if conflicts
+ */
+ ONLY_UPDATE,
+ /**
+ * Merge commits with pulled
+ */
+ MERGE,
+ /**
+ * Rebase local commits
+ */
+ REBASE
+}
\ No newline at end of file
boolean update(UpdatedFiles updatedFiles, ProgressIndicator indicator, List<VcsException> exceptions)
throws VcsException;
-
- class UpdateConfiguration{
- private boolean shouldMerge = true;
- private boolean shouldCommitAfterMerge = true;
- private boolean shouldRebase = false;
-
-
- public void setShouldMerge(boolean shouldMerge) {
- this.shouldMerge = shouldMerge;
- }
-
- public void setShouldCommitAfterMerge(boolean shouldCommitAfterMerge) {
- this.shouldCommitAfterMerge = shouldCommitAfterMerge;
- }
-
- public void setShouldRebase(boolean shouldRebase) {
- this.shouldRebase = shouldRebase;
- }
-
- public boolean shouldRebase() {
- return shouldRebase;
- }
-
- public boolean shouldMerge() {
- return shouldMerge;
- }
-
- public boolean shouldCommitAfterMerge() {
- return shouldMerge() && shouldCommitAfterMerge;
- }
- }
}
package org.zmlx.hg4idea.ui;
import com.intellij.ui.IdeBorderFactory;
+import com.intellij.ui.components.JBCheckBox;
import net.miginfocom.swing.MigLayout;
-import org.zmlx.hg4idea.provider.update.HgUpdater;
+import org.jetbrains.annotations.NotNull;
+import org.zmlx.hg4idea.provider.update.HgUpdateConfigurationSettings;
+import org.zmlx.hg4idea.provider.update.HgUpdateType;
import javax.swing.*;
import java.awt.event.ItemEvent;
* Configuration dialog for the update process.
*/
public class HgUpdateDialog {
+
+ private JComponent myContentPanel;
+ private JCheckBox myPullCheckBox;
private JCheckBox myCommitAfterMergeCheckBox;
+ private JRadioButton myOnlyUpdateButton;
private JRadioButton myMergeRadioButton;
private JRadioButton myRebaseRadioButton;
- public HgUpdateDialog() {
- createCenterPanel();
+ public HgUpdateDialog(@NotNull HgUpdateConfigurationSettings updateSettings) {
+ myContentPanel = createCenterPanel(updateSettings);
+ }
+
+ public JComponent getContentPanel() {
+ return myContentPanel;
}
private void updateEnabledStates() {
myCommitAfterMergeCheckBox.setEnabled(myMergeRadioButton.isSelected());
}
- public void applyTo(HgUpdater.UpdateConfiguration updateConfiguration) {
- updateConfiguration.setShouldMerge(myMergeRadioButton.isSelected());
+ public void applyTo(HgUpdateConfigurationSettings updateConfiguration) {
+ updateConfiguration.setShouldPull(myPullCheckBox.isSelected());
+ if (myOnlyUpdateButton.isSelected()) {
+ updateConfiguration.setUpdateType(HgUpdateType.ONLY_UPDATE);
+ }
+ if (myMergeRadioButton.isSelected()) {
+ updateConfiguration.setUpdateType(HgUpdateType.MERGE);
+ }
+ if (myRebaseRadioButton.isSelected()) {
+ updateConfiguration.setUpdateType(HgUpdateType.REBASE);
+ }
updateConfiguration.setShouldCommitAfterMerge(myCommitAfterMergeCheckBox.isSelected());
- updateConfiguration.setShouldRebase(myRebaseRadioButton.isSelected());
}
- public JComponent createCenterPanel() {
+ public JComponent createCenterPanel(HgUpdateConfigurationSettings updateSettings) {
MigLayout migLayout = new MigLayout("flowy,ins 0, fill");
JPanel contentPane = new JPanel(migLayout);
+ myPullCheckBox = new JBCheckBox("Pull", true);
+ myPullCheckBox.setMnemonic('p');
+ myPullCheckBox.setToolTipText("Pull from the default remote repository");
+ myPullCheckBox.setSelected(updateSettings.shouldPull());
+ myOnlyUpdateButton = new JRadioButton("Only Update", true);
+ myOnlyUpdateButton.setMnemonic('u');
+ myOnlyUpdateButton.setToolTipText("Update to the head of the current branch");
- contentPane.setBorder(IdeBorderFactory.createTitledBorder("Update Type"));
-
- myMergeRadioButton = new JRadioButton("Merge", true);
+ myMergeRadioButton = new JRadioButton("Merge", false);
myMergeRadioButton.setMnemonic('m');
myMergeRadioButton.setToolTipText("Merge if pulling resulted in extra heads");
+ myMergeRadioButton.addItemListener(new ItemListener() {
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ updateEnabledStates();
+ }
+ });
+
myCommitAfterMergeCheckBox = new JCheckBox("Commit after merge without conflicts", false);
myCommitAfterMergeCheckBox.setMnemonic('c');
myCommitAfterMergeCheckBox.setToolTipText("Commit automatically after the merge");
+ myCommitAfterMergeCheckBox.setSelected(updateSettings.shouldCommitAfterMerge());
+
myRebaseRadioButton = new JRadioButton("Rebase", false);
myRebaseRadioButton.setToolTipText("Rebase changesets to a branch tip as destination");
myRebaseRadioButton.setMnemonic('r');
- final ButtonGroup radioButtonGroup = new ButtonGroup();
- radioButtonGroup.add(myMergeRadioButton);
- radioButtonGroup.add(myRebaseRadioButton);
- contentPane.add(myMergeRadioButton, "left");
- contentPane.add(myCommitAfterMergeCheckBox, "gapx 5%");
- contentPane.add(myRebaseRadioButton, "left");
- myMergeRadioButton.addItemListener(new ItemListener() {
- public void itemStateChanged(ItemEvent e) {
- updateEnabledStates();
- }
- });
+ contentPane.add(myPullCheckBox, "left");
+ JPanel strategyPanel = new JPanel(migLayout);
+ strategyPanel.setBorder(IdeBorderFactory.createTitledBorder("Update Strategy"));
+ strategyPanel.add(myOnlyUpdateButton, "left");
+ strategyPanel.add(myMergeRadioButton, "left");
+ strategyPanel.add(myCommitAfterMergeCheckBox, "gapx 5%");
+ strategyPanel.add(myRebaseRadioButton, "left");
+ contentPane.add(strategyPanel);
+ ButtonGroup group = new ButtonGroup();
+ group.add(myOnlyUpdateButton);
+ group.add(myRebaseRadioButton);
+ group.add(myMergeRadioButton);
updateEnabledStates();
return contentPane;
}
- public void updateFrom(HgUpdater.UpdateConfiguration updateConfiguration) {
- myMergeRadioButton.setSelected(updateConfiguration.shouldMerge());
+ public void updateFrom(@NotNull HgUpdateConfigurationSettings updateConfiguration) {
+ myPullCheckBox.setSelected(updateConfiguration.shouldPull());
+ HgUpdateType updateType = updateConfiguration.getUpdateType();
+ switch (updateType) {
+ case ONLY_UPDATE:
+ myOnlyUpdateButton.setSelected(true);
+ break;
+ case MERGE:
+ myMergeRadioButton.setSelected(true);
+ break;
+ case REBASE:
+ myRebaseRadioButton.setSelected(true);
+ break;
+ default:
+ assert false : "Unknown value of update type: " + updateType;
+ }
myCommitAfterMergeCheckBox.setSelected(updateConfiguration.shouldCommitAfterMerge());
- myRebaseRadioButton.setSelected(updateConfiguration.shouldRebase());
}
}
import org.zmlx.hg4idea.HgRevisionNumber;
import org.zmlx.hg4idea.command.*;
import org.zmlx.hg4idea.provider.update.HgRegularUpdater;
+import org.zmlx.hg4idea.provider.update.HgUpdateConfigurationSettings;
import org.zmlx.hg4idea.util.HgUtil;
import java.io.File;
}
private List<VcsException> updateThroughPlugin() throws VcsException {
- HgRegularUpdater updater = new HgRegularUpdater(myProject, projectRepoVirtualFile, new org.zmlx.hg4idea.provider.update.HgUpdater.UpdateConfiguration());
+ HgRegularUpdater updater = new HgRegularUpdater(myProject, projectRepoVirtualFile, new HgUpdateConfigurationSettings());
UpdatedFiles updatedFiles = UpdatedFiles.create();
EmptyProgressIndicator indicator = new EmptyProgressIndicator();
ArrayList<VcsException> nonFatalWarnings = new ArrayList<VcsException>();
import com.intellij.execution.configurations.ModuleBasedConfiguration;
import com.intellij.execution.junit2.info.MethodLocation;
import com.intellij.execution.testframework.AbstractTestProxy;
+import com.intellij.execution.testframework.TestTreeView;
+import com.intellij.execution.testframework.TestsUIUtil;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
+import com.intellij.util.ui.Tree;
+import javax.swing.*;
+import javax.swing.tree.TreePath;
+import java.awt.*;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
}
public static boolean isMultipleElementsSelected(ConfigurationContext context) {
- if (AbstractTestProxy.DATA_KEY.getData(context.getDataContext()) != null) return false;
+ if (TestsUIUtil.isMultipleSelectionImpossible(context.getDataContext())) return false;
final LinkedHashSet<String> classes = new LinkedHashSet<String>();
final PsiElement[] elements = collectPatternElements(context, classes);
if (elements != null && collectTestMembers(elements, false).size() > 1) {
import com.intellij.execution.junit.JUnitUtil;
import com.intellij.execution.junit2.info.MethodLocation;
import com.intellij.execution.testframework.AbstractTestProxy;
+import com.intellij.execution.testframework.TestsUIUtil;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
}
public static boolean isMultipleElementsSelected(ConfigurationContext context) {
- if (AbstractTestProxy.DATA_KEY.getData(context.getDataContext()) != null) return false;
+ if (TestsUIUtil.isMultipleSelectionImpossible(context.getDataContext())) return false;
final LinkedHashSet<String> classes = new LinkedHashSet<String>();
final PsiElement[] elements = collectPatternElements(context, classes);
if (elements != null && collectTestMembers(elements).size() > 1) {
}
final String filterSuffix = ((IdentifierToken)token).getText();
- if (!ZenCodingUtil.checkFilterSuffix(filterSuffix)) {
- return null;
+ if (ZenCodingUtil.checkFilterSuffix(filterSuffix)) {
+ result = new FilterNode(result, filterSuffix);
}
advance();
- result = new FilterNode(result, filterSuffix);
}
}
});
field.addKeyboardListener(new KeyAdapter() {
@Override
- public void keyPressed(KeyEvent e) {
+ public void keyPressed(@NotNull KeyEvent e) {
if (!field.isPopupVisible()) {
switch (e.getKeyCode()) {
case KeyEvent.VK_ENTER:
}
}).isEmpty();
+ CompletionResultSet resultSet = result.withPrefixMatcher(result.getPrefixMatcher().cloneWithPrefix(templatePrefix));
+ resultSet.restartCompletionOnPrefixChange(StandardPatterns.string().startsWith(templatePrefix));
if (!regularTemplateWithSamePrefixExists) {
// exclude perfect matches with existing templates because LiveTemplateCompletionContributor handles it
final Collection<SingleLineEmmetFilter> extraFilters = ContainerUtil.newLinkedList(new SingleLineEmmetFilter());
template.setKey(templatePrefix);
template.setDescription(template.getTemplateText());
- CompletionResultSet resultSet = result.withPrefixMatcher(result.getPrefixMatcher().cloneWithPrefix(templatePrefix));
- resultSet.restartCompletionOnPrefixChange(StandardPatterns.string().startsWith(templatePrefix));
- resultSet.addElement(new CustomLiveTemplateLookupElement(this, template.getKey(), template.getKey(), template.getDescription(), true, true));
+ resultSet.addElement(new CustomLiveTemplateLookupElement(this, template.getKey(), template.getKey(), template.getDescription(),
+ !LiveTemplateCompletionContributor.shouldShowAllTemplates(), true));
}
}
}