Merge remote-tracking branch 'origin/master'

This commit is contained in:
Roman Shevchenko
2015-10-08 18:05:05 +02:00
73 changed files with 990 additions and 354 deletions
+9 -13
View File
@@ -8,9 +8,7 @@
message()
{
TITLE="Cannot start @@product_full@@"
if [ -t 1 ]; then
echo "ERROR: $TITLE\n$1"
elif [ -n `which zenity` ]; then
if [ -n `which zenity` ]; then
zenity --error --title="$TITLE" --text="$1"
elif [ -n `which kdialog` ]; then
kdialog --error --title "$TITLE" "$1"
@@ -35,13 +33,6 @@ RM=`which rm`
CAT=`which cat`
TR=`which tr`
#Disbale Jayatana on linux
if [ -n "$JAVA_TOOL_OPTIONS" -a "$JAVA_TOOL_OPTIONS" != "${JAVA_TOOL_OPTIONS%-javaagent*jayatanaag.jar*"}" ] ; then
JAVA_TOOL_OPTIONS=${JAVA_TOOL_OPTIONS%-javaagent*jayatanaag.jar*}${JAVA_TOOL_OPTIONS#*jayatanaag.jar};
message "Jayatana global menu integration is disabled.";
fi
if [ -z "$UNAME" -o -z "$GREP" -o -z "$CUT" -o -z "$MKTEMP" -o -z "$RM" -o -z "$CAT" -o -z "$TR" ]; then
message "Required tools are missing - check beginning of \"$0\" file for details."
exit 1
@@ -125,7 +116,7 @@ if [ -z "$JDK" ] || [ ! -x "$JAVA_BIN" ]; then
fi
VERSION_LOG=`"$MKTEMP" -t java.version.log.XXXXXX`
"$JAVA_BIN" -version 2> "$VERSION_LOG"
JAVA_TOOL_OPTIONS= "$JAVA_BIN" -version 2> "$VERSION_LOG"
"$GREP" "64-Bit|x86_64|amd64" "$VERSION_LOG" > /dev/null
BITS=$?
"$RM" -f "$VERSION_LOG"
@@ -162,8 +153,8 @@ fi
VM_OPTIONS=""
if [ -r "$vm_options_file" ]; then
VM_OPTIONS_DATA=`"$CAT" "$vm_options_file" | "$GREP" -v "^#.*" | "$TR" '\n' ' '`
VM_OPTIONS="$VM_OPTIONS $VM_OPTIONS_DATA"
VM_OPTIONS_DATA=`"$CAT" "$vm_options_file" | "$GREP" -v "^#.*" | "$TR" '\n' ' '`
VM_OPTIONS="$VM_OPTIONS $VM_OPTIONS_DATA"
else
message "Cannot find VM options file."
fi
@@ -184,6 +175,11 @@ if [ -n "$@@product_uc@@_CLASSPATH" ]; then
CLASSPATH="$CLASSPATH:$@@product_uc@@_CLASSPATH"
fi
if [ -n "$JAVA_TOOL_OPTIONS" -a "$JAVA_TOOL_OPTIONS" != "${JAVA_TOOL_OPTIONS%-javaagent*jayatanaag.jar*}" ] ; then
export _ORIGINAL_JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS"
JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS%-javaagent*jayatanaag.jar*}${JAVA_TOOL_OPTIONS#*jayatanaag.jar}"
fi
# ---------------------------------------------------------------------
# Run the IDE.
# ---------------------------------------------------------------------
@@ -286,7 +286,7 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project);
if (forceIgnoreTypeCast) {
return (PsiExpression)javaCodeStyleManager.shortenClassReferences(elementFactory.createExpressionFromText(withoutTypesDeclared, lambdaExpression));
return (PsiExpression)javaCodeStyleManager.shortenClassReferences(lambdaExpression);
}
PsiTypeCastExpression typeCast = (PsiTypeCastExpression)elementFactory
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInspection;
import com.intellij.codeInsight.CodeInsightUtil;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -177,6 +178,8 @@ public class CollectionAddAllCanBeReplacedWithConstructorInspection extends Base
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiMethodCallExpression methodCallExpression = myMethodCallExpression.getElement();
LOG.assertTrue(methodCallExpression != null);
if (!CodeInsightUtil.preparePsiElementsForWrite(methodCallExpression.getContainingFile())) return;
final PsiElement parameter = methodCallExpression.getArgumentList().getExpressions()[0].copy();
final PsiNewExpression element = myAssignmentExpression.getElement();
LOG.assertTrue(element != null);
@@ -33,7 +33,7 @@ import java.util.*;
/**
* @author Dmitry Batkovich
*/
class PseudoLambdaReplaceTemplate {
public class PseudoLambdaReplaceTemplate {
private final static Logger LOG = Logger.getInstance(PseudoLambdaReplaceTemplate.class);
public enum LambdaRole {
@@ -512,7 +512,7 @@ class PseudoLambdaReplaceTemplate {
return expression;
}
private static String createPipelineHeadText(PsiExpression collectionExpression, boolean force) {
public static PsiExpression replaceTypeParameters(PsiExpression collectionExpression) {
if (collectionExpression instanceof PsiNewExpression) {
final PsiDiamondType.DiamondInferenceResult diamondResolveResult =
PsiDiamondTypeImpl.resolveInferredTypesNoCheck((PsiNewExpression)collectionExpression, collectionExpression);
@@ -528,12 +528,16 @@ class PseudoLambdaReplaceTemplate {
final PsiExpression copiedExpression = (PsiExpression) collectionExpression.copy();
final PsiType newType = copiedExpression.getType();
if (!currentType.equals(newType)) {
collectionExpression = AddTypeArgumentsFix.addTypeArguments(copiedExpression, currentType);
if (collectionExpression == null) {
return null;
}
final PsiExpression newExpression = AddTypeArgumentsFix.addTypeArguments(copiedExpression, currentType);
return newExpression == null ? collectionExpression : newExpression;
}
}
return collectionExpression;
}
private static String createPipelineHeadText(PsiExpression collectionExpression, boolean force) {
collectionExpression = replaceTypeParameters(collectionExpression);
if (collectionExpression == null) return null;
final PsiType type = collectionExpression.getType();
if (type instanceof PsiClassType) {
final PsiClass resolved = ((PsiClassType)type).resolve();
@@ -31,8 +31,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class JavaSourceFilterScope extends DelegatingGlobalSearchScope {
private static final Logger LOG = Logger.getInstance(JavaSourceFilterScope.class);
@Nullable
private final ProjectFileIndex myIndex;
@@ -45,7 +43,6 @@ public class JavaSourceFilterScope extends DelegatingGlobalSearchScope {
}
else {
myIndex = null;
LOG.error("delegate.getProject() == null, delegate.getClass() == " + delegate.getClass());
}
}
@@ -135,6 +135,10 @@ public class AppMain {
System.err.println("main method should be static");
return;
}
if (!Void.class.isInstance(m.getReturnType())) {
System.err.println("main method must return a value of type void");
return;
}
try {
ensureAccess(m);
m.invoke(null, new Object[]{parms});
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,8 +20,8 @@
*/
package com.intellij.codeInsight.daemon.quickFix;
import com.intellij.codeInsight.daemon.impl.DefaultHighlightVisitorBasedInspection;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.DefaultHighlightVisitorBasedInspection;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.ide.highlighter.JavaHighlightingColors;
@@ -31,7 +31,6 @@ import com.intellij.lang.annotation.Annotation;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
@@ -21,7 +21,6 @@ package com.intellij.psi;
import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase;
import com.intellij.codeInsight.daemon.impl.DaemonProgressIndicator;
import com.intellij.codeInsight.daemon.impl.DefaultHighlightVisitor;
import com.intellij.codeInsight.daemon.impl.HighlightVisitor;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder;
import com.intellij.openapi.application.ApplicationManager;
@@ -29,6 +28,7 @@ import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.pom.java.LanguageLevel;
@@ -163,8 +163,10 @@ public class PsiConcurrencyStressTest extends DaemonAnalyzerTestCase {
super.visitElement(element);
final HighlightInfoHolder infoHolder = new HighlightInfoHolder(myFile);
final HighlightVisitor visitor = new DefaultHighlightVisitor(getProject());
visitor.analyze(myFile, true, infoHolder, () -> visitor.visit(element));
for (HighlightVisitor visitor : Extensions.getExtensions(HighlightVisitor.EP_HIGHLIGHT_VISITOR, getProject())) {
HighlightVisitor v = visitor.clone(); // to avoid race for com.intellij.codeInsight.daemon.impl.DefaultHighlightVisitor.myAnnotationHolder
v.analyze(myFile, true, infoHolder, () -> v.visit(element));
}
}
});
break;
@@ -110,6 +110,14 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool {
final PsiMethodCallExpression chain = findGuavaMethodChain(expression);
final PsiElement maybeLocalVariable = chain.getParent();
if (maybeLocalVariable instanceof PsiLocalVariable) {
final PsiClass aClass = PsiUtil.resolveClassInType(chain.getType());
if (aClass != null && GuavaFluentIterableConversionRule.FLUENT_ITERABLE.equals(aClass.getQualifiedName())) {
return;
}
}
PsiClassType initialType = (PsiClassType)expression.getType();
LOG.assertTrue(initialType != null);
PsiClass resolvedClass = initialType.resolve();
@@ -26,6 +26,8 @@ import com.intellij.util.containers.hash.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
/**
@@ -93,12 +95,6 @@ public abstract class BaseGuavaTypeConversionRule extends TypeConversionRule {
}
private boolean canConvert(PsiType from, PsiType to) {
if (from instanceof PsiEllipsisType) {
from = ((PsiEllipsisType)from).getComponentType();
}
if (to instanceof PsiEllipsisType) {
to = ((PsiEllipsisType)to).getComponentType();
}
if (!(from instanceof PsiClassType)) {
return false;
}
@@ -0,0 +1,161 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.refactoring.typeMigration.rules.guava;
import com.intellij.codeInspection.AnonymousCanBeLambdaInspection;
import com.intellij.codeInspection.java18StreamApi.StreamApiConstants;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
import com.intellij.util.SmartList;
import com.siyeh.ipp.types.ReplaceMethodRefWithLambdaIntention;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* @author Dmitry Batkovich
*/
public class FluentIterableConversionUtil {
private final static Logger LOG = Logger.getInstance(FluentIterableConversionUtil.class);
@Nullable
static TypeConversionDescriptor getFilterDescriptor(PsiMethod method) {
LOG.assertTrue("filter".equals(method.getName()));
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length != 1) return null;
final PsiParameter parameter = parameters[0];
final PsiType type = parameter.getType();
if (!(type instanceof PsiClassType)) return null;
final PsiClass resolvedClass = ((PsiClassType)type).resolve();
if (resolvedClass == null) return null;
if (CommonClassNames.JAVA_LANG_CLASS.equals(resolvedClass.getQualifiedName())) {
return new GuavaFilterInstanceOfConversionDescriptor();
}
else if (GuavaPredicateConversionRule.GUAVA_PREDICATE.equals(resolvedClass.getQualifiedName())) {
return new LambdaParametersTypeConversionDescriptor("$it$.filter($p$)", "$it$." + StreamApiConstants.FILTER + "($p$)");
}
return null;
}
static class TransformAndConcatConversionRule extends LambdaParametersTypeConversionDescriptor {
public TransformAndConcatConversionRule() {
super("$q$.transformAndConcat($params$)", "$q$.flatMap($params$)");
}
@Override
public PsiExpression replace(PsiExpression expression) {
PsiExpression argument = ((PsiMethodCallExpression)expression).getArgumentList().getExpressions()[0];
PsiAnonymousClass anonymousClass;
if (argument instanceof PsiNewExpression &&
(anonymousClass = ((PsiNewExpression)argument).getAnonymousClass()) != null) {
if (AnonymousCanBeLambdaInspection.canBeConvertedToLambda(anonymousClass, true)) {
argument = AnonymousCanBeLambdaInspection.replacePsiElementWithLambda(argument, true, true);
};
}
final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(expression.getProject());
if (argument != null && !(argument instanceof PsiFunctionalExpression)) {
argument =
(PsiExpression)argument.replace(javaPsiFacade.getElementFactory().createExpressionFromText("(" + argument.getText() + ")::apply", null));
}
if (argument instanceof PsiMethodReferenceExpression) {
argument = ReplaceMethodRefWithLambdaIntention.convertMethodReferenceToLambda((PsiMethodReferenceExpression)argument);
}
if (argument instanceof PsiLambdaExpression) {
List<Pair<PsiExpression, Boolean>> iterableReturnValues = new SmartList<Pair<PsiExpression, Boolean>>();
final PsiElement body = ((PsiLambdaExpression)argument).getBody();
final PsiClass collection = javaPsiFacade.findClass(CommonClassNames.JAVA_UTIL_COLLECTION, expression.getResolveScope());
if (collection == null) return expression;
final PsiClass iterable = javaPsiFacade.findClass(CommonClassNames.JAVA_LANG_ITERABLE, expression.getResolveScope());
if (iterable == null) return expression;
if (body instanceof PsiCodeBlock) {
for (PsiReturnStatement statement : PsiTreeUtil
.findChildrenOfType(body, PsiReturnStatement.class)) {
final PsiExpression retValue = statement.getReturnValue();
if (!determineType(retValue, iterableReturnValues, iterable, collection)) {
return expression;
}
}
} else if (!(body instanceof PsiExpression) || !determineType((PsiExpression)body, iterableReturnValues, iterable, collection)) {
return expression;
}
for (Pair<PsiExpression, Boolean> returnValueAndIsCollection : iterableReturnValues) {
convertToStream(returnValueAndIsCollection.getFirst(), returnValueAndIsCollection.getSecond());
}
} else {
return expression;
}
return super.replace(expression);
}
private static boolean determineType(PsiExpression retValue,
List<Pair<PsiExpression, Boolean>> iterableReturnValues,
PsiClass iterable,
PsiClass collection) {
if (retValue == null) return false;
final PsiType type = retValue.getType();
if (PsiType.NULL.equals(type)) {
return true;
}
if (type instanceof PsiClassType) {
final PsiClass resolvedClass = ((PsiClassType)type).resolve();
if (InheritanceUtil.isInheritorOrSelf(resolvedClass, iterable, true)) {
final boolean isCollection = InheritanceUtil.isInheritorOrSelf(resolvedClass, collection, true);
iterableReturnValues.add(Pair.create(retValue, isCollection));
return true;
}
}
return false;
}
private static void convertToStream(@NotNull PsiExpression returnValue, boolean isCollection) {
String expressionAsText = isCollection
? "(" + returnValue.getText() + ").stream()"
: "java.util.stream.StreamSupport.stream((" + returnValue.getText() + ").spliterator(), false)";
returnValue.replace(JavaPsiFacade.getElementFactory(returnValue.getProject()).createExpressionFromText(expressionAsText, returnValue));
}
}
private static class GuavaFilterInstanceOfConversionDescriptor extends TypeConversionDescriptor {
public GuavaFilterInstanceOfConversionDescriptor() {
super("$it$.filter($p$)", "$it$." + StreamApiConstants.FILTER + "($p$)");
}
@Override
public PsiExpression replace(PsiExpression expression) {
final PsiExpression argument = ((PsiMethodCallExpression)expression).getArgumentList().getExpressions()[0];
final PsiExpression newArgument =
JavaPsiFacade.getElementFactory(expression.getProject()).createExpressionFromText("(" + argument.getText() + ")::isInstance", argument);
argument.replace(newArgument);
return super.replace(expression);
}
}
}
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.typeMigration.rules.guava;
import com.intellij.codeInspection.java18StreamApi.PseudoLambdaReplaceTemplate;
import com.intellij.codeInspection.java18StreamApi.StreamApiConstants;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.psi.*;
@@ -62,7 +63,7 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
}
public TypeConversionDescriptor create() {
return myWithLambdaParameter ? new LambdaParametersTypeConversionDescription(myStringToReplace, myReplaceByString)
return myWithLambdaParameter ? new LambdaParametersTypeConversionDescriptor(myStringToReplace, myReplaceByString)
: new TypeConversionDescriptor(myStringToReplace, myReplaceByString);
}
@@ -74,20 +75,15 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
static {
DESCRIPTORS_MAP.put("contains",
new TypeConversionDescriptorFactory("$it$.contains($o$)", "$it$.anyMatch(e -> e != null && e.equals($o$))", false));
DESCRIPTORS_MAP.put("from", new TypeConversionDescriptorFactory("FluentIterable.from($it$)", "$it$.stream()", false, true));
DESCRIPTORS_MAP.put("isEmpty", new TypeConversionDescriptorFactory("$q$.isEmpty()", "$q$.findAny().isPresent()", false));
DESCRIPTORS_MAP.put("skip", new TypeConversionDescriptorFactory("$q$.skip($p$)", "$q$.skip($p$)", false, true));
DESCRIPTORS_MAP.put("limit", new TypeConversionDescriptorFactory("$q$.limit($p$)", "$q$.limit($p$)", false, true));
DESCRIPTORS_MAP.put("first", new TypeConversionDescriptorFactory("$q$.first()", "$q$.findFirst()", false));
DESCRIPTORS_MAP.put("transform", new TypeConversionDescriptorFactory("$q$.transform($params$)", "$q$.map($params$)", true, true));
//TODO support
//DESCRIPTORS_MAP.put("transformAndConcat", new TransformAndConcatDescriptorBase("$q$.transformAndConcat($params$)", "$q$.flatMap($params$)"));
DESCRIPTORS_MAP.put("allMatch", new TypeConversionDescriptorFactory("$it$.allMatch($c$)", "$it$." + StreamApiConstants.ALL_MATCH + "($c$)", true));
DESCRIPTORS_MAP.put("anyMatch", new TypeConversionDescriptorFactory("$it$.anyMatch($c$)", "$it$." + StreamApiConstants.ANY_MATCH + "($c$)", true));
//TODO add another filter processor
DESCRIPTORS_MAP.put("filter", new TypeConversionDescriptorFactory("$it$.filter($p$)", "$it$." + StreamApiConstants.FILTER + "($p$)", true, true));
DESCRIPTORS_MAP.put("first", new TypeConversionDescriptorFactory("$it$.first()", "$it$." + StreamApiConstants.FIND_FIRST + "()", false));
DESCRIPTORS_MAP.put("firstMatch", new TypeConversionDescriptorFactory("$it$.firstMatch($p$)", "$it$.filter($p$).findFirst()", true));
DESCRIPTORS_MAP.put("get", new TypeConversionDescriptorFactory("$it$.get($p$)", "$it$.collect(java.util.stream.Collectors.toList()).get($p$)", false));
@@ -113,21 +109,52 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
if (context instanceof PsiMethodCallExpression) {
return buildCompoundDescriptor((PsiMethodCallExpression)context, to, labeler);
}
final TypeConversionDescriptorFactory base = DESCRIPTORS_MAP.get(methodName);
if (base != null) {
final TypeConversionDescriptor descriptor = base.create();
if (base.isChainedMethod()) {
descriptor.withConversionType(to);
}
return descriptor;
}
else {
return null;
}
return getOneMethodDescriptor(methodName, method, to, context);
}
@Nullable
private static GuavaChainedConversionDescriptor buildCompoundDescriptor(PsiMethodCallExpression expression,
private TypeConversionDescriptorBase getOneMethodDescriptor(@NotNull String methodName,
@NotNull PsiMethod method,
@Nullable PsiType to,
@Nullable PsiExpression context) {
TypeConversionDescriptor descriptorBase = null;
boolean needSpecifyType = true;
if (methodName.equals("from")) {
descriptorBase = new TypeConversionDescriptor("FluentIterable.from($it$)", "$it$.stream()") {
@Override
public PsiExpression replace(PsiExpression expression) {
PseudoLambdaReplaceTemplate.replaceTypeParameters(((PsiMethodCallExpression) expression).getArgumentList().getExpressions()[0]);
return super.replace(expression);
}
};
} else if (methodName.equals("filter")) {
descriptorBase = FluentIterableConversionUtil.getFilterDescriptor(method);
}
else if (methodName.equals("transformAndConcat")) {
descriptorBase = new FluentIterableConversionUtil.TransformAndConcatConversionRule();
}
else {
final TypeConversionDescriptorFactory base = DESCRIPTORS_MAP.get(methodName);
if (base != null) {
final TypeConversionDescriptor descriptor = base.create();
needSpecifyType = base.isChainedMethod();
descriptorBase = descriptor;
}
}
if (descriptorBase != null) {
if (needSpecifyType && to != null) {
descriptorBase.withConversionType(to);
}
return descriptorBase;
}
return null;
}
@Nullable
private GuavaChainedConversionDescriptor buildCompoundDescriptor(PsiMethodCallExpression expression,
PsiType to,
TypeMigrationLabeler labeler) {
List<TypeConversionDescriptorBase> methodDescriptors = new SmartList<TypeConversionDescriptorBase>();
@@ -156,21 +183,15 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
if (containingClass == null) {
break;
}
TypeConversionDescriptorBase descriptor;
TypeConversionDescriptorBase descriptor = null;
if (FLUENT_ITERABLE.equals(containingClass.getQualifiedName())) {
final TypeConversionDescriptorFactory descriptorFactory = DESCRIPTORS_MAP.get(methodName);
if (descriptorFactory == null) {
return null;
}
descriptor = descriptorFactory.create();
descriptor = getOneMethodDescriptor(methodName, method, null, current);
}
else if (GuavaOptionalConversionRule.GUAVA_OPTIONAL.equals(containingClass.getQualifiedName())) {
descriptor = optionalDescriptor.getValue().findConversion(null, null, method, current.getMethodExpression(), labeler);
if (descriptor == null) {
return null;
}
} else {
break;
}
if (descriptor == null) {
return null;
}
methodDescriptors.add(descriptor);
final PsiExpression qualifier = current.getMethodExpression().getQualifierExpression();
@@ -45,11 +45,7 @@ public class GuavaOptionalConversionRule extends BaseGuavaTypeConversionRule {
if ("or".equals(methodName)) {
PsiMethodCallExpression methodCallExpression = null;
if (context instanceof PsiMethodCallExpression) {
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length != 1) {
return null;
}
final PsiClass aClass = PsiTypesUtil.getPsiClass(parameters[0].getType());
final PsiClass aClass = getParameterClass(method);
if (aClass != null) {
final String qName = aClass.getQualifiedName();
String pattern =
@@ -63,11 +59,7 @@ public class GuavaOptionalConversionRule extends BaseGuavaTypeConversionRule {
if (methodCallExpression == null) {
return null;
}
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length != 1) {
return null;
}
final PsiClass aClass = PsiTypesUtil.getPsiClass(parameters[0].getType());
final PsiClass aClass = getParameterClass(method);
if (aClass != null) {
final String qName = aClass.getQualifiedName();
if (GUAVA_OPTIONAL.equals(qName)) {
@@ -79,13 +71,21 @@ public class GuavaOptionalConversionRule extends BaseGuavaTypeConversionRule {
return descriptor;
}
String pattern = GuavaSupplierConversionRule.GUAVA_SUPPLIER.equals(qName) ? "$val$.orElseGet($other$)" : "$val$.orElse($other$)";
return new LambdaParametersTypeConversionDescription("$val$.or($other$)", pattern);
return new LambdaParametersTypeConversionDescriptor("$val$.or($other$)", pattern);
}
return null;
}
return null;
}
private PsiClass getParameterClass(PsiMethod method) {
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length != 1) {
return null;
}
return PsiTypesUtil.getPsiClass(parameters[0].getType());
}
@Override
protected void fillSimpleDescriptors(Map<String, TypeConversionDescriptorBase> descriptorsMap) {
descriptorsMap.put("absent", new TypeConversionDescriptor("Optional.absent()", "java.util.Optional.empty()") {
@@ -33,6 +33,8 @@ import java.util.Map;
* @author Dmitry Batkovich
*/
public class GuavaPredicateConversionRule extends BaseGuavaTypeConversionRule {
public static final String GUAVA_PREDICATE = "com.google.common.base.Predicate";
@Override
protected void fillSimpleDescriptors(Map<String, TypeConversionDescriptorBase> descriptorsMap) {
descriptorsMap.put("apply", new TypeConversionDescriptor("$q$.apply($o$)", "$q$.test($o$)"));
@@ -41,7 +43,7 @@ public class GuavaPredicateConversionRule extends BaseGuavaTypeConversionRule {
@NotNull
@Override
public String ruleFromClass() {
return "com.google.common.base.Predicate";
return GUAVA_PREDICATE;
}
@NotNull
@@ -24,15 +24,15 @@ import org.jetbrains.annotations.NonNls;
/**
* @author Dmitry Batkovich
*/
public class LambdaParametersTypeConversionDescription extends TypeConversionDescriptor {
private static final Logger LOG = Logger.getInstance(LambdaParametersTypeConversionDescription.class);
public class LambdaParametersTypeConversionDescriptor extends TypeConversionDescriptor {
private static final Logger LOG = Logger.getInstance(LambdaParametersTypeConversionDescriptor.class);
public LambdaParametersTypeConversionDescription(@NonNls String stringToReplace, @NonNls String replaceByString) {
public LambdaParametersTypeConversionDescriptor(@NonNls String stringToReplace, @NonNls String replaceByString) {
super(stringToReplace, replaceByString);
}
@Override
public final PsiExpression replace(PsiExpression expression) {
public PsiExpression replace(PsiExpression expression) {
LOG.assertTrue(expression instanceof PsiMethodCallExpression);
PsiMethodCallExpression methodCall = (PsiMethodCallExpression)expression;
final PsiExpression[] arguments = methodCall.getArgumentList().getExpressions();
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.daemon.impl.quickfix.VariableTypeFix;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.application.PathManager;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.typeMigration.inspections.GuavaInspection;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.PlatformTestUtil;
@@ -26,6 +27,7 @@ import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
import java.io.File;
import java.util.Arrays;
/**
* @author Dmitry Batkovich
@@ -75,6 +77,45 @@ public class GuavaInspectionTest extends JavaCodeInsightFixtureTestCase {
doTest();
}
public void testTransformAndConcat1() {
doTest();
}
public void testTransformAndConcat2() {
doTest();
}
public void testTransformAndConcat3() {
doTest();
}
public void testTransformAndConcat4() {
doTest();
}
public void testFilterIsInstance() {
doTest();
}
public void testInsertTypeParameter() {
doTest();
}
public void testDontShowFluentIterableChainQuickFix() {
doTestNoQuickFixes(GuavaInspection.MigrateFluentIterableChainQuickFix.class);
}
private void doTestNoQuickFixes(final Class<? extends IntentionAction>... quickFixesClasses) {
myFixture.configureByFile(getTestName(true) + ".java");
myFixture.enableInspections(new GuavaInspection());
myFixture.doHighlighting();
for (IntentionAction action : myFixture.getAvailableIntentions()) {
if (PsiTreeUtil.instanceOf(action, quickFixesClasses)) {
fail("Quick fix is found for types " + Arrays.toString(quickFixesClasses));
}
}
}
private void doTest() {
myFixture.configureByFile(getTestName(true) + ".java");
myFixture.enableInspections(new GuavaInspection());
@@ -0,0 +1,10 @@
import com.google.common.collect.FluentIterable;
import java.util.ArrayList;
class A {
void c() {
ArrayList<String> strings = new ArrayList<String>();
FluentIterable<String> it = FluentIte<caret>rable.from(strings).transform(String::trim);
System.out.println(it.size());
}
}
@@ -0,0 +1,12 @@
import com.google.common.collect.FluentIterable;
import java.util.ArrayList;
class A {
void c() {
ArrayList<String> strings = new ArrayList<String>();
FluentIterable<String> i<caret>t = FluentIterable.from(strings);
int i = it.filter(String::isEmpty).filter(String.class).size();
}
}
@@ -0,0 +1,12 @@
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class A {
void c() {
ArrayList<String> strings = new ArrayList<String>();
Stream<String> it = strings.stream();
int i = it.filter(String::isEmpty).filter((String.class)::isInstance).collect(Collectors.toList()).size();
}
}
@@ -0,0 +1,11 @@
import com.google.common.collect.FluentIterable;
import java.util.ArrayList;
import java.util.Collections;
class A {
void c() {
FluentIterable<String> i<caret>t = FluentIterable.from(new ArrayList<>());
int i = it.transformAndConcat(input -> Collections.emptyList()).size();
}
}
@@ -0,0 +1,11 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class A {
void c() {
Stream<String> it = new ArrayList<String>().stream();
int i = it.flatMap(input -> (Collections.emptyList()).stream()).collect(Collectors.toList()).size();
}
}
@@ -0,0 +1,14 @@
import com.google.common.collect.FluentIterable;
import java.util.ArrayList;
import java.util.Collections;
class A {
void c() {
ArrayList<String> strings = new ArrayList<String>();
FluentIterable<String> i<caret>t = FluentIterable.from(strings);
int i = it.transformAndConcat(input -> Collections.emptyList()).size();
}
}
@@ -0,0 +1,14 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class A {
void c() {
ArrayList<String> strings = new ArrayList<String>();
Stream<String> it = strings.stream();
int i = it.flatMap(input -> (Collections.emptyList()).stream()).collect(Collectors.toList()).size();
}
}
@@ -0,0 +1,14 @@
import com.google.common.collect.FluentIterable;
import java.util.ArrayList;
import java.util.Collections;
class A {
void c() {
ArrayList<String> strings = new ArrayList<String>();
FluentIterable<String> i<caret>t = FluentIterable.from(strings);
int i = it.transformAndConcat(Collections::singletonList).size();
}
}
@@ -0,0 +1,14 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class A {
void c() {
ArrayList<String> strings = new ArrayList<String>();
Stream<String> it = strings.stream();
int i = it.flatMap((t) -> (Collections.singletonList(t)).stream()).collect(Collectors.toList()).size();
}
}
@@ -0,0 +1,30 @@
import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
import java.util.ArrayList;
class A {
void c() {
ArrayList<String> strings = new ArrayList<String>();
FluentIterable<String> i<caret>t = FluentIterable.from(strings);
int i = it.transformAndConcat(new Function<String, Iterable<String>>() {
@Override
public Iterable<String> apply(String o) {
if ('a' > 2) {
return getIterable();
} else if ('c' < 123) {
ArrayList<String> strings1 = new ArrayList<>();
strings1.add(o);
return strings1;
}
return null;
}
}).size();
}
Iterable<String> getIterable() {
return null;
}
}
@@ -0,0 +1,27 @@
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
class A {
void c() {
ArrayList<String> strings = new ArrayList<String>();
Stream<String> it = strings.stream();
int i = it.flatMap(o -> {
if ('a' > 2) {
return StreamSupport.stream((getIterable()).spliterator(), false);
} else if ('c' < 123) {
ArrayList<String> strings1 = new ArrayList<>();
strings1.add(o);
return (strings1).stream();
}
return null;
}).collect(Collectors.toList()).size();
}
Iterable<String> getIterable() {
return null;
}
}
@@ -0,0 +1,19 @@
import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
import java.util.ArrayList;
import java.util.List;
class A {
void c() {
ArrayList<String> strings = new ArrayList<String>();
FluentIterable<String> i<caret>t = FluentIterable.from(strings);
int i = it.transformAndConcat(getFunction()).size();
}
Function<String, List<String>> getFunction() {
return null;
}
}
@@ -0,0 +1,20 @@
import com.google.common.base.Function;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class A {
void c() {
ArrayList<String> strings = new ArrayList<String>();
Stream<String> it = strings.stream();
int i = it.flatMap((f) -> ((getFunction()).apply(f)).stream()).collect(Collectors.toList()).size();
}
Function<String, List<String>> getFunction() {
return null;
}
}
@@ -0,0 +1,60 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.daemon.impl;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageAnnotators;
import com.intellij.lang.annotation.Annotator;
import com.intellij.openapi.extensions.ExtensionPointListener;
import com.intellij.openapi.extensions.PluginDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
public class CachedAnnotators {
private final ThreadLocalAnnotatorMap<String, Annotator> cachedAnnotators = new ThreadLocalAnnotatorMap<String, Annotator>() {
@NotNull
@Override
public Collection<Annotator> initialValue(@NotNull String languageId) {
Language language = Language.findLanguageByID(languageId);
return language == null ? ContainerUtil.<Annotator>emptyList() : LanguageAnnotators.INSTANCE.allForLanguage(language);
}
};
public CachedAnnotators(Project project) {
ExtensionPointListener<Annotator> listener = new ExtensionPointListener<Annotator>() {
@Override
public void extensionAdded(@NotNull Annotator extension, @Nullable PluginDescriptor pluginDescriptor) {
cachedAnnotators.clear();
}
@Override
public void extensionRemoved(@NotNull Annotator extension, @Nullable PluginDescriptor pluginDescriptor) {
cachedAnnotators.clear();
}
};
LanguageAnnotators.INSTANCE.addListener(listener, project);
}
@NotNull
List<Annotator> get(@NotNull String languageId) {
return cachedAnnotators.get(languageId);
}
}
@@ -19,14 +19,10 @@ package com.intellij.codeInsight.daemon.impl;
import com.intellij.codeInsight.daemon.impl.analysis.ErrorQuickFixProvider;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder;
import com.intellij.codeInsight.highlighting.HighlightErrorFilter;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageAnnotators;
import com.intellij.lang.LanguageUtil;
import com.intellij.lang.annotation.Annotation;
import com.intellij.lang.annotation.Annotator;
import com.intellij.openapi.extensions.ExtensionPointListener;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.PluginDescriptor;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbService;
@@ -37,17 +33,14 @@ import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
/**
* @author yole
*/
public class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
private AnnotationHolderImpl myAnnotationHolder;
private final HighlightErrorFilter[] myErrorFilters;
@@ -57,15 +50,18 @@ public class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
private final DumbService myDumbService;
private HighlightInfoHolder myHolder;
private final boolean myBatchMode;
private final CachedAnnotators cachedAnnotators;
@SuppressWarnings("UnusedDeclaration")
public DefaultHighlightVisitor(@NotNull Project project) {
this(project, true, true, false);
DefaultHighlightVisitor(@NotNull Project project, @NotNull CachedAnnotators cachedAnnotators) {
this(project, true, true, false, cachedAnnotators);
}
public DefaultHighlightVisitor(@NotNull Project project, boolean highlightErrorElements, boolean runAnnotators, boolean batchMode) {
DefaultHighlightVisitor(@NotNull Project project, boolean highlightErrorElements, boolean runAnnotators, boolean batchMode, @NotNull CachedAnnotators cachedAnnotators) {
myProject = project;
myHighlightErrorElements = highlightErrorElements;
myRunAnnotators = runAnnotators;
this.cachedAnnotators = cachedAnnotators;
myErrorFilters = Extensions.getExtensions(HighlightErrorFilter.EP_NAME, project);
myDumbService = DumbService.getInstance(project);
myBatchMode = batchMode;
@@ -114,7 +110,7 @@ public class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
@Override
@NotNull
public HighlightVisitor clone() {
return new DefaultHighlightVisitor(myProject, myHighlightErrorElements, myRunAnnotators, myBatchMode);
return new DefaultHighlightVisitor(myProject, myHighlightErrorElements, myRunAnnotators, myBatchMode,cachedAnnotators);
}
@Override
@@ -122,29 +118,6 @@ public class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
return 2;
}
private static final ThreadLocalAnnotatorMap<String, Annotator> cachedAnnotators = new ThreadLocalAnnotatorMap<String, Annotator>() {
@NotNull
@Override
public Collection<Annotator> initialValue(@NotNull String languageId) {
Language language = Language.findLanguageByID(languageId);
return language == null ? ContainerUtil.<Annotator>emptyList() : LanguageAnnotators.INSTANCE.allForLanguage(language);
}
};
static {
LanguageAnnotators.INSTANCE.addListener(new ExtensionPointListener<Annotator>() {
@Override
public void extensionAdded(@NotNull Annotator extension, @Nullable PluginDescriptor pluginDescriptor) {
cachedAnnotators.clear();
}
@Override
public void extensionRemoved(@NotNull Annotator extension, @Nullable PluginDescriptor pluginDescriptor) {
cachedAnnotators.clear();
}
});
}
private void runAnnotators(PsiElement element) {
List<Annotator> annotators = cachedAnnotators.get(element.getLanguage().getID());
if (annotators.isEmpty()) return;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,12 +14,13 @@
* limitations under the License.
*/
package com.intellij.codeInspection;
package com.intellij.codeInsight.daemon.impl;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeHighlighting.TextEditorHighlightingPass;
import com.intellij.codeInsight.daemon.impl.*;
import com.intellij.codeInspection.*;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
@@ -174,7 +175,10 @@ public abstract class DefaultHighlightVisitorBasedInspection extends GlobalSimpl
@Override
public HighlightVisitor[] produce() {
gpass.incVisitorUsageCount(1);
return new HighlightVisitor[]{new DefaultHighlightVisitor(project, highlightErrorElements, runAnnotators, true)};
HighlightVisitor visitor = new DefaultHighlightVisitor(project, highlightErrorElements, runAnnotators, true,
ServiceManager.getService(project, CachedAnnotators.class));
return new HighlightVisitor[]{visitor};
}
});
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
package com.intellij.openapi.util;
import com.intellij.diagnostic.PluginException;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.*;
import com.intellij.openapi.progress.ProcessCanceledException;
@@ -230,6 +231,15 @@ public class KeyedExtensionCollector<T, KeyT> {
public void addListener(@NotNull ExtensionPointListener<T> listener) {
myListeners.add(listener);
}
public void addListener(@NotNull final ExtensionPointListener<T> listener, @NotNull Disposable parent) {
myListeners.add(listener);
Disposer.register(parent, new Disposable() {
@Override
public void dispose() {
myListeners.remove(listener);
}
});
}
public void removeListener(@NotNull ExtensionPointListener<T> listener) {
myListeners.remove(listener);
@@ -66,10 +66,12 @@ public class NaturalLanguageTextSelectioner extends ExtendWordSelectionHandlerBa
return new TextRange(prev, next + 1);
}
@Nullable
private static TextRange findSentenceRange(String editorText, int start, int end) {
int sentenceStart = start;
while (sentenceStart > 0) {
if (start - sentenceStart > 1000) return null;
if (isSentenceEnd(editorText, sentenceStart - 1) || !isNatural(editorText.charAt(sentenceStart - 1))) {
break;
}
@@ -83,6 +85,7 @@ public class NaturalLanguageTextSelectioner extends ExtendWordSelectionHandlerBa
while (sentenceEnd < editorText.length()) {
sentenceEnd++;
if (sentenceEnd - end > 1000) return null;
if (isSentenceEnd(editorText, sentenceEnd - 1)) {
break;
}
@@ -145,6 +148,8 @@ public class NaturalLanguageTextSelectioner extends ExtendWordSelectionHandlerBa
int end = selEnd - shift;
TextRange best = findSentenceRange(elementText, start, end);
if (best == null) return null;
best = narrowRange(best, findCustomRange(elementText, start, end, '\"', '\"'));
best = narrowRange(best, findCustomRange(elementText, start, end, '(', ')'));
best = narrowRange(best, findCustomRange(elementText, start, end, '<', '>'));
@@ -15,15 +15,12 @@
*/
package com.intellij.ide.util.projectWizard;
import com.intellij.ide.util.projectWizard.SettingsStep;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.ui.LabeledComponent;
import com.intellij.openapi.util.Pair;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import javax.swing.*;
import java.util.List;
@@ -66,12 +63,12 @@ public class WebProjectSettingsStepWrapper implements SettingsStep {
@Override
public void addExpertPanel(@NotNull JComponent panel) {
throw new NotImplementedException();
throw new UnsupportedOperationException();
}
@Override
public void addExpertField(@NotNull String label, @NotNull JComponent field) {
throw new NotImplementedException();
throw new UnsupportedOperationException();
}
@Override
@@ -21,14 +21,19 @@ import com.intellij.internal.statistic.beans.GroupDescriptor;
import com.intellij.internal.statistic.beans.UsageDescriptor;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.FileTypeIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.NotNullFunction;
import com.intellij.util.ThreeState;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.indexing.FileBasedIndex;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.FilenameFilter;
import java.util.HashSet;
import java.util.Set;
@@ -58,8 +63,7 @@ public class FileTypeUsagesCollector extends AbstractApplicationUsagesCollector
if (project.isDisposed()) {
throw new CollectUsagesException("Project is disposed");
}
VirtualFile ideaDir = project.getBaseDir().findChild(Project.DIRECTORY_STORE_FOLDER);
final String ideaDirPath = ideaDir == null ? null : ideaDir.getPath();
final String ideaDirPath = getIdeaDirPath(project.getBasePath());
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
@@ -71,7 +75,7 @@ public class FileTypeUsagesCollector extends AbstractApplicationUsagesCollector
@Override
public boolean process(VirtualFile file, Void value) {
//skip files from .idea directory otherwise 99% of projects would have XML and PLAIN_TEXT file types
if (ideaDirPath == null || !file.getPath().startsWith(ideaDirPath)) {
if (ideaDirPath == null || FileUtil.isAncestorThreeState(ideaDirPath, file.getPath(), true) == ThreeState.NO) {
usedFileTypes.add(fileType);
return false;
}
@@ -89,4 +93,21 @@ public class FileTypeUsagesCollector extends AbstractApplicationUsagesCollector
}
});
}
@Nullable
private static String getIdeaDirPath(@Nullable String projectPath) {
if (projectPath != null) {
File projectDir = new File(projectPath);
File[] ideaDirs = projectDir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return Project.DIRECTORY_STORE_FOLDER.equals(name);
}
});
if (ideaDirs.length == 1) {
return ideaDirs[0].getPath();
}
}
return null;
}
}
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.EnvironmentUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -79,7 +80,7 @@ public class PathEnvironmentVariableUtil {
@Nullable
private static File findInPath(@NotNull String fileBaseName, boolean logDetails, @Nullable FileFilter filter) {
List<File> exeFiles = findExeFilesInPath(fileBaseName, true, logDetails, filter);
return exeFiles.size() > 0 ? exeFiles.get(0) : null;
return ContainerUtil.getFirstItem(exeFiles);
}
/**
@@ -91,15 +92,9 @@ public class PathEnvironmentVariableUtil {
* @return {@link File} instance or null if not found
*/
private static File findInOriginalPath(@NotNull String fileBaseName) {
String originalPath;
if (SystemInfo.isMac) {
originalPath = System.getenv(PATH_ENV_VAR_NAME);
}
else {
originalPath = EnvironmentUtil.getValue(PATH_ENV_VAR_NAME);
}
String originalPath = System.getenv(PATH_ENV_VAR_NAME);
List<File> exeFiles = doFindExeFilesInPath(originalPath, fileBaseName, true, false, null);
return exeFiles.size() > 0 ? exeFiles.get(0) : null;
return ContainerUtil.getFirstItem(exeFiles);
}
/**
@@ -165,17 +160,34 @@ public class PathEnvironmentVariableUtil {
}
/**
* Finds the absolute path of an executable file in PATH by the given relative path.
* This method makes sense for Mac only, because other OSs pass correct environment variables to IDE process
* letting {@link ProcessBuilder#start} sees correct PATH environment variable.
* Alters the passed in exe path to increase probability of exe file success finding when
* spawning an external process. Modifications are performed iff the passed in exe path is
* a basename (i.e. it doesn't contain slashes). E.g. "java", "git" or "node".
* <p>
* The motivation behind this modification is as follows. When exe path is a basename,
* {@link ProcessBuilder#start} searches for the executable file in the original PATH
* environment variable (i.e. {@code System.getenv("PATH")}).
* The problem is that on MacOSX original PATH value can be different than the PATH
* value in Terminal (see {@link EnvironmentUtil#getEnvironmentMap()}.
*
* @param exePath String relative path (or just a base name)
* @return the absolute path if the executable file found, and the given {@code exePath} otherwise
* @param exePath String path to exe file (basename, relative path or absolute path)
* @return if an exe file can be found in {@code EnvironmentUtil.getValue("PATH")} and
* nothing found in original PATH (i.e. {@code System.getenv("PATH")}),
* return the found exe file absolute path.
* Otherwise, return the passed in exe path.
*/
@NotNull
public static String toLocatableExePath(@NotNull String exePath) {
//noinspection deprecation
return findAbsolutePathOnMac(exePath);
}
/**
* @deprecated use {@link #toLocatableExePath(String)} instead
*/
public static String findAbsolutePathOnMac(@NotNull String exePath) {
if (SystemInfo.isMac) {
if (!exePath.contains(File.separator)) {
if (!StringUtil.containsChar(exePath, '/') && !StringUtil.containsChar(exePath, '\\')) {
File originalResolvedExeFile = findInOriginalPath(exePath);
// don't modify exePath if the absolute path can be found in the original PATH
if (originalResolvedExeFile == null) {
@@ -16,7 +16,10 @@
package com.intellij.ui;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonShortcuts;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.actionSystem.ShortcutSet;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.util.Couple;
@@ -354,7 +357,7 @@ public class ScrollingUtil {
UIUtil.maybeInstall(map, MOVE_END_ID, KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
}
public static abstract class ListScrollAction extends AnAction {
public static abstract class ListScrollAction extends DumbAwareAction {
protected ListScrollAction(final ShortcutSet shortcutSet, final JComponent component) {
registerCustomShortcutSet(shortcutSet, component);
}
@@ -69,6 +69,7 @@ public class SystemHealthMonitor extends ApplicationComponent.Adapter {
public void initComponent() {
checkJvm();
checkIBus();
checkJAyatana();
startDiskSpaceMonitoring();
}
@@ -99,6 +100,16 @@ public class SystemHealthMonitor extends ApplicationComponent.Adapter {
}
}
@SuppressWarnings("SpellCheckingInspection")
private void checkJAyatana() {
if (SystemInfo.isXWindow) {
String originalOpts = System.getenv("_ORIGINAL_JAVA_TOOL_OPTIONS");
if (originalOpts != null && originalOpts.contains("jayatanaag.jar")) {
showNotification("ayatana.menu.warn.message");
}
}
}
private void showNotification(@PropertyKey(resourceBundle = "messages.IdeBundle") String key) {
final String ignoreKey = "ignore." + key;
if (myProperties.isValueSet(ignoreKey)) {
@@ -30,6 +30,7 @@ import javax.swing.event.ChangeListener;
final class ColorBlindnessPanel extends JPanel implements ChangeListener {
private final JCheckBox myCheckBox = new JCheckBox();
private final JComboBox myComboBox = new ComboBox();
private ColorBlindness myBlindness;
public ColorBlindnessPanel() {
super(new HorizontalLayout(JBUI.scale(10)));
@@ -58,6 +59,9 @@ final class ColorBlindnessPanel extends JPanel implements ChangeListener {
public ColorBlindness getColorBlindness() {
if (myCheckBox.isSelected()) {
if (myBlindness != null) {
return myBlindness;
}
Object object = myComboBox.getSelectedItem();
if (object instanceof Item) {
Item item = (Item)object;
@@ -68,8 +72,10 @@ final class ColorBlindnessPanel extends JPanel implements ChangeListener {
}
public void setColorBlindness(ColorBlindness blindness) {
// invisible combobox should not be used to store values
myBlindness = myComboBox.isVisible() ? null : blindness;
Item item = null;
if (blindness != null) {
if (myBlindness == null && blindness != null) {
int count = myComboBox.getItemCount();
for (int i = 0; i < count && item == null; i++) {
Object object = myComboBox.getItemAt(i);
@@ -81,7 +87,7 @@ final class ColorBlindnessPanel extends JPanel implements ChangeListener {
}
}
}
myCheckBox.setSelected(item != null);
myCheckBox.setSelected(myBlindness != null || item != null);
if (item != null) {
myComboBox.setSelectedItem(item);
}
@@ -342,22 +342,16 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border {
if (hasFocus) {
g.clipRect(JBUI.scale(2), JBUI.scale(2), comboBox.getWidth()- JBUI.scale(4), comboBox.getHeight() - JBUI.scale(4));
}
if (editor != null && comboBox.isEditable()) {
((JComponent)editor).setBorder(null);
g.setColor(editor.getBackground());
g.fillRoundRect(x + JBUI.scale(1), y + JBUI.scale(1), W, H, R, R);
g.setColor(getArrowButtonFillColor(arrowButton.getBackground()));
g.fillRoundRect(xxx, y + JBUI.scale(1), width - xxx, H, R, R);
g.setColor(editor.getBackground());
g.fillRect(xxx, y + JBUI.scale(1), JBUI.scale(5), H);
} else {
g.setColor(UIUtil.getPanelBackground());
g.fillRoundRect(x + JBUI.scale(1), y + JBUI.scale(1), W, H, R, R);
g.setColor(getArrowButtonFillColor(arrowButton.getBackground()));
g.fillRoundRect(xxx, y + JBUI.scale(1), width - xxx, H, R, R);
g.setColor(UIUtil.getPanelBackground());
g.fillRect(xxx, y + JBUI.scale(1), JBUI.scale(5), H);
}
final Color background = editor != null && comboBox.isEditable()
? editor.getBackground()
: UIUtil.getPanelBackground();
g.setColor(background);
g.fillRoundRect(x + JBUI.scale(1), y + JBUI.scale(1), W, H, R, R);
g.setColor(getArrowButtonFillColor(arrowButton.getBackground()));
g.fillRoundRect(xxx, y + JBUI.scale(1), width - xxx, H, R, R);
g.setColor(background);
g.fillRect(xxx, y + JBUI.scale(1), JBUI.scale(5), H);
final Color borderColor = getBorderColor();//ColorUtil.shift(UIUtil.getBorderColor(), 4);
g.setColor(getArrowButtonFillColor(borderColor));
int off = hasFocus ? 1 : 0;
@@ -22,6 +22,7 @@ import com.intellij.ide.ui.UISettingsListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.colors.FontPreferences;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import gnu.trove.TIntHashSet;
import org.intellij.lang.annotations.JdkConstants;
import org.jetbrains.annotations.NonNls;
@@ -51,6 +52,16 @@ public class ComplementaryFontsRegistry {
private static final String[] BOLD_ITALIC_NAMES = {"bolditalic", "bold-italic", "bold italic", "boldoblique", "bold-oblique",
"bold oblique", "demibold italic", "negreta cursiva","demi oblique"};
// Explicit mapping fontName->style for cases where generic rules (given above) don't work.
private static final Map<String, Integer> FONT_NAME_TO_STYLE = new HashMap<String, Integer>();
static {
FONT_NAME_TO_STYLE.put("AnkaCoder-b", Font.BOLD);
FONT_NAME_TO_STYLE.put("AnkaCoder-i", Font.ITALIC);
FONT_NAME_TO_STYLE.put("AnkaCoder-bi", Font.BOLD | Font.ITALIC);
FONT_NAME_TO_STYLE.put("SourceCodePro-It", Font.ITALIC);
FONT_NAME_TO_STYLE.put("SourceCodePro-BoldIt", Font.BOLD | Font.ITALIC);
}
static {
final UISettings settings = UISettings.getInstance();
ourOldUseAntialiasing = !AntialiasingType.OFF.equals(settings.EDITOR_AA_TYPE);
@@ -111,7 +122,7 @@ public class ComplementaryFontsRegistry {
if (ApplicationManager.getApplication().isUnitTestMode()) {
ourFontNames.add("Monospaced");
} else {
if (Patches.JDK_MAC_FONT_STYLE_BUG) {
if (Patches.JDK_MAC_FONT_STYLE_DETECTION_WORKAROUND) {
fillStyledFontMap();
}
String[] fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
@@ -128,7 +139,14 @@ public class ComplementaryFontsRegistry {
Font[] allFonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
for (Font font : allFonts) {
String name = font.getName();
int style = getFontStyle(name);
Integer style = null;
if (!SystemInfo.isAppleJvm) {
style = FONT_NAME_TO_STYLE.get(name); // workaround with explicit fontName->style mapping doesn't work on Apple JVM
}
if (style == null) {
if (!Patches.JDK_MAC_FONT_STYLE_BUG) continue;
style = getFontStyle(name);
}
if (style != Font.PLAIN) {
String familyName = font.getFamily();
Pair<String, Integer>[] entry = ourStyledFontMap.get(familyName);
@@ -199,7 +217,7 @@ public class ComplementaryFontsRegistry {
@Nullable
private static FontInfo doGetFontAbleToDisplay(char c, int size, @JdkConstants.FontStyle int style, @NotNull String defaultFontFamily) {
synchronized (lock) {
if (Patches.JDK_MAC_FONT_STYLE_BUG && style > 0 && style < 4) {
if (Patches.JDK_MAC_FONT_STYLE_DETECTION_WORKAROUND && style > 0 && style < 4) {
Pair<String, Integer>[] replacement = ourStyledFontMap.get(defaultFontFamily);
if (replacement != null) {
defaultFontFamily = replacement[style].first;
@@ -203,7 +203,7 @@ public class ActionsTree {
reset(myKeymap, currentQuickListIds, filter, null);
}
private void reset(@NotNull Keymap keymap, @NotNull QuickList[] allQuickLists, String filter, @Nullable KeyboardShortcut shortcut) {
private void reset(@NotNull Keymap keymap, @NotNull QuickList[] allQuickLists, String filter, @Nullable Shortcut shortcut) {
myKeymap = keymap;
final PathsKeeper pathsKeeper = new PathsKeeper();
@@ -228,8 +228,8 @@ public class ActionsTree {
pathsKeeper.restorePaths();
}
public void filterTree(final KeyboardShortcut keyboardShortcut, final QuickList [] currentQuickListIds) {
reset(myKeymap, currentQuickListIds, myFilter, keyboardShortcut);
public void filterTree(Shortcut shortcut, QuickList[] currentQuickListIds) {
reset(myKeymap, currentQuickListIds, myFilter, shortcut);
}
private class MyModel extends DefaultTreeModel implements TreeTableModel {
@@ -34,7 +34,6 @@ import com.intellij.openapi.keymap.ex.KeymapManagerEx;
import com.intellij.openapi.keymap.impl.ActionShortcutRestrictions;
import com.intellij.openapi.keymap.impl.KeymapImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
@@ -528,19 +527,16 @@ public class ActionsTreeUtil {
public static Condition<AnAction> isActionFiltered(final ActionManager actionManager,
final Keymap keymap,
final KeyboardShortcut keyboardShortcut) {
final Shortcut shortcut) {
return new Condition<AnAction>() {
public boolean value(final AnAction action) {
if (keyboardShortcut == null) return true;
if (shortcut == null) return true;
if (action == null) return false;
final Shortcut[] actionShortcuts =
keymap.getShortcuts(action instanceof ActionStub ? ((ActionStub)action).getId() : actionManager.getId(action));
for (Shortcut shortcut : actionShortcuts) {
if (shortcut instanceof KeyboardShortcut) {
final KeyboardShortcut keyboardActionShortcut = (KeyboardShortcut)shortcut;
if (Comparing.equal(keyboardActionShortcut, keyboardShortcut)) {
return true;
}
for (Shortcut actionShortcut : actionShortcuts) {
if (shortcut.equals(actionShortcut)) {
return true;
}
}
return false;
@@ -550,7 +546,7 @@ public class ActionsTreeUtil {
public static Condition<AnAction> isActionFiltered(final ActionManager actionManager,
final Keymap keymap,
final KeyboardShortcut shortcut,
final Shortcut shortcut,
final String filter,
final boolean force) {
return filter != null && filter.length() > 0 ? isActionFiltered(filter, force) :
@@ -513,9 +513,14 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
final ShortcutTextField secondShortcut) {
final KeyStroke keyStroke = firstShortcut.getKeyStroke();
if (keyStroke != null) {
filterTreeByShortcut(new KeyboardShortcut(keyStroke, enable2Shortcut.isSelected() ? secondShortcut.getKeyStroke() : null));
}
}
private void filterTreeByShortcut(Shortcut shortcut) {
if (shortcut != null) {
myTreeExpansionMonitor.freeze();
myActionsTree.filterTree(new KeyboardShortcut(keyStroke, enable2Shortcut.isSelected() ? secondShortcut.getKeyStroke() : null),
myQuickLists);
myActionsTree.filterTree(shortcut, myQuickLists);
final JTree tree = myActionsTree.getTree();
TreeUtil.expandAll(tree);
myTreeExpansionMonitor.restore();
@@ -0,0 +1,111 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.keymap.impl.ui;
import com.intellij.openapi.actionSystem.MouseShortcut;
import com.intellij.util.Consumer;
import com.intellij.util.ui.UIUtil;
import java.awt.*;
import java.awt.event.*;
import javax.swing.SwingUtilities;
/**
* @author Sergey.Malenkov
*/
abstract class MouseShortcutConsumer implements HierarchyListener, Consumer<MouseShortcut> {
private Window myWindow;
private Component myComponent;
private MouseShortcut myShortcut;
private final MouseAdapter myListener = new MouseAdapter() {
@Override
public void mouseWheelMoved(MouseWheelEvent event) {
setShortcutFrom(event);
}
@Override
public void mouseReleased(MouseEvent event) {
setShortcutFrom(event);
}
};
MouseShortcutConsumer(MouseShortcut shortcut) {
if (shortcut != null) {
setShortcut(shortcut);
}
}
MouseShortcut getShortcut() {
return myShortcut;
}
private void setShortcut(MouseShortcut shortcut) {
myShortcut = shortcut;
consume(shortcut);
}
private void setShortcutFrom(MouseEvent event) {
if (myComponent != null) {
Point point = SwingUtilities.convertPoint(event.getComponent(), event.getX(), event.getY(), myComponent);
if (0 <= point.x && point.x < myComponent.getWidth() && 0 <= point.y && point.y < myComponent.getHeight()) {
event.consume();
int button = MouseShortcut.getButton(event);
if (button >= 0) {
int modifiers = event.getModifiersEx();
int clickCount = event instanceof MouseWheelEvent ? 1 : event.getClickCount();
if (myShortcut == null
|| button != myShortcut.getButton()
|| modifiers != myShortcut.getModifiers()
|| clickCount != myShortcut.getClickCount()) {
setShortcut(new MouseShortcut(button, modifiers, clickCount));
}
}
}
}
}
@Override
public void hierarchyChanged(HierarchyEvent event) {
Component component = event.getComponent();
if (component != null) {
if (myComponent == null) {
myComponent = component;
}
if (HierarchyEvent.SHOWING_CHANGED == (HierarchyEvent.SHOWING_CHANGED & event.getChangeFlags())) {
if (myComponent == component) {
Window window = !component.isShowing() ? null : UIUtil.getWindow(component);
if (myWindow != window) {
// It's very important that MouseListener is added to the Window.
// If you add the same listener, for example, to the component
// you will get fake Alt and Meta modifiers.
// Pressing of a middle button causes Alt+Button2 event:
// http://bugs.openjdk.java.net/browse/JDK-4109826
if (myWindow != null) {
myWindow.removeMouseListener(myListener);
myWindow.removeMouseWheelListener(myListener);
}
myWindow = window;
if (myWindow != null) {
myWindow.addMouseListener(myListener);
myWindow.addMouseWheelListener(myListener);
}
}
}
}
}
}
}
@@ -46,9 +46,11 @@ class MouseShortcutDialog extends DialogWrapper{
private final JRadioButton myRbSingleClick;
private final JRadioButton myRbDoubleClick;
private final JLabel myLblPreview;
private final MyClickPad myClickPad;
private final JLabel myClickPad;
private final JTextArea myTarConflicts;
private final MouseShortcutConsumer myShortcutConsumer;
private int myButton;
@JdkConstants.InputEventMask private int myModifiers;
@@ -79,8 +81,6 @@ class MouseShortcutDialog extends DialogWrapper{
myLblPreview=new JLabel(" ");
myClickPad=new MyClickPad();
myTarConflicts=new JTextArea();
myTarConflicts.setFocusable(false);
myTarConflicts.setEditable(false);
@@ -106,6 +106,20 @@ class MouseShortcutDialog extends DialogWrapper{
updatePreviewAndConflicts();
myClickPad = new JLabel(
KeyMapBundle.message("mouse.shortcut.label"),
AllIcons.General.Mouse, SwingConstants.LEADING
);
myShortcutConsumer = new MouseShortcutConsumer(shortcut) {
@Override
public void consume(MouseShortcut shortcut) {
myButton = shortcut.getButton();
myModifiers = shortcut.getModifiers();
updatePreviewAndConflicts();
}
};
myClickPad.addHierarchyListener(myShortcutConsumer);
init();
}
@@ -160,15 +174,13 @@ class MouseShortcutDialog extends DialogWrapper{
// Click pad
JPanel clickPadPanel=new JPanel(new BorderLayout());
panel.add(
clickPadPanel,
myClickPad,
new GridBagConstraints(0,1,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,4,0),0,0)
);
clickPadPanel.setBorder(IdeBorderFactory.createTitledBorder(
KeyMapBundle.message("mouse.shortcut.dialog.click.pad.border"), true));
myClickPad.setPreferredSize(JBUI.size(260, 60));
clickPadPanel.add(myClickPad,BorderLayout.CENTER);
myClickPad.setBorder(BorderFactory.createCompoundBorder(
IdeBorderFactory.createTitledBorder(KeyMapBundle.message("mouse.shortcut.dialog.click.pad.border"), true),
JBUI.Borders.empty(20, 0, 20, 20)));
// Shortcut preview
@@ -276,38 +288,4 @@ class MouseShortcutDialog extends DialogWrapper{
myTarConflicts.setText(KeyMapBundle.message("mouse.shortcut.dialog.assigned.to.area", buffer.toString()));
}
}
private class MyClickPad extends JLabel{
public MyClickPad(){
super(
KeyMapBundle.message("mouse.shortcut.label"),
AllIcons.General.Mouse, SwingConstants.CENTER
);
// It's very imporatant that MouseListener is added to the Dialog. If you add
// the same listener, for example, into the MyClickPad component you get fake
// Alt and Meta modifiers. I means that pressing of middle button causes
// Alt+Button2 event.
// See bug ID 4109826 on Sun's bug parade.
//cast is needed in order to compile with mustang
MouseAdapter adapter = new MouseAdapter() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
mouseReleased(e);
}
public void mouseReleased(MouseEvent e){
Component component= SwingUtilities.getDeepestComponentAt(e.getComponent(),e.getX(),e.getY());
if(component== MyClickPad.this){
e.consume();
myButton = MouseShortcut.getButton(e);
myModifiers=e.getModifiersEx();
updatePreviewAndConflicts();
}
}
};
Window window = MouseShortcutDialog.this.getPeer().getWindow();
window.addMouseListener(adapter);
window.addMouseWheelListener(adapter);
}
}
}
@@ -131,6 +131,8 @@ public class AppUIUtil {
registerFont("/fonts/Inconsolata.ttf");
registerFont("/fonts/SourceCodePro-Regular.ttf");
registerFont("/fonts/SourceCodePro-Bold.ttf");
registerFont("/fonts/SourceCodePro-It.ttf");
registerFont("/fonts/SourceCodePro-BoldIt.ttf");
}
}
@@ -1120,7 +1120,9 @@ updates.check.period.on.exit=On every exit
unsupported.jvm.openjdk.message=OpenJDK 6 is not supported. Please use Oracle Java or newer OpenJDK.
unsupported.jvm.ea.message=Early Access Java versions may cause compatibility issues. Please use stable release.
ibus.blocking.warn.message=IBus prior to 1.5.11 may cause input problem. See <a href="https://youtrack.jetbrains.com/issue/IDEA-78860">IDEA-78860</a> for details.
ibus.blocking.warn.message=IBus prior to 1.5.11 may cause input problems. See <a href="https://youtrack.jetbrains.com/issue/IDEA-78860">IDEA-78860</a> for details.
ayatana.menu.warn.message=JAyatana may cause menus not working. See <a href="https://youtrack.jetbrains.com/issue/IDEA-141725">IDEA-141725</a> for details.
sys.health.acknowledge.link=<br/><a href="ack">Do not show again</a>.
@@ -451,6 +451,7 @@
<refactoring.elementListenerProvider implementation="com.intellij.packageDependencies.ui.RefactoringScopeElementListenerProvider"/>
<highlightVisitor implementation="com.intellij.codeInsight.daemon.impl.DefaultHighlightVisitor"/>
<projectService serviceImplementation="com.intellij.codeInsight.daemon.impl.CachedAnnotators"/>
<daemon.changeLocalityDetector implementation="com.intellij.codeInsight.daemon.impl.DefaultChangeLocalityDetector"/>
<liveTemplateMacro implementation="com.intellij.codeInsight.template.macro.CurrentDateMacro"/>
@@ -778,9 +779,9 @@
serviceImplementation="com.intellij.ui.debugger.extensions.PlaybackDebugger$PlaybackDebuggerState"/>
<globalInspection shortName="Annotator" displayName="Annotator" groupName="General" enabledByDefault="true" level="ERROR"
implementationClass="com.intellij.codeInspection.DefaultHighlightVisitorBasedInspection$AnnotatorBasedInspection"/>
implementationClass="com.intellij.codeInsight.daemon.impl.DefaultHighlightVisitorBasedInspection$AnnotatorBasedInspection"/>
<globalInspection shortName="SyntaxError" displayName="Syntax error" groupName="General" enabledByDefault="true" level="ERROR"
implementationClass="com.intellij.codeInspection.DefaultHighlightVisitorBasedInspection$SyntaxErrorInspection"/>
implementationClass="com.intellij.codeInsight.daemon.impl.DefaultHighlightVisitorBasedInspection$SyntaxErrorInspection"/>
<localInspection shortName="LossyEncoding" bundle="messages.InspectionsBundle" key="lossy.encoding"
groupKey="group.names.internationalization.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.intellij.codeInspection.LossyEncodingInspection"/>
@@ -206,6 +206,7 @@ public class PersistentMapPerformanceTest extends PersistentMapTestBase {
final int finalJ = j;
map.appendData("abc" + i, out -> IOUtil.writeString(StringUtil.repeat("0123456789", 10000 + finalJ - 3), out));
}
map.force();
}
map.close();
@@ -130,6 +130,12 @@ public class Patches {
*/
public static final boolean JDK_BUG_ID_8042123 = !SystemInfo.isJavaVersionAtLeast("1.8.0_40");
/**
* JDK on Mac detects font style for system fonts based only on their name (PostScript name).
* This doesn't work for some fonts which don't use recognizable style suffixes in their names.
*/
public static final boolean JDK_MAC_FONT_STYLE_DETECTION_WORKAROUND = SystemInfo.isMac;
/**
* Older JDK versions could mistakenly use derived italics font, when genuine italics font was available in the system.
* The issue was fixed in JDK 1.8.0_60 as part of <a href="https://bugs.openjdk.java.net/browse/JDK-8064833">JDK-8064833</a>.
@@ -19,10 +19,10 @@ import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.ControlFlowUtils;
import com.siyeh.ig.psiutils.TestUtils;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -137,11 +137,7 @@ public class TestMethodWithoutAssertionInspectionBase extends BaseInspection {
}
private boolean lastStatementIsCallToMethodWithAssertion(PsiMethod method) {
final PsiCodeBlock body = method.getBody();
if (body == null) {
return false;
}
final PsiStatement lastStatement = PsiTreeUtil.getPrevSiblingOfType(body.getLastChild(), PsiStatement.class);
final PsiStatement lastStatement = ControlFlowUtils.getLastStatementInBlock(method.getBody());
if (!(lastStatement instanceof PsiExpressionStatement)) {
return false;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,17 +34,19 @@ import java.util.ArrayList;
import java.util.List;
public class BooleanMethodNameMustStartWithQuestionInspectionBase extends BaseInspection {
@SuppressWarnings({"PublicField"})
public boolean ignoreBooleanMethods = false;
@SuppressWarnings({"PublicField"})
public boolean ignoreInAnnotationInterface = true;
@SuppressWarnings({"PublicField"})
public boolean onlyWarnOnBaseMethods = true;
/**
* @noinspection PublicField
*/
@NonNls public String questionString =
public static final String DEFAULT_QUESTION_WORDS =
"add,are,can,check,contains,could,endsWith,equals,has,is,matches,must,put,remove,shall,should,startsWith,was,were,will,would";
@SuppressWarnings("PublicField")
public boolean ignoreBooleanMethods = false;
@SuppressWarnings("PublicField")
public boolean ignoreInAnnotationInterface = true;
@SuppressWarnings("PublicField")
public boolean onlyWarnOnBaseMethods = true;
@SuppressWarnings("PublicField")
@NonNls public String questionString = DEFAULT_QUESTION_WORDS;
List<String> questionList = new ArrayList(32);
public BooleanMethodNameMustStartWithQuestionInspectionBase() {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,20 +33,20 @@ import java.util.ArrayList;
import java.util.List;
public class NonBooleanMethodNameMayNotStartWithQuestionInspectionBase extends BaseInspection {
@SuppressWarnings("PublicField")
@NonNls public String questionString = BooleanMethodNameMustStartWithQuestionInspectionBase.DEFAULT_QUESTION_WORDS;
@SuppressWarnings("PublicField")
public boolean ignoreBooleanMethods = false;
@SuppressWarnings("PublicField")
public boolean onlyWarnOnBaseMethods = true;
List<String> questionList = new ArrayList(32);
public NonBooleanMethodNameMayNotStartWithQuestionInspectionBase() {
parseString(questionString, questionList);
}
/**
* @noinspection PublicField
*/
@NonNls public String questionString =
"add,are,can,check,contains,could,endsWith,equals,has,is,matches,must,put,remove,shall,should,startsWith,was,were,will,would";
@SuppressWarnings({"PublicField"})
public boolean ignoreBooleanMethods = false;
@SuppressWarnings({"PublicField"})
public boolean onlyWarnOnBaseMethods = true;List<String> questionList = new ArrayList(32);
@Override
@NotNull
public String getDisplayName() {
@@ -471,6 +471,21 @@ public class ControlFlowUtils {
return false;
}
public static PsiStatement getLastStatementInBlock(@Nullable PsiCodeBlock codeBlock) {
return getLastChildOfType(codeBlock, PsiStatement.class);
}
private static <T extends PsiElement> T getLastChildOfType(@Nullable PsiElement element, @NotNull Class<T> aClass) {
if (element == null) return null;
for (PsiElement child = element.getLastChild(); child != null; child = child.getPrevSibling()) {
if (aClass.isInstance(child)) {
//noinspection unchecked
return (T)child;
}
}
return null;
}
public static boolean methodAlwaysThrowsException(@NotNull PsiMethod method) {
final PsiCodeBlock body = method.getBody();
if (body == null) {
@@ -5,6 +5,8 @@ its presence may represent a coding error, particularly in combination with the
<!-- tooltip end -->
<p>
Use the checkbox below to only report when an unary plus is used together with a binary or another unary expression.
This means the inspection won't warn when an unary plus expression is for example used as a variable initializer, as an argument to a method
or as the right-hand side of an assignment. In such cases it is much less confusing.
<p>
</body>
@@ -27,10 +27,10 @@ public class VariableNotUsedInsideIf {
}
void bat(String s) {
if (s != null) {
if (<warning descr="'s' checked for 'null' is not used inside 'if'">s</warning> != null) {
System.out.println();
}
if (s == null) {
if (<warning descr="'s' checked for 'null' is not used inside 'if'">s</warning> == null) {
} else {
@@ -38,24 +38,24 @@ public class VariableNotUsedInsideIf {
}
void money(String s) {
if (((s) != (null))) {
if (((<warning descr="'s' checked for 'null' is not used inside 'if'">s</warning>) != (null))) {
System.out.println();
}
}
void x(Integer x){
if (x != null) {
if (<warning descr="'x' checked for 'null' is not used inside 'if'">x</warning> != null) {
System.out.println();
}
}
int x(Integer x, int y){
if (x != null) return y;//oops, wrong one
if (<warning descr="'x' checked for 'null' is not used inside 'if'">x</warning> != null) return y;//oops, wrong one
return y;
}
int conditional(Integer x) {
return x == null ? 1 : someValue();
return <warning descr="'x' checked for 'null' is not used inside conditional">x</warning> == null ? 1 : someValue();
}
private int someValue() {
@@ -64,6 +64,6 @@ public class VariableNotUsedInsideIf {
void perenthesis(String[] args)
{
String message = (args == null) ? "not null" : "null";
String message = (<warning descr="'args' checked for 'null' is not used inside conditional">args</warning> == null) ? "not null" : "null";
}
}
@@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>VariableNotUsedInsideIf.java</file>
<line>30</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Reference checked for 'null' is not used inside 'if'</problem_class>
<description>&lt;code&gt;s&lt;/code&gt; is not used inside if #loc</description>
</problem>
<problem>
<file>VariableNotUsedInsideIf.java</file>
<line>33</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Reference checked for 'null' is not used inside 'if'</problem_class>
<description>&lt;code&gt;s&lt;/code&gt; is not used inside if #loc</description>
</problem>
<problem>
<file>VariableNotUsedInsideIf.java</file>
<line>41</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Reference checked for 'null' is not used inside 'if'</problem_class>
<description>&lt;code&gt;s&lt;/code&gt; is not used inside if #loc</description>
</problem>
<problem>
<file>VariableNotUsedInsideIf.java</file>
<line>47</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Reference checked for 'null' is not used inside 'if'</problem_class>
<description>&lt;code&gt;x&lt;/code&gt; checked for 'null' is not used inside 'if' #loc</description>
</problem>
<problem>
<file>VariableNotUsedInsideIf.java</file>
<line>53</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Reference checked for 'null' is not used inside 'if'</problem_class>
<description>&lt;code&gt;x&lt;/code&gt; checked for 'null' is not used inside 'if' #loc</description>
</problem>
<problem>
<file>VariableNotUsedInsideIf.java</file>
<line>58</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Reference checked for 'null' is not used inside 'if'</problem_class>
<description>&lt;code&gt;x&lt;/code&gt; checked for 'null' is not used inside conditional #loc</description>
</problem>
<problem>
<file>VariableNotUsedInsideIf.java</file>
<line>67</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Reference checked for 'null' is not used inside 'if'</problem_class>
<description>&lt;code&gt;args&lt;/code&gt; checked for 'null' is not used inside conditional #loc</description>
</problem>
</problems>
@@ -1,10 +1,18 @@
package com.siyeh.ig.bugs;
import com.siyeh.ig.IGInspectionTestCase;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.LightInspectionTestCase;
import org.jetbrains.annotations.Nullable;
public class VariableNotUsedInsideIfInspectionTest extends IGInspectionTestCase {
public class VariableNotUsedInsideIfInspectionTest extends LightInspectionTestCase {
public void test() throws Exception {
doTest("com/siyeh/igtest/bugs/variable_not_used_inside_if", new VariableNotUsedInsideIfInspection());
public void testVariableNotUsedInsideIf() {
doTest();
}
@Nullable
@Override
protected InspectionProfileEntry getInspection() {
return new VariableNotUsedInsideIfInspection();
}
}
@@ -59,6 +59,21 @@ public class ReplaceMethodRefWithLambdaIntention extends Intention {
protected void processIntention(final Editor editor, @NotNull PsiElement element) {
final PsiMethodReferenceExpression referenceExpression = PsiTreeUtil.getParentOfType(element, PsiMethodReferenceExpression.class);
LOG.assertTrue(referenceExpression != null);
final PsiLambdaExpression expr = convertMethodReferenceToLambda(referenceExpression);
final Runnable runnable = new Runnable() {
public void run() {
introduceQualifierAsLocalVariable(editor, expr);
}
};
final Application application = ApplicationManager.getApplication();
if (application.isUnitTestMode()) {
runnable.run();
} else {
application.invokeLater(runnable);
}
}
public static PsiLambdaExpression convertMethodReferenceToLambda(final PsiMethodReferenceExpression referenceExpression) {
final PsiElement resolve = referenceExpression.resolve();
final PsiType functionalInterfaceType = referenceExpression.getFunctionalInterfaceType();
final PsiClassType.ClassResolveResult functionalInterfaceResolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
@@ -87,20 +102,21 @@ public class ReplaceMethodRefWithLambdaIntention extends Intention {
final Map<PsiParameter, String> map = new HashMap<PsiParameter, String>();
final UniqueNameGenerator nameGenerator = new UniqueNameGenerator();
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(element.getProject());
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(referenceExpression.getProject());
final String paramsString = StringUtil.join(parameters, new Function<PsiParameter, String>() {
@Override
public String fun(PsiParameter parameter) {
final int parameterIndex = parameterList.getParameterIndex(parameter);
String baseName;
if (isReceiver && parameterIndex == 0) {
final SuggestedNameInfo nameInfo = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, psiSubstitutor.substitute(parameter.getType()));
final SuggestedNameInfo
nameInfo = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, psiSubstitutor.substitute(parameter.getType()));
baseName = nameInfo.names.length > 0 ? nameInfo.names[0] : parameter.getName();
}
else {
final String initialName = psiParameters != null ? psiParameters[parameterIndex - (isReceiver ? 1 : 0)].getName() : parameter.getName();
baseName = codeStyleManager.variableNameToPropertyName(initialName, VariableKind.PARAMETER);
}
}
if (baseName != null) {
String parameterName = nameGenerator.generateUniqueName(codeStyleManager.suggestUniqueVariableName(baseName, referenceExpression, true));
@@ -133,7 +149,7 @@ public class ReplaceMethodRefWithLambdaIntention extends Intention {
}
final boolean onArrayRef =
JavaPsiFacade.getElementFactory(element.getProject()).getArrayClass(PsiUtil.getLanguageLevel(element)) == containingClass;
JavaPsiFacade.getElementFactory(referenceExpression.getProject()).getArrayClass(PsiUtil.getLanguageLevel(referenceExpression)) == containingClass;
final PsiElement referenceNameElement = referenceExpression.getReferenceNameElement();
if (isReceiver){
@@ -149,7 +165,7 @@ public class ReplaceMethodRefWithLambdaIntention extends Intention {
buf.append(qualifier.getText()).append(".");
}
}
}
}
//new or method name
buf.append(referenceExpression.getReferenceName());
@@ -209,7 +225,7 @@ public class ReplaceMethodRefWithLambdaIntention extends Intention {
final PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression)referenceExpression
.replace(JavaPsiFacade.getElementFactory(element.getProject()).createExpressionFromText(buf.toString(), referenceExpression));
.replace(JavaPsiFacade.getElementFactory(referenceExpression.getProject()).createExpressionFromText(buf.toString(), referenceExpression));
PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)typeCastExpression.getOperand();
if (RedundantCastUtil.isCastRedundant(typeCastExpression)) {
final PsiExpression operand = typeCastExpression.getOperand();
@@ -219,21 +235,10 @@ public class ReplaceMethodRefWithLambdaIntention extends Intention {
final PsiExpression singleExpression = RedundantLambdaCodeBlockInspection.isCodeBlockRedundant(lambdaExpression, body);
if (singleExpression != null) {
body.replace(singleExpression);
}
}
}
final PsiLambdaExpression expr = lambdaExpression;
final Runnable runnable = new Runnable() {
public void run() {
introduceQualifierAsLocalVariable(editor, expr);
}
};
final Application application = ApplicationManager.getApplication();
if (application.isUnitTestMode()) {
runnable.run();
} else {
application.invokeLater(runnable);
}
return lambdaExpression;
}
private static void introduceQualifierAsLocalVariable(Editor editor, PsiLambdaExpression lambdaExpression) {
@@ -16,7 +16,7 @@
package com.intellij.execution.junit;
public class AllInDirectoryConfigurationProducer extends AbstractAllInDirectoryConfigurationProducer {
protected AllInDirectoryConfigurationProducer() {
public AllInDirectoryConfigurationProducer() {
super(JUnitConfigurationType.getInstance());
}
}
@@ -612,6 +612,9 @@ public class JUnitConfiguration extends JavaTestConfigurationBase {
final String fqName = myPattern.iterator().next();
return (fqName.contains("*") ? fqName : StringUtil.getShortName(fqName)) + (size > 1 ? " and " + (size - 1) + " more" : "");
}
if (TEST_CATEGORY.equals(TEST_OBJECT)) {
return "@Category(" + (StringUtil.isEmpty(CATEGORY_NAME) ? "Invalid" : CATEGORY_NAME) + ")";
}
final String className = JavaExecutionUtil.getPresentableClassName(getMainClassName());
if (TEST_METHOD.equals(TEST_OBJECT)) {
return className + '.' + getMethodName();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ import java.util.LinkedHashSet;
import java.util.Set;
public class PatternConfigurationProducer extends AbstractPatternBasedConfigurationProducer<JUnitConfiguration> {
protected PatternConfigurationProducer() {
public PatternConfigurationProducer() {
super(JUnitConfigurationType.getInstance());
}
@@ -16,7 +16,7 @@
package com.intellij.execution.junit;
public class TestClassConfigurationProducer extends AbstractTestClassConfigurationProducer {
protected TestClassConfigurationProducer() {
public TestClassConfigurationProducer() {
super(JUnitConfigurationType.getInstance());
}
}
@@ -16,7 +16,7 @@
package com.intellij.execution.junit;
public class TestMethodConfigurationProducer extends AbstractTestMethodConfigurationProducer {
protected TestMethodConfigurationProducer() {
public TestMethodConfigurationProducer() {
super(JUnitConfigurationType.getInstance());
}
}
@@ -16,6 +16,7 @@
package com.jetbrains.python.documentation.docstrings;
import com.google.common.collect.Lists;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.process.ProcessOutput;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
@@ -122,15 +123,11 @@ public class PyStructuredDocstringFormatter {
final Map<String, String> env = new HashMap<String, String>();
PythonEnvUtil.setPythonDontWriteBytecode(env);
final ProcessOutput output = PySdkUtil.getProcessOutput(formatter.newCommandLine(sdkHome, Lists.<String>newArrayList()),
new File(sdkHome).getParent(),
env, 5000, data, true);
if (output.isTimeout()) {
LOG.info("timeout when calculating docstring");
return null;
}
else if (output.getExitCode() != 0) {
LOG.info("error when calculating docstring: " + output.getStderr());
final GeneralCommandLine commandLine = formatter.newCommandLine(sdkHome, Lists.<String>newArrayList());
LOG.debug("Command for launching docstring formatter: " + commandLine.getCommandLineString());
final ProcessOutput output = PySdkUtil.getProcessOutput(commandLine, new File(sdkHome).getParent(), env, 5000, data, true);
if (!output.checkSuccess(LOG)) {
return null;
}
return output.getStdout();
@@ -42,7 +42,8 @@ public class PyRemoteSdkFlavor extends CPythonSdkFlavor {
@Override
public boolean isValidSdkHome(String path) {
return StringUtil.isNotEmpty(path) && checkName(NAMES, getExecutableName(path)) && (path.startsWith("ssh:") || path.startsWith("vagrant:"));
return StringUtil.isNotEmpty(path) && checkName(NAMES, getExecutableName(path))
&& (path.startsWith("ssh:") || path.startsWith("vagrant:") || path.startsWith("docker:"));
}
private static boolean checkName(String[] names, @Nullable String name) {
@@ -64,7 +64,8 @@ public class XmlCommenter implements EscapingCommenter {
String suffix = getBlockCommentSuffix();
int start = range.getStartOffset();
if (CharArrayUtil.regionMatches(document.getCharsSequence(), start, prefix)) {
int prefixStart = start = CharArrayUtil.shiftForward(document.getCharsSequence(), start, " \t\n");
if (CharArrayUtil.regionMatches(document.getCharsSequence(), prefixStart, prefix)) {
start += prefix.length();
}
int end = range.getEndOffset();
@@ -83,7 +84,7 @@ public class XmlCommenter implements EscapingCommenter {
if (CharArrayUtil.regionMatches(document.getCharsSequence(), start, GT)) {
document.replaceString(start, start + GT.length(), ESCAPED_GT);
}
if (CharArrayUtil.regionMatches(document.getCharsSequence(), range.getStartOffset(), prefix + "-")) {
if (CharArrayUtil.regionMatches(document.getCharsSequence(), prefixStart, prefix + "-")) {
document.insertString(start, " ");
}
if (CharArrayUtil.regionMatches(document.getCharsSequence(), range.getEndOffset() - suffix.length() - 1, "-" + suffix)) {