Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
Bas Leijdekkers
2012-08-19 13:46:35 +02:00
49 changed files with 923 additions and 335 deletions
+3 -3
View File
@@ -229,9 +229,9 @@ public def layoutCommunityPlugins(String home) {
fileset(dir: "$home/plugins/maven/maven2-server-impl/lib")
}
layoutPlugin("rearranger") {
jar("rearranger.jar") {
module("rearranger")
layoutPlugin("gradle") {
jar("gradle.jar") {
module("gradle")
}
}
@@ -315,7 +315,9 @@ public class CreatePropertyFromUsageFix extends CreateFromUsageBaseFix implement
}
protected void beforeTemplateFinished(PsiClass aClass, PsiField field) {
positionCursor(myMethodCall.getProject(), myMethodCall.getContainingFile(), myMethodCall);
if (myMethodCall.isValid()) {
positionCursor(myMethodCall.getProject(), myMethodCall.getContainingFile(), myMethodCall);
}
}
private static String getVariableName(PsiMethodCallExpression methodCall, boolean isStatic) {
@@ -48,6 +48,7 @@ public class AddOverrideAnnotationAction implements IntentionAction {
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
if (!PsiUtil.isLanguageLevel5OrHigher(file)) return false;
if (!file.getManager().isInProject(file)) return false;
PsiMethod method = findMethod(file, editor.getCaretModel().getOffset());
if (method == null) return false;
if (method.getModifierList().findAnnotation(JAVA_LANG_OVERRIDE) != null) return false;
@@ -16,6 +16,10 @@
package com.intellij.psi;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.*;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
@@ -95,79 +99,6 @@ public class LambdaUtil {
return signatures.size() == 1 ? null : "Multiple non-overriding abstract methods found";
}
public static PsiType getLambdaParameterType(PsiParameter param) {
final PsiElement paramParent = param.getParent();
if (paramParent instanceof PsiParameterList) {
final int parameterIndex = ((PsiParameterList)paramParent).getParameterIndex(param);
if (parameterIndex > -1) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(param, PsiLambdaExpression.class);
final PsiType type = getFunctionInterfaceType(lambdaExpression);
final PsiClassType.ClassResolveResult resolveResult = type instanceof PsiClassType ? ((PsiClassType)type).resolveGenerics() : null;
if (resolveResult != null) {
final MethodSignature methodSignature = getFunction(resolveResult.getElement());
if (methodSignature != null) {
final PsiType[] types = methodSignature.getParameterTypes();
if (parameterIndex < types.length) {
final PsiType psiType = resolveResult.getSubstitutor().substitute(types[parameterIndex]);
if (psiType instanceof PsiWildcardType) {
final PsiType bound = ((PsiWildcardType)psiType).getBound();
if (bound != null) {
return bound;
}
}
return psiType;
}
}
}
}
}
return new PsiLambdaParameterType(param);
}
@Nullable
public static PsiType getFunctionInterfaceType(@Nullable PsiLambdaExpression lambdaExpression) {
if (lambdaExpression != null) {
final PsiElement parent = lambdaExpression.getParent();
PsiType type = null;
if (parent instanceof PsiTypeCastExpression) {
type = ((PsiTypeCastExpression)parent).getType();
}
else if (parent instanceof PsiVariable) {
type = ((PsiVariable)parent).getType();
}
else if (parent instanceof PsiAssignmentExpression) {
final PsiExpression lExpression = ((PsiAssignmentExpression)parent).getLExpression();
type = lExpression.getType();
}
else if (parent instanceof PsiExpressionList) {
final PsiExpressionList expressionList = (PsiExpressionList)parent;
final int lambdaIdx = getLambdaIdx(expressionList, lambdaExpression);
if (lambdaIdx > -1) {
final PsiElement gParent = expressionList.getParent();
if (gParent instanceof PsiMethodCallExpression) {
final JavaResolveResult resolveResult = ((PsiMethodCallExpression)gParent).resolveMethodGenerics();
final PsiElement resolve = resolveResult.getElement();
if (resolve instanceof PsiMethod) {
final PsiParameter[] parameters = ((PsiMethod)resolve).getParameterList().getParameters();
if (lambdaIdx < parameters.length) {
type = resolveResult.getSubstitutor().substitute(parameters[lambdaIdx].getType());
}
}
}
}
}
else if (parent instanceof PsiReturnStatement) {
final PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class);
if (method != null) {
type = method.getReturnType();
}
}
return type;
}
return null;
}
public static boolean isAcceptable(PsiLambdaExpression lambdaExpression, final PsiType leftType) {
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(leftType);
final PsiClass psiClass = resolveResult.getElement();
@@ -195,22 +126,29 @@ public class LambdaUtil {
}
LOG.assertTrue(psiClass != null);
PsiType methodReturnType = getReturnType(psiClass, methodSignature);
if (methodReturnType != null && methodReturnType != PsiType.VOID) {
methodReturnType = resolveResult.getSubstitutor().substitute(methodSignature.getSubstitutor().substitute(methodReturnType));
final PsiElement body = lambdaExpression.getBody();
if (body instanceof PsiCodeBlock) {
final PsiCodeBlock block = (PsiCodeBlock)body;
for (PsiStatement statement : block.getStatements()) {
if (statement instanceof PsiReturnStatement) {
final PsiExpression returnValue = ((PsiReturnStatement)statement).getReturnValue();
if (returnValue != null) {
if (!checkReturnTypeAssignability(returnValue.getType(), parameterTypes, lambdaExpression, methodReturnType)) return false;
if (methodReturnType != null) {
if (methodReturnType != PsiType.VOID) {
methodReturnType = resolveResult.getSubstitutor().substitute(methodSignature.getSubstitutor().substitute(methodReturnType));
final PsiElement body = lambdaExpression.getBody();
if (body instanceof PsiCodeBlock) {
final PsiCodeBlock block = (PsiCodeBlock)body;
for (PsiStatement statement : block.getStatements()) {
if (statement instanceof PsiReturnStatement) {
final PsiExpression returnValue = ((PsiReturnStatement)statement).getReturnValue();
if (returnValue != null) {
if (!checkReturnTypeAssignability(returnValue.getType(), parameterTypes, lambdaExpression, methodReturnType)) return false;
}
}
}
}
}
else if (body instanceof PsiExpression) {
return checkReturnTypeAssignability(((PsiExpression)body).getType(), parameterTypes, lambdaExpression, methodReturnType);
else if (body instanceof PsiExpression) {
return checkReturnTypeAssignability(((PsiExpression)body).getType(), parameterTypes, lambdaExpression, methodReturnType);
}
} else {
final List<PsiExpression> returnExpressions = lambdaExpression.getReturnExpressions();
for (PsiExpression returnValue : returnExpressions) {
if (returnValue.getType() != PsiType.VOID) return false;
}
}
}
return true;
@@ -331,6 +269,37 @@ public class LambdaUtil {
return -1;
}
public static boolean dependsOnTypeParams(PsiType type, PsiLambdaExpression expr) {
final Boolean accept = type.accept(new TypeParamsChecker(expr));
return accept != null && accept.booleanValue();
}
public static boolean isFreeFromTypeInferenceArgs(final PsiParameter[] methodParameters,
final PsiLambdaExpression lambdaExpression,
final PsiExpression expression) {
final PsiParameter[] lambdaParams = lambdaExpression.getParameterList().getParameters();
final boolean [] independent = new boolean[]{true};
expression.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitReferenceExpression(PsiReferenceExpression expression) {
super.visitReferenceExpression(expression);
int usedParamIdx = -1;
for (int i = 0; i < lambdaParams.length; i++) {
PsiParameter param = lambdaParams[i];
if (expression.isReferenceTo(param)) {
usedParamIdx = i;
break;
}
}
if (usedParamIdx > -1 && dependsOnTypeParams(methodParameters[usedParamIdx].getType(), lambdaExpression)) {
independent[0] = false;
}
}
});
return independent[0];
}
private static class TypeParamsChecker extends PsiTypeVisitor<Boolean> {
private final PsiLambdaExpression myExpression;
@@ -17,6 +17,8 @@ package com.intellij.psi;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.impl.source.resolve.ParameterTypeInferencePolicy;
import com.intellij.psi.infos.CandidateInfo;
@@ -29,6 +31,8 @@ import org.jetbrains.annotations.Nullable;
* @see JavaPsiFacade#getResolveHelper()
*/
public interface PsiResolveHelper {
RecursionGuard ourGuard = RecursionManager.createGuard("typeArgInference");
class SERVICE {
private SERVICE() {
}
@@ -21,20 +21,26 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy;
import com.intellij.psi.impl.source.resolve.ParameterTypeInferencePolicy;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.containers.ConcurrentHashMap;
import com.intellij.util.containers.ConcurrentWeakHashMap;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
/**
* @author ik, dsl
*/
public class MethodCandidateInfo extends CandidateInfo{
public static final Key<PsiMethod> CURRENT_CANDIDATE = Key.create("CURRENT_CANDIDATE");
public static final ThreadLocal<Map<PsiElement, PsiMethod>> CURRENT_CANDIDATE = new ThreadLocal<Map<PsiElement, PsiMethod>>();
@ApplicabilityLevelConstant private int myApplicabilityLevel = 0;
private final PsiElement myArgumentList;
private final PsiType[] myArgumentTypes;
private final PsiType[] myTypeArguments;
private PsiSubstitutor myCalcedSubstitutor = null;
private final LanguageLevel myLanguageLevel;
private static final Object LOCK = new Object();
public MethodCandidateInfo(PsiElement candidate,
PsiSubstitutor substitutor,
@@ -92,12 +98,20 @@ public class MethodCandidateInfo extends CandidateInfo{
PsiSubstitutor incompleteSubstitutor = super.getSubstitutor();
PsiMethod method = getElement();
if (myTypeArguments == null) {
myArgumentList.putUserData(CURRENT_CANDIDATE, getElement());
Map<PsiElement, PsiMethod> map;
synchronized (LOCK) {
map = CURRENT_CANDIDATE.get();
if (map == null) {
map = new ConcurrentWeakHashMap<PsiElement, PsiMethod>();
CURRENT_CANDIDATE.set(map);
}
}
map.put(myArgumentList, getElement());
try {
myCalcedSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE);
}
finally {
myArgumentList.putUserData(CURRENT_CANDIDATE, null);
map.remove(myArgumentList);
}
}
else {
@@ -29,7 +29,7 @@ import com.intellij.psi.impl.java.stubs.PsiParameterStub;
import com.intellij.psi.impl.source.tree.ChildRole;
import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.impl.source.tree.JavaSharedImplUtil;
import com.intellij.psi.LambdaUtil;
import com.intellij.psi.impl.source.tree.java.PsiLambdaExpressionImpl;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.ui.RowIcon;
@@ -122,7 +122,7 @@ public class PsiParameterImpl extends JavaStubPsiElement<PsiParameterStub> imple
final PsiTypeElement typeElement = getTypeElement();
if (typeElement == null && isLambdaParameter()) {
return LambdaUtil.getLambdaParameterType(this);
return PsiLambdaExpressionImpl.getLambdaParameterType(this);
}
return JavaSharedImplUtil.getType(typeElement, getNameIdentifier(), this);
@@ -75,7 +75,7 @@ public class ProcessCandidateParameterTypeInferencePolicy extends DefaultParamet
}
if (parameter != null) {
final PsiParameter finalParameter = parameter;
PsiType type = PsiResolveHelperImpl.ourGuard.doPreventingRecursion(innerMethodCall, true, new Computable<PsiType>() {
PsiType type = PsiResolveHelper.ourGuard.doPreventingRecursion(innerMethodCall, true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return substitutor.substitute(finalParameter.getType());
@@ -17,8 +17,6 @@ package com.intellij.psi.impl.source.resolve;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.java.PsiLambdaExpressionImpl;
@@ -38,9 +36,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
public class PsiResolveHelperImpl implements PsiResolveHelper {
static final RecursionGuard ourGuard = RecursionManager.createGuard("typeArgInference");
private final PsiManager myManager;
public PsiResolveHelperImpl(PsiManager manager) {
@@ -130,7 +128,8 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
@NotNull PsiElement place,
@Nullable PsiClass accessObjectClass,
final PsiElement currentFileResolveScope) {
return JavaResolveUtil.isAccessible(member, member.getContainingClass(), modifierList, place, accessObjectClass, currentFileResolveScope);
return JavaResolveUtil.isAccessible(member, member.getContainingClass(), modifierList, place, accessObjectClass,
currentFileResolveScope);
}
@Override
@@ -166,9 +165,11 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
paramTypes[j] = parameter.getType();
if (paramTypes[j] instanceof PsiEllipsisType) {
paramTypes[j] = ((PsiEllipsisType)paramTypes[j]).getComponentType();
if (arguments.length == parameters.length && argTypes[j] instanceof PsiArrayType && !(((PsiArrayType)argTypes[j]).getComponentType() instanceof PsiPrimitiveType)) {
argTypes[j] = ((PsiArrayType)argTypes[j]).getComponentType();
}
if (arguments.length == parameters.length &&
argTypes[j] instanceof PsiArrayType &&
!(((PsiArrayType)argTypes[j]).getComponentType() instanceof PsiPrimitiveType)) {
argTypes[j] = ((PsiArrayType)argTypes[j]).getComponentType();
}
}
}
}
@@ -185,6 +186,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
PsiType lowerBound = PsiType.NULL;
PsiType upperBound = PsiType.NULL;
if (paramTypes.length > 0) {
sortLambdaExpressionsLast(paramTypes, argTypes);
for (int j = 0; j < argTypes.length; j++) {
PsiType argumentType = argTypes[j];
if (argumentType == null) continue;
@@ -199,8 +201,13 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
argumentType = ((PsiArrayType)argumentType).getComponentType();
}
}
final Pair<PsiType,ConstraintType> currentSubstitution = getSubstitutionForTypeParameterConstraint(typeParameter, parameterType,
argumentType, true, PsiUtil.getLanguageLevel(typeParameter));
final Pair<PsiType,ConstraintType> currentSubstitution;
if (argumentType instanceof PsiLambdaExpressionType) {
currentSubstitution = inferSubstitutionFromLambda(typeParameter, (PsiLambdaExpressionType)argumentType, lowerBound);
} else {
currentSubstitution = getSubstitutionForTypeParameterConstraint(typeParameter, parameterType,
argumentType, true, PsiUtil.getLanguageLevel(typeParameter));
}
if (currentSubstitution == null) continue;
if (currentSubstitution == FAILED_INFERENCE) {
return getFailedInferenceConstraint(typeParameter);
@@ -268,6 +275,23 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
return null;
}
private static void sortLambdaExpressionsLast(PsiType[] paramTypes, PsiType[] argTypes) {
for (int i = 0; i < argTypes.length; i++) {
PsiType argType = argTypes[i];
if (argType instanceof PsiLambdaExpressionType && i < argTypes.length - 1) {
int k = i + 1;
while(argTypes[k] instanceof PsiLambdaExpressionType && k < argTypes.length - 1) {
k++;
}
if (!(argTypes[k] instanceof PsiLambdaExpressionType)) {
ArrayUtil.swap(paramTypes, i, k);
ArrayUtil.swap(argTypes, i, k);
i = k;
}
}
}
}
private static Pair<PsiType, ConstraintType> getFailedInferenceConstraint(final PsiTypeParameter typeParameter) {
return new Pair<PsiType, ConstraintType>(JavaPsiFacade.getInstance(typeParameter.getProject()).getElementFactory().createType(typeParameter), ConstraintType.EQUALS);
}
@@ -509,10 +533,6 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
}
if (paramClass == null) return null;
if (arg instanceof PsiLambdaExpressionType) {
return inferSubstitutionFromLambda(typeParam, (PsiLambdaExpressionType)arg);
}
if (!(arg instanceof PsiClassType)) return null;
JavaResolveResult argResult = ((PsiClassType)arg).resolveGenerics();
@@ -536,24 +556,26 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
}
@Nullable
private static Pair<PsiType, ConstraintType> inferSubstitutionFromLambda(PsiTypeParameter typeParam, PsiLambdaExpressionType arg) {
private static Pair<PsiType, ConstraintType> inferSubstitutionFromLambda(PsiTypeParameter typeParam,
PsiLambdaExpressionType arg,
PsiType lowerBound) {
final PsiLambdaExpression lambdaExpression = arg.getExpression();
if (PsiUtil.getLanguageLevel(lambdaExpression).isAtLeast(LanguageLevel.JDK_1_8)) {
final PsiElement parent = skipParenthesizedExprUp(lambdaExpression.getParent());
if (parent instanceof PsiExpressionList) {
final PsiExpressionList expressionList = (PsiExpressionList)parent;
final PsiMethod method = expressionList.getUserData(MethodCandidateInfo.CURRENT_CANDIDATE);
final Map<PsiElement,PsiMethod> methodMap = MethodCandidateInfo.CURRENT_CANDIDATE.get();
final PsiMethod method = methodMap != null ? methodMap.get(expressionList) : null;
if (method != null) {
final int i = LambdaUtil.getLambdaIdx(expressionList,
((PsiLambdaExpressionImpl)lambdaExpression));
final int i = LambdaUtil.getLambdaIdx(expressionList, lambdaExpression);
if (i < 0) return null;
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length <= i) return null;
return inferConstraintFromFunctionalInterfaceMethod(typeParam, lambdaExpression, parameters[i].getType());
return inferConstraintFromFunctionalInterfaceMethod(typeParam, lambdaExpression, parameters[i].getType(), lowerBound);
}
}
else {
return inferConstraintFromFunctionalInterfaceMethod(typeParam, lambdaExpression, lambdaExpression.getFunctionalInterfaceType());
return inferConstraintFromFunctionalInterfaceMethod(typeParam, lambdaExpression, lambdaExpression.getFunctionalInterfaceType(), lowerBound);
}
}
return null;
@@ -561,8 +583,9 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
@Nullable
private static Pair<PsiType, ConstraintType> inferConstraintFromFunctionalInterfaceMethod(PsiTypeParameter typeParam,
PsiLambdaExpression lambdaExpression,
PsiType functionalInterfaceType) {
final PsiLambdaExpression lambdaExpression,
final PsiType functionalInterfaceType,
PsiType lowerBound) {
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
final PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType);
if (method != null) {
@@ -573,9 +596,14 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
final PsiSubstitutor subst = resolveResult.getSubstitutor();
final PsiType returnType = subst.substitute(method.getReturnType());
if (returnType != null && returnType != PsiType.VOID) {
Pair<PsiType, ConstraintType> constraint = null;
final List<PsiExpression> expressions = lambdaExpression.getReturnExpressions();
for (final PsiExpression expression : expressions) {
PsiType exprType = ourGuard.doPreventingRecursion(lambdaExpression, true, new Computable<PsiType>() {
final boolean independent = LambdaUtil.isFreeFromTypeInferenceArgs(methodParameters, lambdaExpression, expression);
if (!independent && lowerBound != PsiType.NULL) {
return null;
}
PsiType exprType = independent ? expression.getType() : ourGuard.doPreventingRecursion(lambdaExpression, true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return expression.getType();
@@ -588,15 +616,32 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
exprType = subst.substitute(methodParameters[parameterIndex].getType());
}
} else if (exprType instanceof PsiLambdaExpressionType) {
return inferConstraintFromFunctionalInterfaceMethod(typeParam, ((PsiLambdaExpressionType)exprType).getExpression(), returnType);
return inferConstraintFromFunctionalInterfaceMethod(typeParam, ((PsiLambdaExpressionType)exprType).getExpression(), returnType,
lowerBound);
}
if (exprType == null) return null;
Pair<PsiType, ConstraintType> constraint =
if (exprType == null){
return FAILED_INFERENCE;
}
final Pair<PsiType, ConstraintType> returnExprConstraint =
getSubstitutionForTypeParameterConstraint(typeParam, returnType, exprType, false, PsiUtil.getLanguageLevel(method));
if (constraint != null) {
return constraint; //todo check that all return statements lead to the same inference
if (returnExprConstraint != null) {
if (returnExprConstraint == FAILED_INFERENCE) return returnExprConstraint;
if (constraint != null) {
final PsiType leastUpperBound = GenericsUtil.getLeastUpperBound(constraint.getFirst(), returnExprConstraint.getFirst(), typeParam.getManager());
constraint = new Pair<PsiType, ConstraintType>(leastUpperBound, ConstraintType.SUPERTYPE);
} else {
constraint = returnExprConstraint;
}
}
}
if (constraint != null) return constraint;
}
for (PsiParameter parameter : methodParameters) {
if (LambdaUtil.dependsOnTypeParams(parameter.getType(), lambdaExpression)) {
return getFailedInferenceConstraint(typeParam);
}
}
}
return null;
@@ -793,6 +838,9 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
}
} else if (parent instanceof PsiLambdaExpression) {
expectedType = LambdaUtil.getFunctionalInterfaceReturnType(((PsiLambdaExpression)parent).getFunctionalInterfaceType());
if (expectedType == null) {
return getFailedInferenceConstraint(typeParameter);
}
}
final PsiManager manager = typeParameter.getManager();
@@ -829,8 +877,14 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
final PsiExpressionList argumentList = methodCall.getArgumentList();
if (argumentList != null && PsiUtil.getLanguageLevel(argumentList).isAtLeast(LanguageLevel.JDK_1_8)) {
for (PsiExpression expression : argumentList.getExpressions()) {
if (expression instanceof PsiLambdaExpression){
return getFailedInferenceConstraint(typeParameter);
if (expression instanceof PsiLambdaExpression) {
if (((PsiLambdaExpression)expression).getParameterList().getParametersCount() > 0){
return getFailedInferenceConstraint(typeParameter);
}
final PsiType functionalInterfaceType = PsiLambdaExpressionImpl.getFunctionalInterfaceType(((PsiLambdaExpression)expression), false);
if (functionalInterfaceType == null || PsiUtil.resolveClassInType(functionalInterfaceType) == typeParameter){
return getFailedInferenceConstraint(typeParameter);
}
}
}
}
@@ -20,6 +20,7 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -29,7 +30,6 @@ import java.util.Collections;
import java.util.List;
public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements PsiLambdaExpression {
public static RecursionGuard ourGuard = RecursionManager.createGuard("Lambda");
public PsiLambdaExpressionImpl() {
super(JavaElementType.LAMBDA_EXPRESSION);
@@ -76,7 +76,12 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi
@Nullable
@Override
public PsiType getFunctionalInterfaceType() {
PsiElement parent = getParent();
return getFunctionalInterfaceType(this, true);
}
@Nullable
public static PsiType getFunctionalInterfaceType(PsiLambdaExpression expression, final boolean tryToSubstitute) {
PsiElement parent = expression.getParent();
while (parent instanceof PsiParenthesizedExpression) {
parent = parent.getParent();
}
@@ -93,8 +98,7 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi
}
else if (parent instanceof PsiExpressionList) {
final PsiExpressionList expressionList = (PsiExpressionList)parent;
int lambdaIdx = LambdaUtil.getLambdaIdx(expressionList, this);
int lambdaIdx = LambdaUtil.getLambdaIdx(expressionList, expression);
if (lambdaIdx > -1) {
final PsiElement gParent = expressionList.getParent();
if (gParent instanceof PsiMethodCallExpression) {
@@ -105,13 +109,15 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi
final PsiParameter[] parameters = ((PsiMethod)resolve).getParameterList().getParameters();
if (lambdaIdx < parameters.length) {
type = parameters[lambdaIdx].getType();
final PsiType psiType = type;
type = ourGuard.doPreventingRecursion(this, true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return resolveResult.getSubstitutor().substitute(psiType);
}
});
if (tryToSubstitute) {
final PsiType psiType = type;
type = PsiResolveHelper.ourGuard.doPreventingRecursion(expression, true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return resolveResult.getSubstitutor().substitute(psiType);
}
});
}
}
}
}
@@ -159,4 +165,38 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi
public String toString() {
return "PsiLambdaExpression:" + getText();
}
public static PsiType getLambdaParameterType(PsiParameter param) {
final PsiElement paramParent = param.getParent();
if (paramParent instanceof PsiParameterList) {
final int parameterIndex = ((PsiParameterList)paramParent).getParameterIndex(param);
if (parameterIndex > -1) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(param, PsiLambdaExpression.class);
PsiType type = getFunctionalInterfaceType(lambdaExpression, true);
if (type == null) {
type = getFunctionalInterfaceType(lambdaExpression, false);
}
final PsiClassType.ClassResolveResult resolveResult = type instanceof PsiClassType ? ((PsiClassType)type).resolveGenerics() : null;
if (resolveResult != null) {
final PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(type);
if (method != null) {
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameterIndex < parameters.length) {
final PsiType psiType = resolveResult.getSubstitutor().substitute(parameters[parameterIndex].getType());
if (!LambdaUtil.dependsOnTypeParams(psiType, lambdaExpression)) {
if (psiType instanceof PsiWildcardType) {
final PsiType bound = ((PsiWildcardType)psiType).getBound();
if (bound != null) {
return bound;
}
}
return psiType;
}
}
}
}
}
}
return new PsiLambdaParameterType(param);
}
}
@@ -22,7 +22,7 @@ class InferenceFromArgs {
bar(b, (k, v) -> {Integer i = k; return v;});
bazz(<error descr="Cyclic inference">(k, v) -> v</error>);
bazz((k, v) -> {<error descr="Incompatible types. Found: 'E', required: 'int'">int i = k;</error> return v;});
bazz((k, v) -> {<error descr="Incompatible types. Found: '<lambda parameter>', required: 'int'">int i = k;</error> return v;});
}
public static <T> SameArgsI<T> max() {
@@ -57,7 +57,7 @@ class ReturnTypeCompatibility {
}
public static void main(String[] args) {
call(<error descr="Cyclic inference">i-> {return i;}</error>);
<error descr="Cannot resolve method 'call(<lambda expression>)'">call</error>(i-> {return i;});
}
}
@@ -15,3 +15,63 @@ class TypeArgsConsistency {
<error descr="Incompatible types. Found: 'TypeArgsConsistency.I<java.lang.String>', required: 'TypeArgsConsistency.I<java.lang.Integer>'">I<Integer> i3 = bar((i, j) -> "" + i + j);</error>
}
}
class TypeArgsConsistency1 {
interface I<T> {
int m(int i, T j);
}
static void foo(I<Integer> s) { }
static <X> I<X> bar(I<X> s) { return null; }
{
I<Integer> i1 = (i, j) -> i + j;
foo((i, j) -> i + j);
I<Integer> i2 =bar(<error descr="Cyclic inference">(i, j) -> i</error>) ;
I<Integer> i3 = bar(<error descr="Cyclic inference">(i, j) -> "" + i + j</error>);
}
}
class TypeArgsConsistency2 {
static <T> I<T> bar(I<T> i) {return null;}
static <T> I1<T> bar1(I1<T> i) {return null;}
static <T> I2<T> bar2(I2<T> i) {return i;}
public static void main(String[] args) {
I<Integer> i1 = bar(<error descr="Cyclic inference">x -> x</error>);
I1<Integer> i2 = bar1(<error descr="Cyclic inference">x -> 1</error>);
I2<String> aI2 = bar2(x -> "");
<error descr="Incompatible types. Found: 'TypeArgsConsistency2.I2<java.lang.String>', required: 'TypeArgsConsistency2.I2<java.lang.Integer>'">I2<Integer> aI28 = bar2( x-> "");</error>
I2<Integer> i3 = bar2(x -> x);
I2<Integer> i4 = bar2(x -> foooI());
System.out.println(i4.foo(2));
}
static <K> K fooo(){return null;}
static int foooI(){return 0;}
interface I<X> {
X foo(X x);
}
interface I1<X> {
int foo(X x);
}
interface I2<X> {
X foo(int x);
}
}
class TypeArgsConsistency3 {
public static void main(String[] args) {
doIt1(1, x -> doIt1(x, y -> x * y));
doIt1(1, x -> x);
doIt1(1, x -> x * x);
}
interface F1<ResultType, P1> { ResultType _(P1 p); }
static <T> T doIt1(T i, F1<T,T> f) { return f._(i);}
}
@@ -0,0 +1,94 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.List;
class Test1 {
interface I<X> {
X foo(List<String> list);
}
static <T> I<T> bar(I<T> i){return i;}
static <T> void bar1(I<T> i){}
static <T> void bar2(T t, I<T> i){}
static <T> void bar3(I<T> i, T t){}
{
bar(x -> x);
bar1(x -> x);
I<Object> lO = x->x;
bar2("", lO);
<error descr="Incompatible types. Found: '<lambda expression>', required: 'Test1.I<java.lang.String>'">I<String> lS = x->x;</error>
bar2("", lS);
bar2("", x -> x);
bar3(x -> x, "");
int ixc = 42;
bar(x -> {
if (ixc == 2) return "aaa";
return x;
});
bar(x -> {
if (ixc == 2) return x;
return x;
});
}
}
class Test2 {
interface I<X> {
X foo(List<X> list);
}
static <T> I<T> bar(I<T> i){return i;}
static <T> void bar1(I<T> i){}
static <T> void bar2(T t, I<T> i){}
static <T> void bar3(I<T> i, T t){}
{
bar(<error descr="Cyclic inference">x -> x</error>);
bar1(<error descr="Cyclic inference">x -> x</error>);
bar2<error descr="'bar2(java.lang.Integer, Test2.I<java.lang.Integer>)' in 'Test2' cannot be applied to '(int, <lambda expression>)'">(1, x -> x)</error>;
bar2<error descr="'bar2(java.lang.String, Test2.I<java.lang.String>)' in 'Test2' cannot be applied to '(java.lang.String, <lambda expression>)'">("", x -> x)</error>;
bar3<error descr="'bar3(Test2.I<java.lang.String>, java.lang.String)' in 'Test2' cannot be applied to '(<lambda expression>, java.lang.String)'">(x -> x, "")</error>;
}
}
class Test3 {
interface I<X> {
List<X> foo(List<X> list);
}
static <T> I<T> bar(I<T> i){return i;}
static <T> void bar1(I<T> i){}
static <T> void bar2(T t, I<T> i){}
static <T> void bar3(I<T> i, T t){}
{
bar(<error descr="Cyclic inference">x -> x</error>);
bar1(<error descr="Cyclic inference">x -> x</error>);
bar2(1, x -> x);
bar2("", x -> x);
bar3(x -> x, "");
}
}
@@ -0,0 +1,36 @@
import java.util.*;
class Test4 {
interface I<K> {
List<K> foo();
}
static <T> void bar(I<T> i){}
{
bar(() -> null);
}
}
class Test5 {
interface I<K> {
void foo(K k);
}
static <T> void bar(I<T> i){}
{
bar<error descr="'bar(Test5.I<T>)' in 'Test5' cannot be applied to '(<lambda expression>)'">(() -> null)</error>;
}
}
class Test6 {
interface I<K> {
void foo();
}
static <T> void bar(I<T> i){}
{
bar<error descr="'bar(Test6.I<java.lang.Object>)' in 'Test6' cannot be applied to '(<lambda expression>)'">(() -> null)</error>;
bar(() -> {});
}
}
@@ -45,6 +45,14 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testTypeArgsConsistencyMisc1() throws Exception {
doTest();
}
public void testTypeArgsConsistencyWithoutParams() throws Exception {
doTest();
}
public void testWildcardBounds() throws Exception {
doTest();
}
@@ -1,7 +1,7 @@
package org.jetbrains.jps.incremental;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.jps.idea.OwnServiceLoader;
import org.jetbrains.jps.service.JpsServiceManager;
import java.util.*;
@@ -25,9 +25,7 @@ public class BuilderRegistry {
myModuleLevelBuilders.put(category, new ArrayList<ModuleLevelBuilder>());
}
final OwnServiceLoader<BuilderService> loader = OwnServiceLoader.load(BuilderService.class);
for (BuilderService service : loader) {
for (BuilderService service : JpsServiceManager.getInstance().getExtensions(BuilderService.class)) {
myProjectLevelBuilders.addAll(service.createProjectLevelBuilders());
final List<? extends ModuleLevelBuilder> moduleLevelBuilders = service.createModuleLevelBuilders();
for (ModuleLevelBuilder builder : moduleLevelBuilders) {
@@ -5,13 +5,13 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ClassMap;
import org.jetbrains.jps.JpsPathUtil;
import org.jetbrains.jps.idea.OwnServiceLoader;
import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactCompilerInstructionCreator;
import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactInstructionsBuilderContext;
import org.jetbrains.jps.model.artifact.JpsArtifact;
import org.jetbrains.jps.model.artifact.elements.*;
import org.jetbrains.jps.model.java.JpsProductionModuleOutputPackagingElement;
import org.jetbrains.jps.model.java.JpsTestModuleOutputPackagingElement;
import org.jetbrains.jps.service.JpsServiceManager;
import java.io.File;
import java.util.List;
@@ -42,7 +42,7 @@ public class LayoutElementBuildersRegistry {
for (LayoutElementBuilderService<?> builder : standardBuilders) {
myBuilders.put(builder.getElementClass(), builder);
}
for (LayoutElementBuilderService builder : OwnServiceLoader.load(LayoutElementBuilderService.class)) {
for (LayoutElementBuilderService builder : JpsServiceManager.getInstance().getExtensions(LayoutElementBuilderService.class)) {
myBuilders.put(builder.getElementClass(), builder);
}
}
-19
View File
@@ -3,7 +3,6 @@
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
@@ -11,29 +10,11 @@
<orderEntry type="library" name="Groovy" level="project" />
<orderEntry type="library" name="Ant" level="project" />
<orderEntry type="module" module-name="antlayout" />
<orderEntry type="module-library" exported="" scope="PROVIDED">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/gant-1.9.5_groovy-1.7.10.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="library" name="asm4" level="project" />
<orderEntry type="module" module-name="jps-model" exported="" />
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
<orderEntry type="module" module-name="util" />
<orderEntry type="module" module-name="javac2" />
<orderEntry type="module-library" scope="TEST">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/junit-addons-1.4.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module" module-name="instrumentation-util" />
</component>
</module>
@@ -18,7 +18,7 @@ public abstract class JpsServiceManager {
private static final JpsServiceManager INSTANCE;
static {
INSTANCE = ServiceLoader.load(JpsServiceManager.class).iterator().next();
INSTANCE = ServiceLoader.load(JpsServiceManager.class, JpsServiceManager.class.getClassLoader()).iterator().next();
}
}
}
@@ -17,7 +17,7 @@ public class JpsServiceManagerImpl extends JpsServiceManager {
//noinspection unchecked
T service = (T)myServices.get(serviceClass);
if (service == null) {
final Iterator<T> iterator = ServiceLoader.load(serviceClass).iterator();
final Iterator<T> iterator = ServiceLoader.load(serviceClass, serviceClass.getClassLoader()).iterator();
if (!iterator.hasNext()) {
throw new ServiceConfigurationError("Implementation for " + serviceClass + " not found");
}
@@ -37,7 +37,7 @@ public class JpsServiceManagerImpl extends JpsServiceManager {
public <T> Iterable<T> getExtensions(Class<T> extensionClass) {
List<?> cached = myExtensions.get(extensionClass);
if (cached == null) {
final ServiceLoader<T> loader = ServiceLoader.load(extensionClass);
final ServiceLoader<T> loader = ServiceLoader.load(extensionClass, extensionClass.getClassLoader());
List<T> extensions = new ArrayList<T>();
for (T t : loader) {
extensions.add(t);
@@ -12,6 +12,20 @@ public class IdeaProjectLoader {
private ProjectLoadingErrorReporter errorReporter
private final XmlParser xmlParser = new XmlParser(false, false)
public static String guessHome(Script script) {
File home = new File(script["gant.file"].substring("file:".length()))
while (home != null) {
if (home.isDirectory()) {
if (new File(home, ".idea").exists()) return home.getCanonicalPath()
}
home = home.getParentFile()
}
return null
}
public static ProjectMacroExpander loadFromPath(Project project, String path, Map<String, String> pathVariables) {
return loadFromPath(project, path, pathVariables, "")
}
@@ -1,25 +0,0 @@
package org.jetbrains.jps.idea;
import java.util.Iterator;
/**
* This class should be used instead of {@link java.util.ServiceLoader} because the standard ServiceLoader
* is not available in JDK 1.5
*
* @author nik
*/
public class OwnServiceLoader<S> implements Iterable<S> {
private Class<S> serviceClass;
private OwnServiceLoader(Class<S> serviceClass) {
this.serviceClass = serviceClass;
}
public static <S> OwnServiceLoader<S> load(Class<S> serviceClass) {
return new OwnServiceLoader<S>(serviceClass);
}
public Iterator<S> iterator() {
return sun.misc.Service.providers(serviceClass);
}
}
+16
View File
@@ -0,0 +1,16 @@
def ctx = context(scope: scriptScope(), filetypes : ["gant"])
contributor ([ctx], {
property name:"project", type:"org.jetbrains.jps.model.JpsProject"
property name:"global", type:"org.jetbrains.jps.model.JpsGlobal"
property name:"projectBuilder", type:"org.jetbrains.jps.gant.JpsGantProjectBuilder"
method name:"jdk", type:"void", params:[name:"String", jdkPath:"String"]
method name:"jdk", type:"void", params:[name:"String", jdkPath:"String", initializer:{}]
method name:"layout", type:"org.jetbrains.jps.gant.LayoutInfo", params: [name:"String", layout:{}]
method name:"module", type:"void", params: [name:"String"]
method name:"module", type:"void", params: [name:"String", layout:{}]
["jar", "dir", "zip"].each { methodName ->
method name:methodName, type:"void", params: [name:"String", layout:{}]
}
})
@@ -104,16 +104,8 @@ public class Standalone {
return;
}
runBuild(loader, dataStorageRoot, buildType, modulesSet, artifactsList, true);
}
public static void runBuild(JpsModelLoader loader, final File dataStorageRoot, BuildType buildType, Set<String> modulesSet,
List<String> artifactsList, final boolean includeTests) {
final BuildRunner buildRunner = new BuildRunner(loader, modulesSet, buildType, artifactsList, Collections.<String>emptyList(), Collections.<String, String>emptyMap());
final ConsoleMessageHandler messageHandler = new ConsoleMessageHandler();
try {
ProjectDescriptor descriptor = buildRunner.load(messageHandler, dataStorageRoot, new BuildFSState(true));
buildRunner.runBuild(descriptor, CanceledStatus.NULL, null, messageHandler, includeTests);
runBuild(loader, dataStorageRoot, buildType, modulesSet, artifactsList, true, new ConsoleMessageHandler());
}
catch (Throwable t) {
System.err.println("Internal error: " + t.getMessage());
@@ -121,6 +113,13 @@ public class Standalone {
}
}
public static void runBuild(JpsModelLoader loader, final File dataStorageRoot, BuildType buildType, Set<String> modulesSet,
List<String> artifactsList, final boolean includeTests, final MessageHandler messageHandler) throws Exception {
final BuildRunner buildRunner = new BuildRunner(loader, modulesSet, buildType, artifactsList, Collections.<String>emptyList(), Collections.<String, String>emptyMap());
ProjectDescriptor descriptor = buildRunner.load(messageHandler, dataStorageRoot, new BuildFSState(true));
buildRunner.runBuild(descriptor, CanceledStatus.NULL, null, messageHandler, includeTests);
}
private static class ConsoleMessageHandler implements MessageHandler {
@Override
public void processMessage(BuildMessage msg) {
@@ -0,0 +1,24 @@
package org.jetbrains.jps.gant;
/**
* @author nik
*/
public class DefaultBuildInfoPrinter implements BuildInfoPrinter {
@Override
public void printProgressMessage(JpsGantProjectBuilder project, String message) {
project.info(message);
}
@Override
public void printCompilationErrors(JpsGantProjectBuilder project, String compilerName, String messages) {
project.error(messages);
}
@Override
public void printCompilationFinish(JpsGantProjectBuilder project, String compilerName) {
}
@Override
public void printCompilationStart(JpsGantProjectBuilder project, String compilerName) {
}
}
@@ -1,11 +1,18 @@
package org.jetbrains.jps.gant;
import com.intellij.openapi.diagnostic.DefaultLogger;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.api.BuildType;
import org.jetbrains.jps.build.Standalone;
import org.jetbrains.jps.cmdline.JpsModelLoader;
import org.jetbrains.jps.incremental.MessageHandler;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.java.JpsJavaClasspathKind;
import org.jetbrains.jps.model.java.JpsJavaDependenciesEnumerator;
@@ -26,7 +33,7 @@ public class JpsGantProjectBuilder {
private File myDataStorageRoot;
private JpsModelLoader myModelLoader;
private boolean myDryRun;
private BuildInfoPrinter myBuildInfoPrinter;
private BuildInfoPrinter myBuildInfoPrinter = new DefaultBuildInfoPrinter();
public JpsGantProjectBuilder(Project project, JpsModel model, org.jetbrains.jps.Project oldProject) {
myProject = project;
@@ -66,11 +73,11 @@ public class JpsGantProjectBuilder {
myBuildInfoPrinter = printer;
}
public void setUseInProcessJavac() {
public void setUseInProcessJavac(boolean value) {
//doesn't make sense for new builders
}
public void setArrangeModuleCyclesOutputs() {
public void setArrangeModuleCyclesOutputs(boolean value) {
//doesn't make sense for new builders
}
@@ -78,6 +85,10 @@ public class JpsGantProjectBuilder {
throw new BuildException(message);
}
public void error(Throwable t) {
throw new BuildException(t);
}
public void warning(String message) {
myProject.log(message, Project.MSG_WARN);
}
@@ -87,12 +98,11 @@ public class JpsGantProjectBuilder {
}
public void stage(String message) {
if (myBuildInfoPrinter != null) {
myBuildInfoPrinter.printProgressMessage(this, message);
}
else {
myProject.log(message, Project.MSG_INFO);
}
myBuildInfoPrinter.printProgressMessage(this, message);
}
public File getDataStorageRoot() {
return myDataStorageRoot;
}
public void setDataStorageRoot(File dataStorageRoot) {
@@ -151,15 +161,30 @@ public class JpsGantProjectBuilder {
private void runBuild(final Set<String> modulesSet, boolean includeTests) {
if (!myDryRun) {
info("Starting build, caches are saved to " + myDataStorageRoot.getAbsolutePath());
Standalone.runBuild(myModelLoader, myDataStorageRoot, BuildType.PROJECT_REBUILD, modulesSet, Collections.<String>emptyList(),
includeTests);
final AntMessageHandler messageHandler = new AntMessageHandler();
Logger.setFactory(new AntLoggerFactory(messageHandler));
info("Starting build: modules = " + modulesSet + ", caches are saved to " + myDataStorageRoot.getAbsolutePath());
try {
Standalone.runBuild(myModelLoader, myDataStorageRoot, BuildType.PROJECT_REBUILD, modulesSet, Collections.<String>emptyList(),
includeTests, messageHandler);
}
catch (Throwable e) {
error(e);
}
}
else {
info("Building skipped as we're running dry");
}
}
public String moduleOutput(JpsModule module) {
return getModuleOutput(module, false);
}
public String moduleTestsOutput(JpsModule module) {
return getModuleOutput(module, true);
}
public String getModuleOutput(JpsModule module, boolean forTests) {
File directory = JpsJavaExtensionService.getInstance().getOutputDirectory(module, forTests);
return directory != null ? directory.getAbsolutePath() : null;
@@ -174,4 +199,59 @@ public class JpsGantProjectBuilder {
}
return result;
}
private class AntMessageHandler implements MessageHandler {
@Override
public void processMessage(BuildMessage msg) {
BuildMessage.Kind kind = msg.getKind();
String text = msg.getMessageText();
switch (kind) {
case ERROR:
String compilerName = msg instanceof CompilerMessage ? ((CompilerMessage)msg).getCompilerName() : "";
myBuildInfoPrinter.printCompilationErrors(JpsGantProjectBuilder.this, compilerName, text);
break;
case WARNING:
warning(text);
break;
case INFO:
if (!text.isEmpty()) {
info(text);
}
break;
case PROGRESS:
myBuildInfoPrinter.printProgressMessage(JpsGantProjectBuilder.this, text);
break;
}
}
}
private class AntLoggerFactory implements Logger.Factory {
private static final String COMPILER_NAME = "build runner";
private final AntMessageHandler myMessageHandler;
public AntLoggerFactory(AntMessageHandler messageHandler) {
myMessageHandler = messageHandler;
}
@Override
public Logger getLoggerInstance(String category) {
return new DefaultLogger(category) {
@Override
public void error(@NonNls String message, @Nullable Throwable t, @NonNls String... details) {
if (t != null) {
myMessageHandler.processMessage(new CompilerMessage(COMPILER_NAME, t));
}
else {
myMessageHandler.processMessage(new CompilerMessage(COMPILER_NAME, BuildMessage.Kind.ERROR, message));
}
}
@Override
public void warn(@NonNls String message, @Nullable Throwable t) {
myMessageHandler.processMessage(new CompilerMessage(COMPILER_NAME, BuildMessage.Kind.WARNING, message));
}
};
}
}
}
@@ -89,7 +89,10 @@ final class JpsGantTool {
IdeaProjectLoader.loadFromPath(oldProject, path, [:])
JpsProjectLoader.loadProject(model.project, [:], path)
builder.exportModuleOutputProperties();
builder.setDataStorageRoot(Utils.getDataStorageRoot(path))
if (builder.getDataStorageRoot() == null) {
builder.setDataStorageRoot(Utils.getDataStorageRoot(path))
}
builder.info("Loaded project " + path + ": " + model.getProject().getModules().size() + " modules, " + model.getProject().getLibraryCollection().getLibraries().size() + " libraries")
}
private void createJavaSdk(JpsGlobal global, String name, String homePath, Closure initializer) {
@@ -1,14 +0,0 @@
package org.jetbrains.jps.idea;
import groovy.lang.Script;
import org.jetbrains.jps.gant.JpsGantTool;
/**
* @author nik
*/
public class IdeaProjectLoader {
//todo[nik] inline this method later
public static String guessHome(Script script) {
return JpsGantTool.guessHome(script);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -42,7 +42,9 @@ public abstract class RelatedItemLineMarkerProvider implements LineMarkerProvide
public void collectNavigationMarkers(List<PsiElement> elements,
Collection<? super RelatedItemLineMarkerInfo> result,
boolean forNavigation) {
for (PsiElement element : elements) {
//noinspection ForLoopReplaceableByForEach
for (int i = 0, size = elements.size(); i < size; i++) {
PsiElement element = elements.get(i);
collectNavigationMarkers(element, result);
if (forNavigation && element instanceof PsiNameIdentifierOwner) {
PsiElement nameIdentifier = ((PsiNameIdentifierOwner)element).getNameIdentifier();
@@ -129,7 +129,13 @@ public abstract class RemoteProcessSupport<Target, EntryPoint, Parameters> {
}
if (ref.isNull()) throw new RuntimeException("Unable to acquire remote proxy for: " + getName(target));
RunningInfo info = ref.get();
if (info.handler == null) throw new ExecutionException(info.name);
if (info.handler == null) {
String message = info.name;
if (message != null && message.startsWith("ERROR: transport error 202:")) {
message = "Unable to start java process in debug mode: -Xdebug parameters are already in use.";
}
throw new ExecutionException(message);
}
return acquire(info);
}
@@ -66,7 +66,10 @@ class EditBookmarkDescriptionAction extends DumbAwareAction {
BookmarkManager.getInstance(myProject).setDescription(b, description);
myPopup.setUiVisible(true);
myPopup.setSize(myPopup.getContent().getPreferredSize());
final JComponent content = myPopup.getContent();
if (content != null) {
myPopup.setSize(content.getPreferredSize());
}
}
public void setPopup(JBPopup popup) {
@@ -20,6 +20,7 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.LineSeparator;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nullable;
@@ -128,6 +129,14 @@ public abstract class DiffContent {
return new DocumentContent(project, document);
}
/**
* @return line separator used in this content, or null if it is unknown.
*/
@Nullable
public LineSeparator getLineSeparator() {
return null;
}
public interface Listener {
void contentInvalid();
}
@@ -21,6 +21,7 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.LineSeparator;
import org.jetbrains.annotations.NotNull;
public class DocumentContent extends DiffContent {
@@ -28,6 +29,7 @@ public class DocumentContent extends DiffContent {
private final VirtualFile myFile;
private final FileType myOverridenType;
private Project myProject;
private FileDocumentManager myDocumentManager;
public DocumentContent(Project project, Document document) {
this(project, document, null);
@@ -36,7 +38,8 @@ public class DocumentContent extends DiffContent {
public DocumentContent(Project project, @NotNull Document document, FileType type) {
myProject = project;
myDocument = document;
myFile = FileDocumentManager.getInstance().getFile(document);
myDocumentManager = FileDocumentManager.getInstance();
myFile = myDocumentManager.getFile(document);
myOverridenType = type;
}
@@ -70,4 +73,10 @@ public class DocumentContent extends DiffContent {
public byte[] getBytes() {
return myDocument.getText().getBytes();
}
@NotNull
@Override
public LineSeparator getLineSeparator() {
return LineSeparator.fromString(myDocumentManager.getLineSeparator(myFile, myProject));
}
}
@@ -24,6 +24,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.LineSeparator;
import org.jetbrains.annotations.NotNull;
import java.io.File;
@@ -34,10 +35,12 @@ public class FileContent extends DiffContent {
private final VirtualFile myFile;
private Document myDocument;
private final Project myProject;
private final FileDocumentManager myDocumentManager;
public FileContent(Project project, @NotNull VirtualFile file) {
myProject = project;
myFile = file;
myDocumentManager = FileDocumentManager.getInstance();
}
public Document getDocument() {
@@ -82,4 +85,11 @@ public class FileContent extends DiffContent {
}
throw new IOException("Can not create temp file for revision content");
}
@NotNull
@Override
public LineSeparator getLineSeparator() {
return LineSeparator.fromString(myDocumentManager.getLineSeparator(myFile, myProject));
}
}
@@ -23,6 +23,7 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.LineSeparator;
import com.intellij.util.SystemProperties;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -135,6 +136,12 @@ public class SimpleContent extends DiffContent {
}
}
@NotNull
@Override
public LineSeparator getLineSeparator() {
return LineSeparator.fromString(myLineSeparators.mySeparator);
}
public Charset getCharset() {
return myCharset;
}
@@ -17,6 +17,7 @@ package com.intellij.codeStyle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.colors.impl.BundledColorSchemesProvider;
import com.intellij.util.PlatformUtils;
/**
* @author Konstantin Bulenkov
@@ -29,7 +30,9 @@ public class IdeaColorSchemesProvider implements BundledColorSchemesProvider {
@Override
public String[] getBundledSchemesRelativePaths() {
if (ApplicationManager.getApplication().isUnitTestMode()) return null;
return PATHS;
if (PlatformUtils.isCommunity() || PlatformUtils.isIdea()) return PATHS;
return null;
}
@Override
@@ -42,6 +42,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.FileStatusManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFilePathWrapper;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
@@ -365,7 +366,7 @@ public class Switcher extends AnAction implements DumbAware {
filesModel.addElement(editor);
}
final VirtualFilesRenderer filesRenderer = new VirtualFilesRenderer(project, pinned) {
final VirtualFilesRenderer filesRenderer = new VirtualFilesRenderer(project) {
JPanel myPanel = new JPanel(new BorderLayout());
JLabel myLabel = new JLabel() {
@Override
@@ -977,20 +978,20 @@ public class Switcher extends AnAction implements DumbAware {
private static class VirtualFilesRenderer extends ColoredListCellRenderer {
private final Project myProject;
private final boolean myPinned;
boolean open;
public VirtualFilesRenderer(Project project, boolean pinned) {
public VirtualFilesRenderer(Project project) {
myProject = project;
myPinned = pinned;
}
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
if (value instanceof FileInfo) {
VirtualFile virtualFile = ((FileInfo)value).getFirst();
String name = UISettings.getInstance().SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES
? UniqueVFilePathBuilder.getInstance().getUniqueVirtualFilePath(myProject, virtualFile)
: virtualFile.getName();
String name = virtualFile instanceof VirtualFilePathWrapper
? ((VirtualFilePathWrapper)virtualFile).getPresentablePath()
: UISettings.getInstance().SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES
? UniqueVFilePathBuilder.getInstance().getUniqueVirtualFilePath(myProject, virtualFile)
: virtualFile.getName();
setIcon(IconUtil.getIcon(virtualFile, Iconable.ICON_FLAG_READ_STATUS, myProject));
FileStatus fileStatus = FileStatusManager.getInstance(myProject).getStatus(virtualFile);
@@ -18,9 +18,7 @@ package com.intellij.openapi.diff.impl;
import com.intellij.execution.ui.RunnerLayoutUi;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.diff.DiffRequest;
import com.intellij.openapi.diff.DiffViewer;
import com.intellij.openapi.diff.DiffViewerType;
import com.intellij.openapi.diff.*;
import com.intellij.openapi.diff.impl.external.DiscloseMultiRequest;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
@@ -97,6 +95,7 @@ public class CompositeDiffPanel implements DiffViewer {
if (myMap.isEmpty()) {
final EmptyDiffViewer emptyDiffViewer = new EmptyDiffViewer();
emptyDiffViewer.setDiffRequest(request);
myMap.put(FICTIVE_KEY, emptyDiffViewer);
final Content content = myUi.createContent(FICTIVE_KEY, emptyDiffViewer.getComponent(), FICTIVE_KEY, null,
emptyDiffViewer.getPreferredFocusedComponent());
@@ -48,7 +48,6 @@ import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
import com.intellij.openapi.editor.ex.EditorMarkupModel;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.UIBasedFileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Getter;
@@ -61,6 +60,7 @@ import com.intellij.pom.Navigatable;
import com.intellij.ui.EditorNotificationPanel;
import com.intellij.ui.PopupHandler;
import com.intellij.ui.border.CustomLineBorder;
import com.intellij.util.LineSeparator;
import com.intellij.util.containers.CacheOneStepIterator;
import com.intellij.util.containers.Convertor;
import com.intellij.util.diff.FilesTooBigForDiffException;
@@ -120,8 +120,8 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
myOwnerWindow = owner;
myIsSyncScroll = true;
final boolean v = !horizontal;
myLeftSide = new DiffSideView("", this, new CustomLineBorder(UIUtil.getBorderColor(), 1, 0, v ? 0 : 1, v ? 0 : 1));
myRightSide = new DiffSideView("", this, new CustomLineBorder(UIUtil.getBorderColor(), v ? 0 : 1, v ? 0 : 1, 1, 0));
myLeftSide = new DiffSideView(this, new CustomLineBorder(UIUtil.getBorderColor(), 1, 0, v ? 0 : 1, v ? 0 : 1));
myRightSide = new DiffSideView(this, new CustomLineBorder(UIUtil.getBorderColor(), v ? 0 : 1, v ? 0 : 1, 1, 0));
myLeftSide.becomeMaster();
myDiffUpdater = new Rediffers(this);
@@ -307,11 +307,35 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
}
public void setTitle1(String title) {
myLeftSide.setTitle(title);
setTitle(title, true);
}
private void setTitle(String title, boolean left) {
Editor editor = left ? getEditor1() : getEditor2();
if (editor == null) return;
title = addReadOnly(title, editor);
JLabel label = new JLabel(title);
if (left) {
myLeftSide.setTitle(label);
}
else {
myRightSide.setTitle(label);
}
}
private static String addReadOnly(@NotNull String title, @Nullable Editor editor) {
if (editor == null) {
return title;
}
boolean readonly = editor.isViewer() || !editor.getDocument().isWritable();
if (readonly) {
title += " " + DiffBundle.message("diff.content.read.only.content.title.suffix");
}
return title;
}
public void setTitle2(String title) {
myRightSide.setTitle(title);
setTitle(title, false);
}
private void setLineBlocks(LineBlocks blocks) {
@@ -490,6 +514,18 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
public LineBlocks getLineBlocks() { return myLineBlocks; }
static JComponent createComponentForTitle(@NotNull String title, @NotNull final LineSeparator separator, boolean left) {
JPanel bottomPanel = new JPanel(new BorderLayout());
JLabel sepLabel = new JLabel(separator.name());
sepLabel.setForeground(separator.equals(LineSeparator.CRLF) ? Color.RED : Color.BLUE);
bottomPanel.add(sepLabel, left ? BorderLayout.EAST : BorderLayout.WEST);
JPanel panel = new JPanel(new BorderLayout());
panel.add(new JLabel(title));
panel.add(bottomPanel, BorderLayout.SOUTH);
return panel;
}
public void setDiffRequest(DiffRequest data) {
myDiffRequest = data;
if (data.getHints().contains(DiffTool.HINT_DO_NOT_IGNORE_WHITESPACES)) {
@@ -497,24 +533,13 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
}
myDataProvider.putData(myDiffRequest.getGenericData());
IdeFocusManager fm = IdeFocusManager.getInstance(myProject);
boolean isEditor1Focused = getEditor1() != null
&& fm.getFocusedDescendantFor(getEditor1().getComponent()) != null;
DiffContent content1 = data.getContents()[0];
DiffContent content2 = data.getContents()[1];
boolean isEditor2Focused = myData.getContent2() != null
&& getEditor2() != null
&& fm.getFocusedDescendantFor(getEditor2().getComponent()) != null;
setContents(content1, content2);
setTitles(data);
setContents(data.getContents()[0], data.getContents()[1]);
setTitle1(data.getContentTitles()[0]);
setTitle2(data.getContentTitles()[1]);
setWindowTitle(myOwnerWindow, data.getWindowTitle());
//if (isBinaryOrUIEditors(data)) {
// myPanel.removeStatusBar();
// //myPanel.disableToolbar(true);
//} else {
// myPanel.addStatusBar();
//}
data.customizeToolbar(myPanel.resetToolbar());
myPanel.registerToolbarActions();
@@ -527,6 +552,14 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
if (myIsRequestFocus) {
IdeFocusManager fm = IdeFocusManager.getInstance(myProject);
boolean isEditor1Focused = getEditor1() != null
&& fm.getFocusedDescendantFor(getEditor1().getComponent()) != null;
boolean isEditor2Focused = myData.getContent2() != null
&& getEditor2() != null
&& fm.getFocusedDescendantFor(getEditor2().getComponent()) != null;
if (isEditor1Focused || isEditor2Focused) {
Editor e = isEditor2Focused ? getEditor2() : getEditor1();
if (e != null) {
@@ -538,12 +571,29 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
}
}
private boolean isBinaryOrUIEditors(DiffRequest data) {
final DiffContent[] contents = data.getContents();
return contents[0].isBinary()
|| contents[1].isBinary()
|| contents[0].getContentType() instanceof UIBasedFileType
|| contents[1].getContentType() instanceof UIBasedFileType;
private void setTitles(@NotNull DiffRequest data) {
LineSeparator sep1 = data.getContents()[0].getLineSeparator();
LineSeparator sep2 = data.getContents()[1].getLineSeparator();
String title1 = addReadOnly(data.getContentTitles()[0], myLeftSide.getEditor());
String title2 = addReadOnly(data.getContentTitles()[1], myRightSide.getEditor());
if (sep1 != null && sep2 != null && !sep1.equals(sep2)) {
setTitle1(createComponentForTitle(title1, sep1, true));
setTitle2(createComponentForTitle(title2, sep2, false));
}
else {
setTitle1(title1);
setTitle2(title2);
}
}
private void setTitle1(JComponent title) {
myLeftSide.setTitle(title);
}
private void setTitle2(JComponent title) {
myRightSide.setTitle(title);
}
private static void setWindowTitle(Window window, String title) {
@@ -37,6 +37,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.util.IJSwingUtilities;
import com.intellij.util.ui.ScrollUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -60,19 +61,14 @@ public class DiffSideView {
private DiffHighlighterFactory myHighlighterFactory = DUMMY_HIGHLIGHTER_FACTORY;
private EditorSource myEditorSource = EditorSource.NULL;
private boolean myIsMaster = false;
private String myTitle;
private JComponent myTitle = new JLabel();
public DiffSideView(String title, DiffSidesContainer container, @Nullable Border editorBorder) {
myTitle = title;
public DiffSideView(DiffSidesContainer container, @Nullable Border editorBorder) {
myContainer = container;
myPanel = new LabeledEditor(editorBorder);
insertComponent(MOCK_COMPONENT);
}
public DiffSideView(String title, DiffSidesContainer container) {
this(title, container, null);
}
public JComponent getComponent() {
return myPanel;
}
@@ -127,12 +123,9 @@ public class DiffSideView {
editor.getColorsScheme().setColor(EditorColors.CARET_ROW_COLOR, null);
}
public void setTitle(String title) {
public void setTitle(@NotNull JComponent title) {
myTitle = title;
Editor editor = getEditor();
if (editor == null) return;
boolean readonly = editor.isViewer() || !editor.getDocument().isWritable();
myPanel.updateTitle(myTitle, readonly);
myPanel.updateTitle(myTitle);
}
private void setMouseListeners(EditorSource source) {
@@ -15,38 +15,84 @@
*/
package com.intellij.openapi.diff.impl;
import com.intellij.openapi.diff.DiffBundle;
import com.intellij.openapi.diff.DiffRequest;
import com.intellij.openapi.diff.DiffViewer;
import com.intellij.openapi.diff.DiffViewerType;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.openapi.diff.*;
import com.intellij.openapi.ui.Splitter;
import com.intellij.util.LineSeparator;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
/**
* Created with IntelliJ IDEA.
* User: Irina.Chernushina
* Date: 3/7/12
* Time: 7:45 PM
* This viewer is shown, when the compared contents are equal or differ only in line separators.
*
* @author Irina.Chernushina
* @author Kirill Likhodedov
*/
public class EmptyDiffViewer implements DiffViewer {
private DiffRequest myRequest;
@Override
public void setDiffRequest(DiffRequest request) {
myRequest = request;
}
@Override
public JComponent getComponent() {
final JLabel label = new JLabel(DiffBundle.message("diff.contents.are.identical.message.text"));
DiffContent content1 = myRequest.getContents()[0];
DiffContent content2 = myRequest.getContents()[1];
LineSeparator sep1 = content1.getLineSeparator();
LineSeparator sep2 = content2.getLineSeparator();
final JPanel messagePanel = createMessagePanel(sep1, sep2);
if (LineSeparator.knownAndDifferent(sep1, sep2)) {
assert sep1 != null && sep2 != null: "Separators should have been checked for nullity. sep1: " + sep1 + ", sep2: " + sep2;
JComponent title1 = createTitleComponent(myRequest.getContentTitles()[0], sep1, true);
JComponent title2 = createTitleComponent(myRequest.getContentTitles()[1], sep2, false);
Splitter titlePanel = new Splitter(false, 0.5F, 0.5F, 0.5F);
titlePanel.setFirstComponent(title1);
titlePanel.setSecondComponent(title2);
titlePanel.setDividerWidth(1);
JPanel rootPanel = new JPanel(new BorderLayout());
rootPanel.add(titlePanel, BorderLayout.NORTH);
rootPanel.add(messagePanel);
return rootPanel;
}
else {
return messagePanel;
}
}
@NotNull
private static JPanel createMessagePanel(@Nullable LineSeparator sep1, @Nullable LineSeparator sep2) {
String message;
if (LineSeparator.knownAndDifferent(sep1, sep2)) {
message = DiffBundle.message("diff.contents.have.differences.only.in.line.separators.message.text");
}
else {
message = DiffBundle.message("diff.contents.are.identical.message.text");
}
final JLabel label = new JLabel(message);
label.setForeground(UIUtil.getInactiveTextColor());
final JPanel wrapper = new JPanel(new GridBagLayout());
wrapper.add(label, new GridBagConstraints(0,0,1,1,0,0,GridBagConstraints.CENTER, GridBagConstraints.NONE,
new Insets(1,1,1,1), 0,0));
wrapper.add(label, new GridBagConstraints(0,0,1,1,0,0,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(1,1,1,1), 0,0));
return wrapper;
}
private static JComponent createTitleComponent(String title, LineSeparator sep1, boolean left) {
JComponent panel = DiffPanelImpl.createComponentForTitle(title, sep1, left);
panel.setBorder(BorderFactory.createEmptyBorder(UIUtil.DEFAULT_VGAP, UIUtil.DEFAULT_HGAP, UIUtil.DEFAULT_VGAP, UIUtil.DEFAULT_HGAP));
return panel;
}
@Nullable
@Override
public JComponent getPreferredFocusedComponent() {
@@ -15,7 +15,7 @@
*/
package com.intellij.openapi.diff.impl.util;
import com.intellij.openapi.diff.DiffBundle;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -23,12 +23,12 @@ import javax.swing.border.Border;
import java.awt.*;
public class LabeledEditor extends JPanel {
private final JLabel myLabel = new JLabel();
private final Border myEditorBorder;
private JComponent myMainComponent;
public LabeledEditor(@Nullable Border editorBorder) {
super(new BorderLayout());
myLabel.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0));
myEditorBorder = editorBorder;
}
@@ -36,31 +36,25 @@ public class LabeledEditor extends JPanel {
this(null);
}
private static String addReadOnly(String title, boolean readonly) {
if (readonly) title += " " + DiffBundle.message("diff.content.read.only.content.title.suffix");
return title;
}
public void setComponent(JComponent component, String title) {
public void setComponent(@NotNull JComponent component, @NotNull JComponent titleComponent) {
myMainComponent = component;
removeAll();
JPanel title = new JPanel(new BorderLayout());
title.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0));
title.add(titleComponent);
revalidate();
final JPanel p = new JPanel(new BorderLayout());
if (myEditorBorder != null) {
p.setBorder(myEditorBorder);
}
p.add(component, BorderLayout.CENTER);
add(p, BorderLayout.CENTER);
add(myLabel, BorderLayout.NORTH);
setLabelTitle(title);
revalidate();
add(title, BorderLayout.NORTH);
}
private void setLabelTitle(String title) {
myLabel.setText(title);
myLabel.setToolTipText(title);
}
public void updateTitle(String title, boolean readonly) {
setLabelTitle(addReadOnly(title, readonly));
public void updateTitle(JComponent title) {
setComponent(myMainComponent, title);
}
}
@@ -127,7 +127,6 @@ public class FSRecords implements Forceable {
w.lock();
if (!ourInitialized) {
init();
scanFreeRecords();
setupFlushing();
ourInitialized = true;
}
@@ -231,8 +230,9 @@ public class FSRecords implements Forceable {
throw new IOException("FS repository wasn't safely shut down");
}
markDirty();
scanFreeRecords();
}
catch (IOException e) {
catch (Exception e) { // IOException, IllegalArgumentException
LOG.info("Filesystem storage is corrupted or does not exist. [Re]Building. Reason: " + e.getMessage());
try {
closeFiles();
@@ -113,6 +113,38 @@ public class UnixProcessManager {
final ProcessInfo processInfo = new ProcessInfo();
final List<Integer> childrenPids = new ArrayList<Integer>();
findChildProcesses(our_pid, process_pid, foundPid, processInfo, childrenPids);
boolean result;
if (!foundPid.isNull()) {
processInfo.killProcTree(foundPid.get(), signal, UNIX_KILLER);
result = true;
}
else {
for (Integer pid : childrenPids) {
processInfo.killProcTree(pid, signal, UNIX_KILLER);
}
result = !childrenPids.isEmpty(); //we've tried to kill at least one process
}
if (result) {
foundPid.set(null);
childrenPids.clear();
findChildProcesses(our_pid, process_pid, foundPid, processInfo, childrenPids);
return foundPid.isNull() && childrenPids.isEmpty(); //all processes have been killed
}
else {
return true; //the parent process was already killed
}
}
private static void findChildProcesses(final int our_pid,
final int process_pid,
final Ref<Integer> foundPid,
final ProcessInfo processInfo, final List<Integer> childrenPids) {
final Ref<Boolean> ourPidFound = Ref.create(false);
processPSOutput(getPSCmd(false), new Processor<String>() {
@Override
public boolean process(String s) {
@@ -127,32 +159,23 @@ public class UnixProcessManager {
childrenPids.add(pid);
}
if (pid == process_pid) {
if (pid == our_pid) {
ourPidFound.set(true);
}
else if (pid == process_pid) {
if (parent_pid == our_pid) {
foundPid.set(pid);
}
else {
throw new IllegalStateException("process is not our child");
throw new IllegalStateException("Process (pid=" + process_pid + ") is not our child(our pid = " + our_pid + ")");
}
}
return false;
}
});
boolean result;
if (!foundPid.isNull()) {
processInfo.killProcTree(foundPid.get(), signal, UNIX_KILLER);
result = true;
if (!ourPidFound.get()) {
throw new IllegalStateException("IDE pid is not found in ps list(" + our_pid + ")");
}
else {
for (Integer pid : childrenPids) {
processInfo.killProcTree(pid, signal, UNIX_KILLER);
}
result = false;
}
//TODO[traff]: check that processes were really terminated.
return result;
}
public static void processPSOutput(String[] cmd, Processor<String> processor) {
@@ -0,0 +1,55 @@
/*
* Copyright 2000-2012 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.util;
import org.jetbrains.annotations.Nullable;
/**
* <p>Identifies a line separator:
* either Unix ({@code \n}), Windows (@{code \r\n}) or (possible not actual anymore) Classic Mac ({@code \r}).</p>
*
* <p>The intention is to use this class everywhere, where a line separator is needed, instead of just Strings.</p>
*
* @author Kirill Likhodedov
*/
public enum LineSeparator {
LF("\n"),
CRLF("\r\n"),
CR("\r");
private final String mySeparatorString;
LineSeparator(String separatorString) {
mySeparatorString = separatorString;
}
public static LineSeparator fromString(String string) {
for (LineSeparator separator : values()) {
if (separator.getSeparatorString().equals(string)) {
return separator;
}
}
throw new IllegalArgumentException("Invalid string for line separator: " + string);
}
public String getSeparatorString() {
return mySeparatorString;
}
public static boolean knownAndDifferent(@Nullable LineSeparator separator1, @Nullable LineSeparator separator2) {
return separator1 != null && separator2 != null && !separator1.equals(separator2);
}
}
@@ -268,8 +268,9 @@ public class DebuggerUIUtil {
editor.setPropertiesPanel(mainPanel);
editor.setShowMoreOptionsLink(true);
final JPanel panel = editor.getMainPanel();
final Balloon balloon = JBPopupFactory.getInstance()
.createDialogBalloonBuilder(editor.getMainPanel(), null)
.createDialogBalloonBuilder(panel, null)
.setHideOnClickOutside(true)
.setCloseButtonEnabled(false)
.setAnimationCycle(0)
@@ -295,7 +296,16 @@ public class DebuggerUIUtil {
balloon.showInCenterOf(component);
}
else {
balloon.show(new RelativePoint(component, whereToShow), Balloon.Position.below);
//todo[kb] modify and move to BalloonImpl?
final Window window = SwingUtilities.windowForComponent(component);
final RelativePoint p = new RelativePoint(component, whereToShow);
if (window != null) {
final RelativePoint point = new RelativePoint(window, new Point(0, 0));
if (p.getScreenPoint().getX() - point.getScreenPoint().getX() < 40) { // triangle + offsets is ~40px
p.getPoint().x += 40;
}
}
balloon.show(p, Balloon.Position.below);
}
BreakpointsMasterDetailPopupFactory.getInstance(project).setBalloonToHide(balloon, breakpoint);
@@ -322,6 +322,14 @@ public class XDebuggerTestUtil {
return breakpoint.get();
}
public static void removeAllBreakpoints(@NotNull final Project project) {
final XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager();
XBreakpoint<?>[] breakpoints = breakpointManager.getAllBreakpoints();
for (XBreakpoint b: breakpoints) {
breakpointManager.removeBreakpoint(b);
}
}
public static void setBreakpointCondition(Project project, int line, final String condition) {
XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager();
for (XBreakpoint breakpoint : breakpointManager.getAllBreakpoints()) {
@@ -198,8 +198,10 @@ public class PsiDocumentNavigator extends DefaultNavigator {
final XmlTag context = (XmlTag)element;
final String namespaceUri = context.getNamespace();
if (!MyPsiUtil.isInDeclaredNamespace(context, namespaceUri, context.getNamespacePrefix())) {
LOG.info("getElementNamespaceUri: not returning implicit namespace uri: " + namespaceUri);
return "";
if (LOG.isDebugEnabled()) {
LOG.debug("getElementNamespaceUri: not returning implicit namespace uri: " + namespaceUri);
}
return "";
}
if (LOG.isDebugEnabled()) {
LOG.debug("enter: getElementNamespaceUri: " + namespaceUri);