Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2014-01-17 20:26:11 +01:00
68 changed files with 1037 additions and 416 deletions
@@ -21,7 +21,6 @@ import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.util.messages.MessageBus;
import org.jetbrains.annotations.NotNull;
@@ -34,8 +33,8 @@ import org.jetbrains.annotations.NotNull;
)}
)
public class RecentProjectsManager extends RecentProjectsManagerBase {
public RecentProjectsManager(final ProjectManager projectManager, final MessageBus messageBus) {
super(projectManager, messageBus);
public RecentProjectsManager(MessageBus messageBus) {
super(messageBus);
}
protected String getProjectPath(@NotNull Project project) {
@@ -35,6 +35,7 @@ import com.intellij.psi.util.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.NullableFunction;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.Stack;
import gnu.trove.THashSet;
@@ -84,6 +85,11 @@ public class ExpectedTypesProvider {
return createInfoImpl(type, kind, defaultType, tailType);
}
@NotNull
private static ExpectedTypeInfoImpl createInfoImpl(@NotNull PsiType type, PsiType defaultType) {
return createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, defaultType, TailType.NONE);
}
@NotNull
private static ExpectedTypeInfoImpl createInfoImpl(@NotNull PsiType type, @ExpectedTypeInfo.Type int kind, PsiType defaultType, @NotNull TailType tailType) {
return new ExpectedTypeInfoImpl(type, kind, defaultType, tailType, null, ExpectedTypeInfoImpl.NULL);
@@ -216,7 +222,7 @@ public class ExpectedTypesProvider {
private final boolean myUsedAfter;
private final ExpectedClassProvider myClassProvider;
private final boolean myVoidable;
private ExpectedTypeInfo[] myResult = ExpectedTypeInfo.EMPTY_ARRAY;
final List<ExpectedTypeInfo> myResult = ContainerUtil.newArrayList();
@NonNls private static final String LENGTH_SYNTHETIC_ARRAY_FIELD = "length";
private MyParentVisitor(PsiExpression expr,
@@ -233,7 +239,7 @@ public class ExpectedTypesProvider {
@NotNull
public ExpectedTypeInfo[] getResult() {
return myResult;
return myResult.toArray(new ExpectedTypeInfo[myResult.size()]);
}
@Override
@@ -241,7 +247,7 @@ public class ExpectedTypesProvider {
if (myExpr == method.getDefaultValue()) {
final PsiType type = method.getReturnType();
if (type != null) {
myResult = new ExpectedTypeInfo[]{createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, TailType.SEMICOLON)};
myResult.add(createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, TailType.SEMICOLON));
}
}
}
@@ -251,7 +257,7 @@ public class ExpectedTypesProvider {
if (myForCompletion) {
final MyParentVisitor visitor = new MyParentVisitor(expression, myForCompletion, myClassProvider, myVoidable, myUsedAfter);
expression.getParent().accept(visitor);
myResult = visitor.getResult();
myResult.addAll(visitor.myResult);
return;
}
@@ -259,15 +265,15 @@ public class ExpectedTypesProvider {
if (referenceName != null) {
final PsiElement parent = expression.getParent();
if (parent instanceof PsiMethodCallExpression) {
myResult = findClassesWithDeclaredMethod((PsiMethodCallExpression)parent, myForCompletion);
Collections.addAll(myResult, findClassesWithDeclaredMethod((PsiMethodCallExpression)parent, false));
}
else if (parent instanceof PsiReferenceExpression || parent instanceof PsiVariable ||
parent instanceof PsiExpression) {
if (LENGTH_SYNTHETIC_ARRAY_FIELD.equals(referenceName)) {
myResult = anyArrayType();
myResult.addAll(anyArrayType());
}
else {
myResult = findClassesWithDeclaredField(expression);
Collections.addAll(myResult, findClassesWithDeclaredField(expression));
}
}
}
@@ -276,7 +282,7 @@ public class ExpectedTypesProvider {
@Override
public void visitExpressionStatement(PsiExpressionStatement statement) {
if (myVoidable) {
myResult = new ExpectedTypeInfo[]{VOID_EXPECTED};
myResult.add(VOID_EXPECTED);
}
}
@@ -298,20 +304,17 @@ public class ExpectedTypesProvider {
type = ((PsiAnnotationMethod)parent).getReturnType();
}
if (type instanceof PsiArrayType) {
myResult = new ExpectedTypeInfo[]{createInfoImpl(((PsiArrayType)type).getComponentType(), ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, TailType.UNKNOWN)};
myResult.add(createInfoImpl(((PsiArrayType)type).getComponentType(), type));
}
}
@Override public void visitNameValuePair(@NotNull PsiNameValuePair pair) {
final PsiType type = getAnnotationMethodType(pair);
if (type == null) return;
final ExpectedTypeInfoImpl info = createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, TailType.UNKNOWN);
myResult.add(createInfoImpl(type, type));
if (type instanceof PsiArrayType) {
PsiType componentType = ((PsiArrayType)type).getComponentType();
myResult = new ExpectedTypeInfo[]{info, createInfoImpl(componentType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, componentType, TailType.UNKNOWN)};
}
else {
myResult = new ExpectedTypeInfo[] {info};
myResult.add(createInfoImpl(componentType, componentType));
}
}
@@ -374,39 +377,27 @@ public class ExpectedTypesProvider {
else {
expectedName = ExpectedTypeInfoImpl.NULL;
}
ExpectedTypeInfoImpl info = createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type,
tailTypeSemicolon ? TailType.SEMICOLON : TailType.NONE, null, expectedName);
myResult = new ExpectedTypeInfo[]{info};
}
else {
myResult = ExpectedTypeInfo.EMPTY_ARRAY;
myResult.add(createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type,
tailTypeSemicolon ? TailType.SEMICOLON : TailType.NONE, null, expectedName));
}
}
@Override public void visitIfStatement(PsiIfStatement statement) {
ExpectedTypeInfoImpl info = createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY,
PsiType.BOOLEAN, TailTypes.IF_RPARENTH);
myResult = new ExpectedTypeInfo[]{info};
myResult.add(createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY, PsiType.BOOLEAN, TailTypes.IF_RPARENTH));
}
@Override public void visitWhileStatement(PsiWhileStatement statement) {
ExpectedTypeInfoImpl info = createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY,
PsiType.BOOLEAN, TailTypes.WHILE_RPARENTH);
myResult = new ExpectedTypeInfo[]{info};
myResult.add(createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY, PsiType.BOOLEAN, TailTypes.WHILE_RPARENTH));
}
@Override public void visitDoWhileStatement(PsiDoWhileStatement statement) {
ExpectedTypeInfoImpl info = createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY,
PsiType.BOOLEAN, TailTypes.WHILE_RPARENTH);
myResult = new ExpectedTypeInfo[]{info};
myResult.add(createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY, PsiType.BOOLEAN, TailTypes.WHILE_RPARENTH));
}
@Override public void visitForStatement(@NotNull PsiForStatement statement) {
if (myExpr.equals(statement.getCondition())) {
ExpectedTypeInfoImpl info = createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY,
PsiType.BOOLEAN, TailType.SEMICOLON);
myResult = new ExpectedTypeInfo[]{info};
myResult.add(createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY, PsiType.BOOLEAN, TailType.SEMICOLON));
}
}
@@ -414,14 +405,10 @@ public class ExpectedTypesProvider {
public void visitAssertStatement(@NotNull PsiAssertStatement statement) {
if (statement.getAssertDescription() == myExpr) {
final PsiClassType stringType = PsiType.getJavaLangString(myExpr.getManager(), myExpr.getResolveScope());
ExpectedTypeInfoImpl info = createInfoImpl(stringType, ExpectedTypeInfo.TYPE_STRICTLY,
stringType, TailType.SEMICOLON);
myResult = new ExpectedTypeInfo[]{info};
myResult.add(createInfoImpl(stringType, ExpectedTypeInfo.TYPE_STRICTLY, stringType, TailType.SEMICOLON));
}
else {
ExpectedTypeInfoImpl info = createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY,
PsiType.BOOLEAN, TailType.SEMICOLON);
myResult = new ExpectedTypeInfo[]{info};
myResult.add(createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY, PsiType.BOOLEAN, TailType.SEMICOLON));
}
}
@@ -430,41 +417,30 @@ public class ExpectedTypesProvider {
PsiType type = statement.getIterationParameter().getType();
PsiType arrayType = type.createArrayType();
ExpectedTypeInfoImpl info1 = createInfoImpl(arrayType, ExpectedTypeInfo.TYPE_OR_SUBTYPE,
arrayType, TailType.NONE);
myResult.add(createInfoImpl(arrayType, arrayType));
PsiManager manager = statement.getManager();
PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
PsiClass iterableClass =
JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Iterable", statement.getResolveScope());
if (iterableClass == null || iterableClass.getTypeParameters().length != 1) {
myResult = new ExpectedTypeInfo[]{info1};
}
else {
if (iterableClass != null && iterableClass.getTypeParameters().length == 1) {
Map<PsiTypeParameter, PsiType> map = new HashMap<PsiTypeParameter, PsiType>();
map.put(iterableClass.getTypeParameters()[0], PsiWildcardType.createExtends(manager, type));
PsiSubstitutor substitutor = factory.createSubstitutor(map);
PsiType iterableType = factory.createType(iterableClass, substitutor);
ExpectedTypeInfoImpl info2 = createInfoImpl(iterableType, ExpectedTypeInfo.TYPE_OR_SUBTYPE,
iterableType, TailType.NONE);
myResult = new ExpectedTypeInfo[]{info1, info2};
PsiType iterableType = factory.createType(iterableClass, factory.createSubstitutor(map));
myResult.add(createInfoImpl(iterableType, iterableType));
}
}
}
@Override public void visitSwitchStatement(@NotNull PsiSwitchStatement statement) {
ExpectedTypeInfoImpl info = createInfoImpl(PsiType.LONG, ExpectedTypeInfo.TYPE_OR_SUBTYPE, PsiType.INT,
TailType.NONE);
myResult.add(createInfoImpl(PsiType.LONG, PsiType.INT));
if (!PsiUtil.isLanguageLevel5OrHigher(statement)) {
myResult = new ExpectedTypeInfo[]{info};
return;
}
PsiManager manager = statement.getManager();
PsiClassType enumType = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName("java.lang.Enum", statement.getResolveScope());
ExpectedTypeInfoImpl enumInfo = createInfoImpl(enumType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, enumType, TailType.NONE);
myResult = new ExpectedTypeInfo[] {info, enumInfo};
myResult.add(createInfoImpl(enumType, enumType));
}
@Override
@@ -475,7 +451,7 @@ public class ExpectedTypesProvider {
if (expression != null) {
final PsiType type = expression.getType();
if (type != null) {
myResult = new ExpectedTypeInfo[]{createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, TailType.CASE_COLON)};
myResult.add(createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, TailType.CASE_COLON));
}
}
}
@@ -484,14 +460,13 @@ public class ExpectedTypesProvider {
@Override public void visitSynchronizedStatement(@NotNull PsiSynchronizedStatement statement) {
PsiElementFactory factory = JavaPsiFacade.getInstance(statement.getProject()).getElementFactory();
PsiType objectType = factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, myExpr.getResolveScope());
myResult = new ExpectedTypeInfo[]{createInfoImpl(objectType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, objectType, TailType.NONE)};
myResult.add(createInfoImpl(objectType, objectType));
}
@Override public void visitVariable(@NotNull PsiVariable variable) {
PsiType type = variable.getType();
ExpectedTypeInfoImpl info = createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type,
variable instanceof PsiResourceVariable ? TailType.NONE : TailType.SEMICOLON, null, getPropertyName(variable));
myResult = new ExpectedTypeInfo[]{info};
myResult.add(createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type,
variable instanceof PsiResourceVariable ? TailType.NONE : TailType.SEMICOLON, null, getPropertyName(variable)));
}
@Override public void visitAssignmentExpression(@NotNull PsiAssignmentExpression assignment) {
@@ -507,11 +482,7 @@ public class ExpectedTypesProvider {
expectedName = getPropertyName((PsiVariable)refElement);
}
}
ExpectedTypeInfoImpl info = createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, tailType, null, expectedName);
myResult = new ExpectedTypeInfo[]{info};
}
else {
myResult = ExpectedTypeInfo.EMPTY_ARRAY;
myResult.add(createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, tailType, null, expectedName));
}
}
else {
@@ -534,12 +505,9 @@ public class ExpectedTypesProvider {
final int kind = assignment.getOperationTokenType() != JavaTokenType.EQ
? ExpectedTypeInfo.TYPE_STRICTLY
: ExpectedTypeInfo.TYPE_OR_SUPERTYPE;
ExpectedTypeInfoImpl info = createInfoImpl(type, kind, type, TailType.NONE);
myResult = new ExpectedTypeInfo[]{info};
return;
myResult.add(createInfoImpl(type, kind, type, TailType.NONE));
}
}
myResult = ExpectedTypeInfo.EMPTY_ARRAY;
}
}
@@ -562,7 +530,7 @@ public class ExpectedTypesProvider {
if (list.getParent() instanceof PsiMethodCallExpression) {
PsiMethodCallExpression methodCall = (PsiMethodCallExpression)list.getParent();
CandidateInfo[] candidates = helper.getReferencedMethodCandidates(methodCall, false);
myResult = getExpectedArgumentTypesForMethodCall(candidates, list, myExpr, myForCompletion);
Collections.addAll(myResult, getExpectedArgumentTypesForMethodCall(candidates, list, myExpr, myForCompletion));
}
else if (list.getParent() instanceof PsiEnumConstant) {
getExpectedArgumentsTypesForEnumConstant((PsiEnumConstant)list.getParent(), list);
@@ -615,7 +583,7 @@ public class ExpectedTypesProvider {
array.add(new MethodCandidateInfo(constructor, substitutor, false, false, argumentList, null, argumentList.getExpressionTypes(), null));
}
CandidateInfo[] candidates = array.toArray(new CandidateInfo[array.size()]);
myResult = getExpectedArgumentTypesForMethodCall(candidates, argumentList, myExpr, myForCompletion);
Collections.addAll(myResult, getExpectedArgumentTypesForMethodCall(candidates, argumentList, myExpr, myForCompletion));
}
@Override
@@ -628,18 +596,19 @@ public class ExpectedTypesProvider {
final MyParentVisitor visitor = new MyParentVisitor(expr, myForCompletion, myClassProvider, myVoidable, myUsedAfter);
myExpr = (PsiExpression)myExpr.getParent();
expr.getParent().accept(visitor);
myResult = visitor.getResult();
myResult.addAll(visitor.myResult);
if (!(expr.getParent() instanceof PsiExpressionList)) {
for (int i = 0; i < myResult.length; i++) {
final ExpectedTypeInfo info = myResult[i];
myResult[i] = createInfoImpl(info.getType(), info.getKind(), info.getDefaultType(), TailType.NONE, info.getCalledMethod(),
new NullableComputable<String>() {
@Nullable
@Override
public String compute() {
return ((ExpectedTypeInfoImpl)info).getExpectedName();
for (int i = 0; i < myResult.size(); i++) {
final ExpectedTypeInfo info = myResult.get(i);
myResult.set(i, createInfoImpl(info.getType(), info.getKind(), info.getDefaultType(), TailType.NONE, info.getCalledMethod(),
new NullableComputable<String>() {
@Nullable
@Override
public String compute() {
return ((ExpectedTypeInfoImpl)info).getExpectedName();
}
}
});
));
}
}
return;
@@ -655,53 +624,39 @@ public class ExpectedTypesProvider {
i == JavaTokenType.GT ||
i == JavaTokenType.LE ||
i == JavaTokenType.GE) {
if (anotherType == null) {
myResult = ExpectedTypeInfo.EMPTY_ARRAY;
}
else {
ExpectedTypeInfoImpl info = createInfoImpl(PsiType.DOUBLE, ExpectedTypeInfo.TYPE_OR_SUBTYPE,
anotherType, TailType.NONE);
myResult = new ExpectedTypeInfo[]{info};
if (anotherType != null) {
myResult.add(createInfoImpl(PsiType.DOUBLE, anotherType));
}
}
else if (i == JavaTokenType.PLUS) {
if (anotherType == null || anotherType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
myResult = ExpectedTypeInfo.EMPTY_ARRAY;
myResult.add(createInfoImpl(PsiType.getJavaLangObject(expr.getManager(), expr.getResolveScope()), anotherType));
}
else if (PsiType.DOUBLE.isAssignableFrom(anotherType)) {
myResult = new ExpectedTypeInfo[]{createInfoImpl(PsiType.DOUBLE, ExpectedTypeInfo.TYPE_OR_SUBTYPE, anotherType, TailType.NONE)};
myResult.add(createInfoImpl(PsiType.DOUBLE, anotherType));
}
}
else if (i == JavaTokenType.EQEQ || i == JavaTokenType.NE) {
ExpectedTypeInfo info = getEqualsType(anotherExpr);
myResult = info == null ? ExpectedTypeInfo.EMPTY_ARRAY : new ExpectedTypeInfo[]{info};
ContainerUtil.addIfNotNull(myResult, getEqualsType(anotherExpr));
}
else if (i == JavaTokenType.LTLT || i == JavaTokenType.GTGT || i == JavaTokenType.GTGTGT) {
if (anotherType == null) {
myResult = ExpectedTypeInfo.EMPTY_ARRAY;
}
else {
myResult = new ExpectedTypeInfo[]{createInfoImpl(PsiType.LONG, ExpectedTypeInfo.TYPE_BETWEEN, PsiType.SHORT, TailType.NONE)};
if (anotherType != null) {
myResult.add(createInfoImpl(PsiType.LONG, ExpectedTypeInfo.TYPE_BETWEEN, PsiType.SHORT, TailType.NONE));
}
}
else if (i == JavaTokenType.OROR || i == JavaTokenType.ANDAND) {
ExpectedTypeInfoImpl info = createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY,
PsiType.BOOLEAN, TailType.NONE);
myResult = new ExpectedTypeInfo[]{info};
myResult.add(createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY, PsiType.BOOLEAN, TailType.NONE));
}
else if (i == JavaTokenType.OR || i == JavaTokenType.XOR || i == JavaTokenType.AND) {
if (anotherType == null) {
myResult = ExpectedTypeInfo.EMPTY_ARRAY;
}
else {
if (anotherType != null) {
ExpectedTypeInfoImpl info;
if (PsiType.BOOLEAN.equals(anotherType)) {
info = createInfoImpl(anotherType, ExpectedTypeInfo.TYPE_STRICTLY, anotherType, TailType.NONE);
}
else {
info = createInfoImpl(PsiType.LONG, ExpectedTypeInfo.TYPE_OR_SUBTYPE, anotherType, TailType.NONE);
info = createInfoImpl(PsiType.LONG, anotherType);
}
myResult = new ExpectedTypeInfo[]{info};
myResult.add(info);
}
}
}
@@ -760,17 +715,13 @@ public class ExpectedTypesProvider {
info = createInfoImpl(PsiType.LONG, ExpectedTypeInfo.TYPE_OR_SUBTYPE, PsiType.INT, tailType);
}
}
myResult = new ExpectedTypeInfo[]{info};
myResult.add(info);
}
else if (i == JavaTokenType.PLUS || i == JavaTokenType.MINUS) {
ExpectedTypeInfoImpl info = createInfoImpl(PsiType.DOUBLE, ExpectedTypeInfo.TYPE_OR_SUBTYPE,
PsiType.INT, tailType);
myResult = new ExpectedTypeInfo[]{info};
myResult.add(createInfoImpl(PsiType.DOUBLE, ExpectedTypeInfo.TYPE_OR_SUBTYPE, PsiType.INT, tailType));
}
else if (i == JavaTokenType.EXCL) {
ExpectedTypeInfoImpl info = createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY,
PsiType.BOOLEAN, tailType);
myResult = new ExpectedTypeInfo[]{info};
myResult.add(createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY, PsiType.BOOLEAN, tailType));
}
}
@@ -787,10 +738,10 @@ public class ExpectedTypesProvider {
info = createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUPERTYPE, PsiType.INT, TailType.NONE);
}
else {
info = createInfoImpl(PsiType.LONG, ExpectedTypeInfo.TYPE_OR_SUBTYPE, PsiType.INT, TailType.NONE);
info = createInfoImpl(PsiType.LONG, PsiType.INT);
}
}
myResult = new ExpectedTypeInfo[]{info};
myResult.add(info);
}
@Override
@@ -812,9 +763,7 @@ public class ExpectedTypesProvider {
if (arrayType instanceof PsiArrayType) {
PsiType componentType = ((PsiArrayType)arrayType).getComponentType();
ExpectedTypeInfoImpl info = createInfoImpl(componentType, ExpectedTypeInfo.TYPE_OR_SUBTYPE,
componentType, TailType.NONE);
myResult = new ExpectedTypeInfo[]{info};
myResult.add(createInfoImpl(componentType, componentType));
}
}
@@ -822,9 +771,7 @@ public class ExpectedTypesProvider {
PsiExpression[] arrayDimensions = expression.getArrayDimensions();
for (PsiExpression dimension : arrayDimensions) {
if (myExpr.equals(dimension)) {
ExpectedTypeInfoImpl info = createInfoImpl(PsiType.INT, ExpectedTypeInfo.TYPE_OR_SUBTYPE,
PsiType.INT, TailType.NONE);
myResult = new ExpectedTypeInfo[]{info};
myResult.add(createInfoImpl(PsiType.INT, PsiType.INT));
return;
}
}
@@ -832,9 +779,7 @@ public class ExpectedTypesProvider {
@Override public void visitArrayAccessExpression(@NotNull PsiArrayAccessExpression expr) {
if (myExpr.equals(expr.getIndexExpression())) {
ExpectedTypeInfoImpl info = createInfoImpl(PsiType.INT, ExpectedTypeInfo.TYPE_OR_SUBTYPE, PsiType.INT, TailType.NONE)
; //todo: special tail type
myResult = new ExpectedTypeInfo[]{info};
myResult.add(createInfoImpl(PsiType.INT, PsiType.INT));
}
else if (myExpr.equals(expr.getArrayExpression())) {
if (myForCompletion) {
@@ -849,14 +794,13 @@ public class ExpectedTypesProvider {
parent.accept(visitor);
ExpectedTypeInfo[] componentTypeInfo = visitor.getResult();
if (componentTypeInfo.length == 0) {
myResult = anyArrayType();
myResult.addAll(anyArrayType());
}
else {
myResult = new ExpectedTypeInfoImpl[componentTypeInfo.length];
for (int i = 0; i < componentTypeInfo.length; i++) {
ExpectedTypeInfo compInfo = componentTypeInfo[i];
PsiType expectedArrayType = compInfo.getType().createArrayType();
myResult[i] = createInfoImpl(expectedArrayType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, expectedArrayType, TailType.NONE);
myResult.add(createInfoImpl(expectedArrayType, expectedArrayType));
}
}
}
@@ -870,9 +814,7 @@ public class ExpectedTypesProvider {
return;
}
ExpectedTypeInfo info = createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY,
PsiType.BOOLEAN, TailType.NONE);
myResult = new ExpectedTypeInfo[]{info};
myResult.add(createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY, PsiType.BOOLEAN, TailType.NONE));
}
else if (myExpr.equals(expr.getThenExpression())) {
ExpectedTypeInfo[] types = getExpectedTypes(expr, myForCompletion);
@@ -887,13 +829,13 @@ public class ExpectedTypesProvider {
}
});
}
myResult = types;
Collections.addAll(myResult, types);
}
else {
if (!myExpr.equals(expr.getElseExpression())) {
LOG.error(Arrays.asList(expr.getChildren()) + "; " + myExpr);
}
myResult = getExpectedTypes(expr, myForCompletion);
Collections.addAll(myResult, getExpectedTypes(expr, myForCompletion));
}
}
@@ -912,18 +854,16 @@ public class ExpectedTypesProvider {
throwsTypes = new PsiClassType[]{exceptionType};
}
ExpectedTypeInfo[] infos = new ExpectedTypeInfo[throwsTypes.length];
for (int i = 0; i < infos.length; i++) {
infos[i] = createInfoImpl(
for (int i = 0; i < throwsTypes.length; i++) {
myResult.add(createInfoImpl(
myExpr instanceof PsiTypeCastExpression && myForCompletion ?
throwsTypes[i] :
throwableType,
ExpectedTypeInfo.TYPE_OR_SUBTYPE,
throwsTypes[i],
TailType.SEMICOLON
);
));
}
myResult = infos;
}
}
@@ -931,7 +871,7 @@ public class ExpectedTypesProvider {
if (codeFragment instanceof PsiExpressionCodeFragment) {
final PsiType type = ((PsiExpressionCodeFragment)codeFragment).getExpectedType();
if (type != null) {
myResult = new ExpectedTypeInfo[] {createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, TailType.NONE)};
myResult.add(createInfoImpl(type, type));
}
}
}
@@ -1225,16 +1165,13 @@ public class ExpectedTypesProvider {
}
@NotNull
private ExpectedTypeInfo[] anyArrayType() {
private List<ExpectedTypeInfo> anyArrayType() {
PsiType objType = PsiType.getJavaLangObject(myExpr.getManager(), myExpr.getResolveScope()).createArrayType();
ExpectedTypeInfo info = createInfoImpl(objType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, objType,
TailType.NONE);
ExpectedTypeInfo info1 = createInfoImpl(PsiType.DOUBLE.createArrayType(), ExpectedTypeInfo.TYPE_OR_SUBTYPE,
PsiType.INT.createArrayType(), TailType.NONE);
ExpectedTypeInfo info = createInfoImpl(objType, objType);
ExpectedTypeInfo info1 = createInfoImpl(PsiType.DOUBLE.createArrayType(), PsiType.INT.createArrayType());
PsiType booleanType = PsiType.BOOLEAN.createArrayType();
ExpectedTypeInfo info2 = createInfoImpl(booleanType, ExpectedTypeInfo.TYPE_STRICTLY, booleanType,
TailType.NONE);
return new ExpectedTypeInfo[]{info, info1, info2};
ExpectedTypeInfo info2 = createInfoImpl(booleanType, ExpectedTypeInfo.TYPE_STRICTLY, booleanType, TailType.NONE);
return Arrays.asList(info, info1, info2);
}
@NotNull
@@ -75,6 +75,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
fixers.add(new ParenthesizedFixer());
fixers.add(new SemicolonFixer());
fixers.add(new MissingArrayInitializerBraceFixer());
fixers.add(new MissingArrayConstructorBracketFixer());
fixers.add(new EnumFieldFixer());
//ourFixers.add(new CompletionFixer());
ourFixers = fixers.toArray(new Fixer[fixers.size()]);
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.editorActions.smartEnter;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNewExpression;
import com.intellij.util.IncorrectOperationException;
public class MissingArrayConstructorBracketFixer implements Fixer {
@Override
public void apply(Editor editor, JavaSmartEnterProcessor processor, PsiElement psiElement) throws IncorrectOperationException {
if (!(psiElement instanceof PsiNewExpression)) return;
PsiNewExpression expr = (PsiNewExpression)psiElement;
int count = 0;
for (PsiElement element : expr.getChildren()) {
if (element.getNode().getElementType() == JavaTokenType.LBRACKET) {
count++;
} else if (element.getNode().getElementType() == JavaTokenType.RBRACKET) {
count--;
}
}
if (count > 0) {
editor.getDocument().insertString(psiElement.getTextRange().getEndOffset(), "]");
}
}
}
@@ -15,18 +15,22 @@
*/
package com.intellij.unscramble;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.icons.AllIcons;
import com.intellij.ide.DataManager;
import com.intellij.notification.NotificationGroup;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
@@ -34,6 +38,7 @@ import com.intellij.util.PlatformIcons;
import com.intellij.util.ui.UIUtil;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
@@ -58,14 +63,16 @@ public class ThreadDumpPanel extends JPanel {
private static final Icon EDT_BUSY_ICON_DAEMON = new LayeredIcon(EdtBusy, Daemon_sign);
private static final Icon IO_ICON_DAEMON = new LayeredIcon(IO, Daemon_sign);
private final JBList myThreadList;
private final List<ThreadState> myThreadDump;
public ThreadDumpPanel(Project project, final ConsoleView consoleView, final DefaultActionGroup toolbarActions, final List<ThreadState> threadDump) {
public ThreadDumpPanel(final Project project, final ConsoleView consoleView, final DefaultActionGroup toolbarActions, final List<ThreadState> threadDump) {
super(new BorderLayout());
myThreadDump = threadDump;
final ThreadState[] data = threadDump.toArray(new ThreadState[threadDump.size()]);
DefaultListModel model = new DefaultListModel();
for (ThreadState threadState : data) {
model.addElement(threadState);
}
final DefaultListModel model = new DefaultListModel();
final SearchTextField filterField = new SearchTextField();
myThreadList = new JBList(model);
myThreadList.setCellRenderer(new ThreadListCellRenderer());
myThreadList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
@@ -82,18 +89,78 @@ public class ThreadDumpPanel extends JPanel {
myThreadList.repaint();
}
});
DocumentAdapter filterListener = new DocumentAdapter() {
@Override
protected void textChanged(DocumentEvent e) {
String text = filterField.getText();
model.clear();
for (ThreadState state : data) {
if (StringUtil.containsIgnoreCase(state.getStackTrace(), text) || StringUtil.containsIgnoreCase(state.getName(), text)) {
//noinspection unchecked
model.addElement(state);
}
}
if (!model.isEmpty()) {
myThreadList.setSelectedIndex(0);
}
myThreadList.revalidate();
myThreadList.repaint();
}
};
filterField.addDocumentListener(filterListener);
filterListener.changedUpdate(null);
toolbarActions.add(new CopyToClipboardAction(threadDump, project));
toolbarActions.add(new SortThreadsAction());
//toolbarActions.add(new ShowRecentlyChanged());
add(ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarActions, false).getComponent(), BorderLayout.WEST);
JPanel filterPanel = new JPanel(new BorderLayout());
filterPanel.add(new JLabel("Filter:"), BorderLayout.WEST);
filterPanel.add(filterField);
JPanel leftPanel = new JPanel(new BorderLayout());
leftPanel.add(filterPanel, BorderLayout.NORTH);
leftPanel.add(ScrollPaneFactory.createScrollPane(myThreadList, SideBorder.LEFT | SideBorder.RIGHT), BorderLayout.CENTER);
final Splitter splitter = new Splitter(false, 0.3f);
splitter.setFirstComponent(ScrollPaneFactory.createScrollPane(myThreadList, SideBorder.LEFT | SideBorder.RIGHT));
splitter.setFirstComponent(leftPanel);
splitter.setSecondComponent(consoleView.getComponent());
add(splitter, BorderLayout.CENTER);
new ListSpeedSearch(myThreadList).setComparator(new SpeedSearchComparator(false, true));
final Editor editor = CommonDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext(consoleView.getPreferredFocusableComponent()));
assert editor != null;
editor.getDocument().addDocumentListener(new com.intellij.openapi.editor.event.DocumentAdapter() {
@Override
public void documentChanged(com.intellij.openapi.editor.event.DocumentEvent e) {
String filter = filterField.getText();
if (StringUtil.isNotEmpty(filter)) {
highlightOccurrences(filter, project, editor);
}
}
});
}
private static void highlightOccurrences(String filter, Project project, Editor editor) {
final HighlightManager highlightManager = HighlightManager.getInstance(project);
EditorColorsManager colorManager = EditorColorsManager.getInstance();
final TextAttributes attributes = colorManager.getGlobalScheme().getAttributes(EditorColors.TEXT_SEARCH_RESULT_ATTRIBUTES);
String documentText = editor.getDocument().getText();
int i = -1;
while (true) {
int nextOccurrence = StringUtil.indexOfIgnoreCase(documentText, filter, i + 1);
if (nextOccurrence < 0) {
break;
}
i = nextOccurrence;
highlightManager.addOccurrenceHighlight(editor, i, i + filter.length(), attributes,
HighlightManager.HIDE_BY_TEXT_CHANGE, null, null);
}
}
private static Icon getThreadStateIcon(final ThreadState threadState) {
@@ -119,7 +186,7 @@ public class ThreadDumpPanel extends JPanel {
return daemon ? RUNNING_ICON_DAEMON : Running;
}
private static enum StateCode {RUN, RUN_IO, RUN_SOCKET, PAUSED, LOCKED, EDT, IDLE}
private enum StateCode {RUN, RUN_IO, RUN_SOCKET, PAUSED, LOCKED, EDT, IDLE}
private static StateCode getThreadStateCode(final ThreadState state) {
if (state.isSleeping()) return StateCode.PAUSED;
if (state.isWaiting()) return StateCode.LOCKED;
@@ -23,7 +23,7 @@ import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizableStringList;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiModifierListOwner;
import com.intellij.psi.*;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -126,11 +126,38 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
}
public boolean isNullable(PsiModifierListOwner owner, boolean checkBases) {
return AnnotationUtil.isAnnotated(owner, getNullables(), checkBases, false);
if (AnnotationUtil.isAnnotated(owner, getNullables(), checkBases, false)) {
return true;
}
return owner instanceof PsiParameter && isContainerAnnotated(owner, "javax.annotation.ParametersAreNullableByDefault");
}
public boolean isNotNull(PsiModifierListOwner owner, boolean checkBases) {
return AnnotationUtil.isAnnotated(owner, getNotNulls(), checkBases, false);
if (AnnotationUtil.isAnnotated(owner, getNotNulls(), checkBases, false)) {
return true;
}
return owner instanceof PsiParameter && isContainerAnnotated(owner, "javax.annotation.ParametersAreNonnullByDefault");
}
private static boolean isContainerAnnotated(PsiModifierListOwner owner, String annotationFQN) {
PsiElement element = owner.getParent();
while (element != null) {
if (element instanceof PsiModifierListOwner &&
AnnotationUtil.isAnnotated((PsiModifierListOwner)element, annotationFQN, false, false)) {
return true;
}
if (element instanceof PsiClassOwner) {
String packageName = ((PsiClassOwner)element).getPackageName();
PsiPackage psiPackage = JavaPsiFacade.getInstance(element.getProject()).findPackage(packageName);
return psiPackage != null && AnnotationUtil.isAnnotated(psiPackage, annotationFQN, false, false);
}
element = element.getContext();
}
return false;
}
public List<String> getNullables() {
@@ -0,0 +1,5 @@
public class Foo {
public void fails() {
boolean[] a = new boolean[f(<caret>
}
}
@@ -0,0 +1,5 @@
public class Foo {
public void fails() {
boolean[] a = new boolean[f()];<caret>
}
}
@@ -0,0 +1,8 @@
public class Test {
{
int abcdef = 2;
System.out.println("" + abcdef<caret>);
}
}
@@ -0,0 +1,8 @@
public class Test {
{
int abcdef = 2;
System.out.println("" + abc<caret>);
}
}
@@ -0,0 +1,6 @@
class Foo {
{
System.out.println("" + <caret>);
}
}
@@ -0,0 +1,25 @@
import foo.*;
class Some {
void foo() {
NotNullClass.foo(<warning descr="Passing 'null' argument to parameter annotated as @NotNull">null</warning>);
NotNullClass.foo("a");
NullableClass.foo(null);
NullableClass.foo("a");
AnotherPackageNotNull.foo(<warning descr="Passing 'null' argument to parameter annotated as @NotNull">null</warning>);
AnotherPackageNotNull.foo("a");
}
}
@javax.annotation.ParametersAreNonnullByDefault
class NotNullClass {
static void foo(String s) {}
}
@javax.annotation.ParametersAreNullableByDefault
class NullableClass {
static void foo(String s) {}
}
@@ -258,6 +258,8 @@ public class CompleteStatementTest extends EditorActionTestCase {
public void testGenericMethodBody() throws Exception { doTest(); }
public void testArrayInitializerRBracket() throws Exception { doTest(); }
private void doTestBracesNextLineStyle() throws Exception {
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
settings.BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE;
@@ -321,6 +321,10 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase {
checkPreferredItems 0, 'type', 'Object.class'
}
public void testPreferStringsInStringConcatenation() {
checkPreferredItems 0, 'toString'
}
@Override
protected String getBasePath() {
return JavaTestUtil.getRelativeJavaTestDataPath() + BASE_PATH;
@@ -1020,6 +1020,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
public void testArrayInitializerBeforeVarargs() throws Throwable { doTest(); }
public void testDuplicateMembersFromSuperClass() throws Throwable { doTest(); }
public void testInnerAfterNew() throws Throwable { doTest(); }
public void testEverythingInStringConcatenation() throws Throwable { doTest(); }
public void testMemberImportStatically() {
configureByTestName();
@@ -303,6 +303,16 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
public void testNotEqualsTypo() { doTest(); }
public void testAndEquals() { doTest(); }
public void testParametersAreNonnullByDefault() {
myFixture.addClass("package javax.annotation; public @interface ParametersAreNonnullByDefault {}");
myFixture.addClass("package javax.annotation; public @interface ParametersAreNullableByDefault {}");
myFixture.addClass("package foo; public class AnotherPackageNotNull { public static void foo(String s) {}}");
myFixture.addFileToProject("foo/package-info.java", "@javax.annotation.ParametersAreNonnullByDefault package foo;");
doTest();
}
public void _testNullCheckBeforeInstanceof() { doTest(); } // http://youtrack.jetbrains.com/issue/IDEA-113220
}
@@ -33,6 +33,10 @@ public abstract class StubProcessingHelperBase {
}
public <Psi extends PsiElement> boolean processStubsInFile(final Project project, final VirtualFile file, StubIdList value, final Processor<? super Psi> processor) {
return processStubsInFile(project, file, value, processor, false);
}
public <Psi extends PsiElement> boolean processStubsInFile(final Project project, final VirtualFile file, StubIdList value, final Processor<? super Psi> processor, final boolean skipOnErrors) {
StubTree stubTree = null;
PsiFile _psifile = PsiManager.getInstance(project).findFile(file);
@@ -66,7 +70,15 @@ public abstract class StubProcessingHelperBase {
stubTree = (StubTree)objectStubTree;
final List<StubElement<?>> plained = stubTree.getPlainList();
for (int i = 0, size = value.size(); i < size; i++) {
final StubElement<?> stub = plained.get(value.get(i));
final int stubTreeIndex = value.get(i);
if (stubTreeIndex >= plained.size()) {
if (!skipOnErrors)
onInternalError(file);
break;
}
final StubElement<?> stub = plained.get(stubTreeIndex);
PsiUtilCore.ensureValid(psiFile);
final ASTNode tree = psiFile.findTreeForStub(stubTree, stub);
@@ -76,7 +88,7 @@ public abstract class StubProcessingHelperBase {
PsiUtilCore.ensureValid(psi);
if (!processor.process(psi)) return false;
}
else {
else if (!skipOnErrors) {
String persistedStubTree = ((PsiFileStubImpl)stubTree.getRoot()).printTree();
String stubTreeJustBuilt =
@@ -103,11 +115,13 @@ public abstract class StubProcessingHelperBase {
for (int i = 0, size = value.size(); i < size; i++) {
final int stubTreeIndex = value.get(i);
if (stubTreeIndex >= plained.size()) {
final VirtualFile virtualFile = psiFile.getVirtualFile();
StubTree stubTreeFromIndex = (StubTree)StubTreeLoader.getInstance().readFromVFile(project, file);
LOG.error(stubTreeAndIndexDoNotMatch(stubTree, psiFile, plained, virtualFile, stubTreeFromIndex));
if (!skipOnErrors) {
final VirtualFile virtualFile = psiFile.getVirtualFile();
StubTree stubTreeFromIndex = (StubTree)StubTreeLoader.getInstance().readFromVFile(project, file);
LOG.error(stubTreeAndIndexDoNotMatch(stubTree, psiFile, plained, virtualFile, stubTreeFromIndex));
onInternalError(file);
onInternalError(file);
}
break;
}
@@ -120,7 +120,8 @@ public class CodeCompletionHandlerBase {
CompletionAssertions.checkEditorValid(editor);
if (editor.isViewer() || editor.getDocument().getOffsetGuard(editor.getCaretModel().getOffset()) != null) {
int offset = editor.getCaretModel().getOffset();
if (editor.isViewer() || editor.getDocument().getRangeGuard(offset, offset) != null) {
editor.getDocument().fireReadOnlyModificationAttempt();
CodeInsightUtilBase.showReadOnlyViewWarning(editor);
return;
@@ -55,7 +55,8 @@ public class HippieWordCompletionHandler implements CodeInsightActionHandler {
public void invoke(@NotNull Project project, @NotNull final Editor editor, @NotNull PsiFile file) {
if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;
if (editor.isViewer() || editor.getDocument().getOffsetGuard(editor.getCaretModel().getOffset()) != null) {
int offset = editor.getCaretModel().getOffset();
if (editor.isViewer() || editor.getDocument().getRangeGuard(offset, offset) != null) {
editor.getDocument().fireReadOnlyModificationAttempt();
CodeInsightUtilBase.showReadOnlyViewWarning(editor);
return;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,12 +17,15 @@
package com.intellij.execution.ui.layout.actions;
import com.intellij.execution.ui.layout.CellTransform;
import com.intellij.icons.AllIcons;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.ui.content.Content;
import javax.swing.*;
public class RestoreViewAction extends AnAction {
private final Content myContent;
@@ -38,7 +41,8 @@ public class RestoreViewAction extends AnAction {
Presentation p = e.getPresentation();
p.setText(ActionsBundle.message("action.Runner.RestoreView.text", myContent.getDisplayName()));
p.setDescription(ActionsBundle.message("action.Runner.RestoreView.description"));
p.setIcon(myContent.getIcon());
Icon icon = myContent.getIcon();
p.setIcon(icon == null ? AllIcons.Debugger.RestoreLayout : icon);
}
@Override
@@ -20,7 +20,6 @@ import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.platform.ModuleAttachProcessor;
import com.intellij.util.messages.MessageBus;
import org.jetbrains.annotations.NotNull;
@@ -37,8 +36,8 @@ import org.jetbrains.annotations.NotNull;
)}
)
public class RecentDirectoryProjectsManagerEx extends RecentDirectoryProjectsManager {
public RecentDirectoryProjectsManagerEx(ProjectManager projectManager, MessageBus messageBus) {
super(projectManager, messageBus);
public RecentDirectoryProjectsManagerEx(MessageBus messageBus) {
super(messageBus);
}
@NotNull
@@ -161,6 +161,11 @@ public class ModuleAttachProcessor extends ProjectAttachProcessor {
if (!canAttachToProject()) {
return null;
}
return findModuleInBaseDir(project);
}
@Nullable
public static Module findModuleInBaseDir(Project project) {
for (Module module : ModuleManager.getInstance(project).getModules()) {
final VirtualFile[] roots = ModuleRootManager.getInstance(module).getContentRoots();
for (VirtualFile root : roots) {
@@ -33,6 +33,7 @@ import com.intellij.openapi.ui.InputValidator;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Ref;
import com.intellij.platform.ModuleAttachProcessor;
import com.intellij.projectImport.ProjectAttachProcessor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.refactoring.RefactoringBundle;
@@ -101,7 +102,7 @@ public class RenameProjectHandler implements RenameHandler, TitledHandler {
@Override
public boolean canClose(final String inputString) {
if (!inputString.equals(myProject.getName()) && (myModule == null || myModule == ModuleAttachProcessor.getPrimaryModule(myProject))) {
if (shouldRenameProject(inputString)) {
myProject.setProjectName(inputString);
myProject.save();
}
@@ -132,5 +133,21 @@ public class RenameProjectHandler implements RenameHandler, TitledHandler {
}
return true;
}
private boolean shouldRenameProject(String inputString) {
if (inputString.equals(myProject.getName())) {
return false;
}
if (myModule == null) {
return true;
}
if (ProjectAttachProcessor.canAttachToProject()) {
return myModule == ModuleAttachProcessor.getPrimaryModule(myProject);
}
return myModule == ModuleAttachProcessor.findModuleInBaseDir(myProject);
}
}
}
@@ -54,7 +54,7 @@ import java.awt.datatransfer.Transferable;
* @author yole
*/
public class AnalyzeStacktraceUtil {
public static ExtensionPointName<Filter> EP_NAME = ExtensionPointName.create("com.intellij.analyzeStacktraceFilter");
public static final ExtensionPointName<Filter> EP_NAME = ExtensionPointName.create("com.intellij.analyzeStacktraceFilter");
private AnalyzeStacktraceUtil() {
}
@@ -20,7 +20,6 @@ import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
@@ -42,8 +41,8 @@ import org.jetbrains.annotations.Nullable;
)}
)
public class RecentDirectoryProjectsManager extends RecentProjectsManagerBase {
public RecentDirectoryProjectsManager(ProjectManager projectManager, MessageBus messageBus) {
super(projectManager, messageBus);
public RecentDirectoryProjectsManager(MessageBus messageBus) {
super(messageBus);
}
@Nullable
@@ -21,9 +21,11 @@ import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.Separator;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ProjectManagerAdapter;
import com.intellij.openapi.project.ProjectManagerListener;
import com.intellij.openapi.project.impl.ProjectImpl;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Ref;
@@ -33,6 +35,7 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.impl.SystemDock;
import com.intellij.openapi.wm.impl.welcomeScreen.WelcomeFrame;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBus;
import org.jetbrains.annotations.NotNull;
@@ -44,16 +47,35 @@ import java.util.*;
/**
* @author yole
*/
public abstract class RecentProjectsManagerBase implements PersistentStateComponent<RecentProjectsManagerBase.State> {
public abstract class RecentProjectsManagerBase implements ProjectManagerListener, PersistentStateComponent<RecentProjectsManagerBase.State> {
public static RecentProjectsManagerBase getInstance() {
return ApplicationManager.getApplication().getComponent(RecentProjectsManagerBase.class);
return ServiceManager.getService(RecentProjectsManagerBase.class);
}
public static class State {
public List<String> recentPaths = new ArrayList<String>();
public List<String> openPaths = new ArrayList<String>();
public Map<String, String> names = new HashMap<String, String>();
public List<String> recentPaths = ContainerUtil.newArrayList();
public List<String> openPaths = ContainerUtil.newArrayList();
public Map<String, String> names = ContainerUtil.newLinkedHashMap();
public String lastPath;
void validateRecentProjects() {
//noinspection StatementWithEmptyBody
while (recentPaths.remove(null)) ;
Collection<String> displayNames = names.values();
//noinspection StatementWithEmptyBody
while (displayNames.remove("")) ;
while (recentPaths.size() > Registry.intValue("ide.max.recent.projects")) {
int index = recentPaths.size() - 1;
names.remove(recentPaths.get(index));
recentPaths.remove(index);
}
}
void removePath(String path) {
recentPaths.remove(path);
names.remove(path);
}
}
private final Object myStateLock = new Object();
@@ -61,14 +83,13 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon
private final Map<String, String> myNameCache = Collections.synchronizedMap(new HashMap<String, String>());
public RecentProjectsManagerBase(ProjectManager projectManager, MessageBus messageBus) {
projectManager.addProjectManagerListener(new MyProjectManagerListener());
protected RecentProjectsManagerBase(MessageBus messageBus) {
messageBus.connect().subscribe(AppLifecycleListener.TOPIC, new MyAppLifecycleListener());
}
public State getState() {
synchronized (myStateLock) {
validateRecentProjects();
myState.validateRecentProjects();
return myState;
}
}
@@ -88,37 +109,16 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon
}
}
private void validateRecentProjects() {
synchronized (myStateLock) {
for (Iterator i = myState.recentPaths.iterator(); i.hasNext();) {
String s = (String)i.next();
if (s == null) {
i.remove();
}
}
while (myState.recentPaths.size() > Registry.intValue("ide.max.recent.projects")) {
final int index = myState.recentPaths.size() - 1;
myState.names.remove(myState.recentPaths.get(index));
myState.recentPaths.remove(index);
}
}
}
public void removePath(final String path) {
if (path == null) return;
synchronized (myStateLock) {
if (SystemInfo.isFileSystemCaseSensitive) {
myState.recentPaths.remove(path);
myState.names.remove(path);
myState.removePath(path);
}
else {
Iterator<String> i = myState.recentPaths.iterator();
while (i.hasNext()) {
String p = i.next();
for (String p : ArrayUtil.toStringArray(myState.recentPaths)) {
if (path.equalsIgnoreCase(p)) {
myState.names.remove(p);
i.remove();
myState.removePath(path);
}
}
}
@@ -137,13 +137,16 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon
if (openProjects.length == 0) {
myState.lastPath = null;
myState.openPaths = Collections.emptyList();
} else {
}
else {
myState.lastPath = getProjectPath(openProjects[openProjects.length - 1]);
myState.openPaths = new ArrayList<String>();
myState.openPaths = ContainerUtil.newArrayList();
for (Project openProject : openProjects) {
final String path = getProjectPath(openProject);
ContainerUtil.addIfNotNull(myState.openPaths, path);
myState.names.put(path, getProjectDisplayName(openProject));
String path = getProjectPath(openProject);
if (path != null) {
myState.openPaths.add(path);
myState.names.put(path, getProjectDisplayName(openProject));
}
}
}
}
@@ -157,17 +160,11 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon
private Set<String> getDuplicateProjectNames(Set<String> openedPaths, Set<String> recentPaths) {
Set<String> names = ContainerUtil.newHashSet();
Set<String> duplicates = ContainerUtil.newHashSet();
for (String path : openedPaths) {
for (String path : ContainerUtil.concat(openedPaths, recentPaths)) {
if (!names.add(getProjectName(path))) {
duplicates.add(path);
}
}
for (String path : recentPaths) {
if (!names.add(getProjectName(path))) {
duplicates.add(path);
}
}
return duplicates;
}
@@ -177,17 +174,17 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon
* @return
*/
public AnAction[] getRecentProjectsActions(boolean addClearListItem) {
validateRecentProjects();
final Set<String> paths;
synchronized (myStateLock) {
myState.validateRecentProjects();
paths = ContainerUtil.newLinkedHashSet(myState.recentPaths);
}
final Set<String> openedPaths = ContainerUtil.newHashSet();
for (Project openProject : ProjectManager.getInstance().getOpenProjects()) {
ContainerUtil.addIfNotNull(openedPaths, getProjectPath(openProject));
}
final LinkedHashSet<String> paths;
synchronized (myStateLock) {
paths = ContainerUtil.newLinkedHashSet(myState.recentPaths);
}
paths.remove(null);
paths.removeAll(openedPaths);
@@ -220,7 +217,7 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon
list.add(action);
}
if (addClearListItem) {
AnAction clearListAction = new AnAction(IdeBundle.message("action.clear.list")) {
AnAction clearListAction = new DumbAwareAction(IdeBundle.message("action.clear.list")) {
public void actionPerformed(AnActionEvent e) {
final int rc = Messages.showOkCancelDialog(e.getData(CommonDataKeys.PROJECT),
"Would you like to clear the list of recent projects?",
@@ -261,34 +258,35 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon
return file.exists() && (!file.isDirectory() || new File(file, Project.DIRECTORY_STORE_FOLDER).exists());
}
private class MyProjectManagerListener extends ProjectManagerAdapter {
public void projectOpened(final Project project) {
if (ApplicationManager.getApplication().isHeadlessEnvironment()) return;
String path = getProjectPath(project);
public void projectOpened(final Project project) {
String path = getProjectPath(project);
if (path != null) {
markPathRecent(path);
}
SystemDock.updateMenu();
}
@Override
public final boolean canCloseProject(Project project) {
return true;
}
@Override
public void projectClosing(Project project) {
synchronized (myStateLock) {
myState.names.put(getProjectPath(project), getProjectDisplayName(project));
}
}
public void projectClosed(final Project project) {
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
if (openProjects.length > 0) {
String path = getProjectPath(openProjects[openProjects.length - 1]);
if (path != null) {
markPathRecent(path);
}
SystemDock.updateMenu();
}
@Override
public void projectClosing(Project project) {
synchronized (myStateLock) {
myState.names.put(getProjectPath(project), getProjectDisplayName(project));
}
}
public void projectClosed(final Project project) {
if (ApplicationManager.getApplication().isHeadlessEnvironment()) return;
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
if (openProjects.length > 0) {
String path = getProjectPath(openProjects[openProjects.length - 1]);
if (path != null) {
markPathRecent(path);
}
}
SystemDock.updateMenu();
}
SystemDock.updateMenu();
}
@NotNull
@@ -330,35 +328,46 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon
}
}
protected boolean willReopenProjectOnStart() {
return GeneralSettings.getInstance().isReopenLastProject() && getLastProjectPath() != null;
}
protected void doReopenLastProject() {
GeneralSettings generalSettings = GeneralSettings.getInstance();
if (generalSettings.isReopenLastProject()) {
Collection<String> openPaths;
synchronized (myStateLock) {
openPaths = ContainerUtil.newLinkedHashSet(myState.openPaths);
}
if (!openPaths.isEmpty()) {
for (String openPath : openPaths) {
if (isValidProjectPath(openPath)) {
doOpenProject(openPath, null, true);
}
}
}
else {
String lastProjectPath = getLastProjectPath();
if (lastProjectPath != null) {
if (isValidProjectPath(lastProjectPath)) doOpenProject(lastProjectPath, null, false);
}
}
}
}
private class MyAppLifecycleListener extends AppLifecycleListener.Adapter {
public void appFrameCreated(final String[] commandLineArgs, @NotNull final Ref<Boolean> willOpenProject) {
if (GeneralSettings.getInstance().isReopenLastProject() && getLastProjectPath() != null) {
if (!ApplicationManager.getApplication().isHeadlessEnvironment()) {
ProjectManager.getInstance().addProjectManagerListener(RecentProjectsManagerBase.this);
}
if (willReopenProjectOnStart()) {
willOpenProject.set(Boolean.TRUE);
}
}
public void appStarting(final Project projectFromCommandLine) {
public void appStarting(Project projectFromCommandLine) {
if (projectFromCommandLine != null) return;
GeneralSettings generalSettings = GeneralSettings.getInstance();
if (generalSettings.isReopenLastProject()) {
List<String> openPaths;
synchronized (myStateLock) {
openPaths = ContainerUtil.newArrayList(myState.openPaths);
}
if (!openPaths.isEmpty()) {
for (String openPath : openPaths) {
if (isValidProjectPath(openPath)) {
doOpenProject(openPath, null, true);
}
}
}
else {
String lastProjectPath = getLastProjectPath();
if (lastProjectPath != null) {
if (isValidProjectPath(lastProjectPath)) doOpenProject(lastProjectPath, null, false);
}
}
}
doReopenLastProject();
}
public void projectFrameClosed() {
@@ -19,6 +19,7 @@ import com.intellij.CommonBundle;
import com.intellij.conversion.ConversionResult;
import com.intellij.conversion.ConversionService;
import com.intellij.ide.AppLifecycleListener;
import com.intellij.ide.RecentProjectsManagerBase;
import com.intellij.ide.impl.ProjectUtil;
import com.intellij.ide.startup.impl.StartupManagerImpl;
import com.intellij.notification.NotificationsManager;
@@ -58,6 +59,7 @@ import com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl;
import com.intellij.openapi.wm.impl.welcomeScreen.WelcomeFrame;
import com.intellij.util.Alarm;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.TimeoutUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
@@ -118,7 +120,10 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
return array;
}
public ProjectManagerImpl(VirtualFileManager virtualFileManager, ProgressManager progressManager) {
/** @noinspection UnusedParameters*/
public ProjectManagerImpl(VirtualFileManager virtualFileManager,
RecentProjectsManagerBase recentProjectsManager,
ProgressManager progressManager) {
myProgressManager = progressManager;
Application app = ApplicationManager.getApplication();
MessageBus messageBus = app.getMessageBus();
@@ -291,7 +296,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
@NotNull String filePath,
boolean isDefault,
boolean isOptimiseTestLoadSpeed) {
return isDefault ? new DefaultProject(this, "", isOptimiseTestLoadSpeed, projectName)
return isDefault ? new DefaultProject(this, "", isOptimiseTestLoadSpeed, ObjectUtils.assertNotNull(projectName))
: new ProjectImpl(this, new File(filePath).getAbsolutePath(), isOptimiseTestLoadSpeed, projectName);
}
@@ -22,6 +22,9 @@
<xi:include href="/META-INF/VcsExtensions.xml" xpointer="xpointer(/idea-plugin/extensions/*)"/>
<xi:include href="/META-INF/LangExtensions.xml" xpointer="xpointer(/idea-plugin/extensions/*)"/>
<applicationService serviceInterface="com.intellij.ide.RecentProjectsManagerBase"
serviceImplementation="com.intellij.ide.RecentDirectoryProjectsManagerEx"/>
<applicationService serviceInterface="com.intellij.packageDependencies.DependenciesVisitorFactory"
serviceImplementation="com.intellij.packageDependencies.DependenciesVisitorFactory"/>
<applicationService serviceInterface="com.intellij.openapi.projectRoots.ProjectJdkTable"
@@ -18,6 +18,9 @@
<xi:include href="/META-INF/PlatformExtensions.xml" xpointer="xpointer(/idea-plugin/extensions/*)"/>
<xi:include href="/META-INF/VcsExtensions.xml" xpointer="xpointer(/idea-plugin/extensions/*)"/>
<applicationService serviceInterface="com.intellij.ide.RecentProjectsManagerBase"
serviceImplementation="com.intellij.ide.RecentDirectoryProjectsManager"/>
<applicationService serviceInterface="com.intellij.codeStyle.CodeStyleFacade"
serviceImplementation="com.intellij.codeStyle.DefaultCodeStyleFacade"/>
@@ -15,10 +15,6 @@
<interface-class>com.intellij.openapi.project.impl.ProjectStoreClassProvider</interface-class>
<implementation-class>com.intellij.openapi.components.impl.stores.PlatformProjectStoreClassProvider</implementation-class>
</component>
<component>
<interface-class>com.intellij.ide.RecentProjectsManagerBase</interface-class>
<implementation-class>com.intellij.ide.RecentDirectoryProjectsManager</implementation-class>
</component>
</application-components>
<project-components>
<component>
@@ -53,7 +49,7 @@
<component>
<implementation-class>com.intellij.platform.PlatformVcsDetector</implementation-class>
<headless-implementation-class></headless-implementation-class>
<headless-implementation-class/>
</component>
</project-components>
@@ -15,10 +15,6 @@
<interface-class>com.intellij.openapi.project.impl.ProjectStoreClassProvider</interface-class>
<implementation-class>com.intellij.openapi.components.impl.stores.PlatformLangProjectStoreClassProvider</implementation-class>
</component>
<component>
<interface-class>com.intellij.ide.RecentProjectsManagerBase</interface-class>
<implementation-class>com.intellij.ide.RecentDirectoryProjectsManagerEx</implementation-class>
</component>
</application-components>
<project-components>
<component>
@@ -78,13 +78,24 @@ public class GuardBlockTest extends LightPlatformCodeInsightFixtureTestCase {
public void testNoCompletion() throws Exception {
String text = "abc abd a<caret> abx";
myFixture.configureByText("x.txt", text);
createGuard(0, myFixture.getFile().getTextLength());
int offset = myFixture.getEditor().getCaretModel().getOffset();
createGuard(offset - 1, myFixture.getFile().getTextLength()).setGreedyToRight(true);
assertNull(myFixture.completeBasic());
myFixture.checkResult(text);
//no hippie completion
myFixture.performEditorAction(IdeActions.ACTION_HIPPIE_BACKWARD_COMPLETION);
assertNull(LookupManager.getInstance(getProject()).getActiveLookup());
myFixture.checkResult(text);
//no completion at the file end
myFixture.getEditor().getCaretModel().moveToOffset(myFixture.getFile().getTextLength());
assertNull(myFixture.completeBasic());
myFixture.checkResult("abc abd a abx<caret>");
//completion at the beginning of the guard fragment
myFixture.getEditor().getCaretModel().moveToOffset(offset - 1);
assertNotNull(myFixture.completeBasic());
}
}
@@ -15,6 +15,7 @@
*/
package com.intellij.execution.rmi;
import com.intellij.execution.rmi.ssl.SslSocketFactory;
import org.jetbrains.annotations.Nullable;
import javax.naming.Context;
@@ -28,6 +29,7 @@ import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.ExportException;
import java.rmi.server.UnicastRemoteObject;
import java.security.Security;
import java.util.Hashtable;
import java.util.Random;
@@ -43,6 +45,7 @@ public class RemoteServer {
protected static void start(Remote remote) throws Exception {
setupRMI();
banJNDI();
setupSSL();
if (ourRemote != null) throw new AssertionError("Already started");
ourRemote = remote;
@@ -101,6 +104,12 @@ public class RemoteServer {
}
}
public static void setupSSL() {
if (System.getProperty(SslSocketFactory.SSL_CA_CERT_PATH) != null) {
Security.setProperty("ssl.SocketFactory.provider", "com.intellij.execution.rmi.ssl.SslSocketFactory");
}
}
@SuppressWarnings("UnusedDeclaration")
public static class Jndi implements InitialContextFactory, InvocationHandler {
@Override
@@ -0,0 +1,102 @@
package com.intellij.execution.rmi.ssl;
import javax.net.ssl.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.UUID;
public class SslSocketFactory extends SSLSocketFactory {
public static final String SSL_CA_CERT_PATH = "sslCaCertPath";
private SSLSocketFactory myFactory;
public SslSocketFactory() throws GeneralSecurityException, IOException {
super();
SSLContext ctx = SSLContext.getInstance("TLS");
TrustManager tm;
try {
tm = new MyX509TrustManager();
}
catch (Exception e) {
throw new RuntimeException(e);
}
ctx.init(new KeyManager[]{}, new TrustManager[]{tm}, null);
myFactory = ctx.getSocketFactory();
}
public Socket createSocket(InetAddress host, int port) throws IOException {
return myFactory.createSocket(host, port);
}
public Socket createSocket(String host, int port) throws IOException {
return myFactory.createSocket(host, port);
}
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
return myFactory.createSocket(host, port, localHost, localPort);
}
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return myFactory.createSocket(address, port, localAddress, localPort);
}
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
return myFactory.createSocket(socket, host, port, autoClose);
}
public String[] getDefaultCipherSuites() {
return myFactory.getDefaultCipherSuites();
}
public String[] getSupportedCipherSuites() {
return myFactory.getSupportedCipherSuites();
}
private static class MyX509TrustManager implements X509TrustManager {
String serverCertFile;
X509TrustManager trustManager;
public MyX509TrustManager() throws Exception {
serverCertFile = System.getProperty(SSL_CA_CERT_PATH);
InputStream inStream = new FileInputStream(serverCertFile);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate ca = (X509Certificate)cf.generateCertificate(inStream);
inStream.close();
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null);
ks.setCertificateEntry(UUID.randomUUID().toString(), ca);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
for (TrustManager tm : tmf.getTrustManagers()) {
if (tm instanceof X509TrustManager) {
trustManager = (X509TrustManager)tm;
break;
}
}
if (trustManager == null) {
throw new RuntimeException("No X509TrustManager found");
}
}
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
if (trustManager == null) throw new RuntimeException("No X509TrustManager found");
trustManager.checkServerTrusted(x509Certificates, s);
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
}
@@ -154,9 +154,6 @@ public class EclipseCodeStyleSchemeImporter implements SchemeImporter<CodeStyleS
VALUE_TRUE.equals(value)) {
return true;
}
if (key.contains("alignment") && value.matches("\\d*")) {
return isAlignmentOn(value);
}
if (!(VALUE_DO_NOT_INSERT.equals(value) ||
VALUE_FALSE.equals(value))) {
throw new SchemeImportException("Unrecognized boolean value: " + value + ", key: " + key);
@@ -172,12 +169,57 @@ public class EclipseCodeStyleSchemeImporter implements SchemeImporter<CodeStyleS
return Integer.parseInt(value);
}
private static boolean isAlignmentOn(@NotNull String value) {
int packed = valueToInt(value);
return (packed & 2) != 0;
private static class AlignmentAndWrapValueDecoder {
int myEncodedValue;
public AlignmentAndWrapValueDecoder(int encodedValue) {
myEncodedValue = encodedValue;
}
public int getWrapType() {
switch (getEclipseWrap()) {
case WRAP_WHERE_NECESSARY:
case WRAP_FIRST_OTHERS_WHERE_NECESSARY:
return CommonCodeStyleSettings.WRAP_AS_NEEDED;
case WRAP_ALL_EXCEPT_FIRST:
case WRAP_ALL_INDENT_EXCEPT_FIRST:
case WRAP_ALL_ON_NEW_LINE_EACH:
return CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM;
}
return CommonCodeStyleSettings.DO_NOT_WRAP;
}
public int getFirstElementWrapType() {
return isNewLineBeforeFirst() ? CommonCodeStyleSettings.WRAP_ALWAYS :
getEclipseWrap() == WRAP_ALL_EXCEPT_FIRST ? CommonCodeStyleSettings.DO_NOT_WRAP :
CommonCodeStyleSettings.WRAP_AS_NEEDED;
}
public boolean isFirstElementWrapped() {
int eclipseWrapValue = getEclipseWrap();
return eclipseWrapValue == WRAP_FIRST_OTHERS_WHERE_NECESSARY ||
eclipseWrapValue == WRAP_ALL_INDENT_EXCEPT_FIRST ||
eclipseWrapValue == WRAP_ALL_ON_NEW_LINE_EACH ||
isNewLineBeforeFirst();
}
public boolean isNewLineBeforeFirst() {
return (myEncodedValue & 1) != 0;
}
public boolean isAlignmentOn() {
return (myEncodedValue & 2) != 0;
}
public int getEclipseWrap() {
return myEncodedValue & WRAP_MASK;
}
}
private static void setProgrammatically(@NotNull Object object, @NotNull String key, @NotNull String value) throws SchemeImportException {
if (key.contains("alignment") && value.matches("\\d*") && object instanceof CommonCodeStyleSettings) {
if (setAlignmentAndWrappingOptions((CommonCodeStyleSettings)object, key, value)) return;
}
if (object instanceof CodeStyleSettings) {
CodeStyleSettings settings = (CodeStyleSettings)object;
if (OPTION_REMOVE_JAVADOC_BLANK_LINES.equals(key)) {
@@ -228,4 +270,66 @@ public class EclipseCodeStyleSchemeImporter implements SchemeImporter<CodeStyleS
}
}
}
private static boolean setAlignmentAndWrappingOptions(@NotNull CommonCodeStyleSettings settings,
@NotNull String key,
@NotNull String value) {
int encodedValue = Integer.parseInt(value);
AlignmentAndWrapValueDecoder decoder = new AlignmentAndWrapValueDecoder(encodedValue);
if (OPTION_ALIGN_ARGS_IN_ANNOTATION.equals(key)) {
settings.FIELD_ANNOTATION_WRAP =
settings.METHOD_ANNOTATION_WRAP =
settings.PARAMETER_ANNOTATION_WRAP =
settings.VARIABLE_ANNOTATION_WRAP =
settings.CLASS_ANNOTATION_WRAP = decoder.getWrapType();
return true;
}
else if (OPTION_ALIGN_EXPR_IN_ARRAY_INITIALIZER.equals(key)) {
settings.ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION = decoder.isAlignmentOn();
settings.ARRAY_INITIALIZER_WRAP = decoder.getWrapType();
settings.ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE = decoder.isFirstElementWrapped();
return true;
}
else if (OPTION_ALIGN_ARGS_IN_METHOD_INVOCATION.equals(key)) {
settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = decoder.isAlignmentOn();
settings.CALL_PARAMETERS_WRAP = decoder.getWrapType();
settings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = decoder.isFirstElementWrapped();
return true;
}
else if (OPTION_ALIGN_INTERFACES_IN_TYPE_DECL.equals(key)) {
settings.ALIGN_MULTILINE_EXTENDS_LIST = decoder.isAlignmentOn();
settings.EXTENDS_KEYWORD_WRAP = decoder.getFirstElementWrapType();
settings.EXTENDS_LIST_WRAP = decoder.getWrapType();
return true;
}
else if (OPTION_ALIGN_ASSIGNMENT.equals(key)) {
settings.ALIGN_MULTILINE_ASSIGNMENT = decoder.isAlignmentOn();
settings.ASSIGNMENT_WRAP = decoder.getWrapType();
return true;
}
else if (OPTION_ALIGN_METHOD_DECL_PARAMETERS.equals(key)) {
settings.ALIGN_MULTILINE_PARAMETERS = decoder.isAlignmentOn();
settings.METHOD_PARAMETERS_WRAP = decoder.getWrapType();
settings.METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE = decoder.isFirstElementWrapped();
return true;
}
else if (OPTION_ALIGN_BINARY_EXPR.equals(key)) {
settings.ALIGN_MULTILINE_BINARY_OPERATION = decoder.isAlignmentOn();
settings.BINARY_OPERATION_WRAP = decoder.getWrapType();
return true;
}
else if (OPTION_ALIGN_THROWS_IN_METHOD_DECL.equals(key)) {
settings.ALIGN_MULTILINE_THROWS_LIST = decoder.isAlignmentOn();
settings.THROWS_KEYWORD_WRAP = decoder.getFirstElementWrapType();
settings.THROWS_LIST_WRAP = decoder.getWrapType();
return true;
}
else if (OPTION_ALIGN_RESOURCES_IN_TRY.equals(key)) {
settings.ALIGN_MULTILINE_RESOURCES = decoder.isAlignmentOn();
settings.RESOURCE_LIST_WRAP = decoder.getWrapType();
settings.RESOURCE_LIST_LPAREN_ON_NEXT_LINE = decoder.isFirstElementWrapped();
return true;
}
return false;
}
}
@@ -34,7 +34,7 @@ org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=Java:
#org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=
#org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=
#org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=Java:ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=Java:<Programmatic>
#org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=Java:SPACE_BEFORE_FOR_PARENTHESES
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=Java:<Programmatic>
@@ -49,7 +49,7 @@ org.eclipse.jdt.core.formatter.blank_lines_after_package=Java:BLANK_LINES_AFTER_
#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=
org.eclipse.jdt.core.formatter.continuation_indentation=Java:IndentOptions:<Programmatic>
#org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=Java:ALIGN_MULTILINE_PARAMETERS_IN_CALLS
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=Java:<Programmatic>
#org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=
#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=
#org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=
@@ -91,8 +91,8 @@ org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized
org.eclipse.jdt.core.formatter.indentation.size=Java:IndentOptions:INDENT_SIZE
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=Java:SPACE_WITHIN_EMPTY_METHOD_PARENTHESES
#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=Java:ALIGN_MULTILINE_EXTENDS_LIST
org.eclipse.jdt.core.formatter.alignment_for_assignment=Java:ALIGN_MULTILINE_ASSIGNMENT
#org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=Java:ALIGN_MULTILINE_EXTENDS_LIST
org.eclipse.jdt.core.formatter.alignment_for_assignment=Java:<Programmatic>
org.eclipse.jdt.core.formatter.tabulation.char=Java:IndentOptions:<Programmatic>
#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=
#org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=
@@ -107,7 +107,7 @@ org.eclipse.jdt.core.formatter.blank_lines_before_method=Java:BLANK_LINES_AROUND
#org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=
#org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=
#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=Java:ALIGN_MULTILINE_PARAMETERS_IN_CALLS
#org.eclipse.jdt.core.formatter.alignment_for_method_declaration=
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=Java:SPACE_WITHIN_METHOD_CALL_PARENTHESES
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=Java:SPACE_WITHIN_TRY_PARENTHESES
#org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=
@@ -150,7 +150,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_p
#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=
org.eclipse.jdt.core.formatter.tabulation.size=Java:IndentOptions:<Programmatic>
#org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=Java:ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE
#org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=Java:ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE
#org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=
#org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=
#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=
@@ -193,8 +193,8 @@ org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=<Progra
#org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=
#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=
#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=
#org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=Java:ALIGN_MULTILINE_BINARY_OPERATION
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=Java:<Programmatic>
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=Java:<Programmatic>
#org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=
#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=Java:SPACE_WITHIN_WHILE_PARENTHESES
@@ -236,7 +236,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=Java:
org.eclipse.jdt.core.formatter.blank_lines_before_imports=Java:BLANK_LINES_BEFORE_IMPORTS
#org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=
#org.eclipse.jdt.core.formatter.comment.format_html=
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=Java:ALIGN_MULTILINE_THROWS_LIST
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=Java:<Programmatic>
#org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=
#org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=
#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=
@@ -248,11 +248,11 @@ org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=Java:SPA
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=Java:SPACE_BEFORE_SYNCHRONIZED_PARENTHESES
#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=
#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=Java:ALIGN_MULTILINE_PARAMETERS
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=Java:<Programmatic>
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=Java:SPACE_WITHIN_ARRAY_INITIALIZER_BRACES
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=Java:ALIGN_MULTILINE_RESOURCES
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=Java:<Programmatic>
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=Java:IndentOptions:SMART_TABS
#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=Java:<Programmatic>
#org.eclipse.jdt.core.formatter.comment.format_header=
#org.eclipse.jdt.core.formatter.comment.format_block_comments=
#org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=
@@ -48,4 +48,25 @@ public interface EclipseXmlProfileElements {
String OPTION_TAB_CHAR = "org.eclipse.jdt.core.formatter.tabulation.char";
String OPTION_CONTINUATION_INDENT = "org.eclipse.jdt.core.formatter.continuation_indentation";
String OPTION_TAB_SIZE = "org.eclipse.jdt.core.formatter.tabulation.size";
String OPTION_ALIGN_EXPR_IN_ARRAY_INITIALIZER = "org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer";
String OPTION_ALIGN_ARGS_IN_ANNOTATION = "org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation";
String OPTION_ALIGN_ARGS_IN_METHOD_INVOCATION = "org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation";
String OPTION_ALIGN_SUPERCLASS_IN_TYPE_DECL = "org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration";
String OPTION_ALIGN_INTERFACES_IN_TYPE_DECL = "org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration";
String OPTION_ALIGN_ASSIGNMENT = "org.eclipse.jdt.core.formatter.alignment_for_assignment";
String OPTION_ALIGN_METHOD_DECL_PARAMETERS = "org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration";
String OPTION_ALIGN_BINARY_EXPR = "org.eclipse.jdt.core.formatter.alignment_for_binary_expression";
String OPTION_ALIGN_THROWS_IN_METHOD_DECL = "org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration";
String OPTION_ALIGN_RESOURCES_IN_TRY = "org.eclipse.jdt.core.formatter.alignment_for_resources_in_try";
String OPTION_ALIGN_METHOD_DECL = "org.eclipse.jdt.core.formatter.alignment_for_method_declaration";
int WRAP_MASK = 0x70;
int DO_NOT_WRAP = 0x00;
int WRAP_WHERE_NECESSARY = 0x10;
int WRAP_FIRST_OTHERS_WHERE_NECESSARY = 0x20;
int WRAP_ALL_ON_NEW_LINE_EACH = 0x30;
int WRAP_ALL_INDENT_EXCEPT_FIRST = 0x40;
int WRAP_ALL_EXCEPT_FIRST = 0x50;
}
@@ -27,7 +27,7 @@
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="34"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
@@ -42,7 +42,7 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
@@ -87,7 +87,7 @@
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@on_tag"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="18"/>
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
@@ -190,8 +190,8 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="50"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="50"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
@@ -234,7 +234,7 @@
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="18"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
@@ -246,12 +246,12 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="36"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="50"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
@@ -63,7 +63,6 @@ public class EclipseSettingsImportTest extends PlatformTestCase {
EditorSettingsExternalizable editorSettings = EditorSettingsExternalizable.getInstance();
boolean currAddLineFeed = editorSettings.isEnsureNewLineAtEOF();
editorSettings.setEnsureNewLineAtEOF(true);
javaSettings.ALIGN_MULTILINE_BINARY_OPERATION = true;
javaSettings.SPACE_WITHIN_TRY_PARENTHESES = true;
javaSettings.SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES = true;
javaSettings.WHILE_ON_NEW_LINE = true;
@@ -76,12 +75,9 @@ public class EclipseSettingsImportTest extends PlatformTestCase {
javaSettings.SPACE_WITHIN_SYNCHRONIZED_PARENTHESES = true;
javaSettings.SPACE_BEFORE_QUEST = false;
javaSettings.BLANK_LINES_BEFORE_IMPORTS = 0;
javaSettings.ALIGN_MULTILINE_THROWS_LIST = true;
javaSettings.SPACE_AFTER_COLON = false;
javaSettings.SPACE_WITHIN_FOR_PARENTHESES = true;
javaSettings.SPACE_BEFORE_SYNCHRONIZED_PARENTHESES = false;
javaSettings.ALIGN_MULTILINE_PARAMETERS = true;
javaSettings.ALIGN_MULTILINE_RESOURCES = true;
javaSettings.SPACE_BEFORE_SWITCH_PARENTHESES = false;
javaSettings.SPACE_WITHIN_METHOD_CALL_PARENTHESES = true;
javaSettings.CLASS_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE;
@@ -92,6 +88,33 @@ public class EclipseSettingsImportTest extends PlatformTestCase {
javaSettings.BLANK_LINES_AFTER_IMPORTS = -1;
javaSettings.KEEP_FIRST_COLUMN_COMMENT = true;
javaSettings.KEEP_CONTROL_STATEMENT_IN_ONE_LINE = true;
javaSettings.FIELD_ANNOTATION_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP;
javaSettings.METHOD_ANNOTATION_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP;
javaSettings.PARAMETER_ANNOTATION_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP;
javaSettings.VARIABLE_ANNOTATION_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP;
javaSettings.CLASS_ANNOTATION_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP;
javaSettings.ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION = false;
javaSettings.ARRAY_INITIALIZER_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS;
javaSettings.ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE = false;
javaSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
javaSettings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP;
javaSettings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = true;
javaSettings.ALIGN_MULTILINE_EXTENDS_LIST = false;
javaSettings.EXTENDS_KEYWORD_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP;
javaSettings.EXTENDS_LIST_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP;
javaSettings.ALIGN_MULTILINE_ASSIGNMENT = false;
javaSettings.ASSIGNMENT_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP;
javaSettings.ALIGN_MULTILINE_PARAMETERS = true;
javaSettings.METHOD_PARAMETERS_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP;
javaSettings.METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE = false;
javaSettings.ALIGN_MULTILINE_BINARY_OPERATION = false;
javaSettings.BINARY_OPERATION_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP;
javaSettings.ALIGN_MULTILINE_THROWS_LIST = false;
javaSettings.THROWS_KEYWORD_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS;
javaSettings.THROWS_LIST_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP;
javaSettings.ALIGN_MULTILINE_RESOURCES = true;
javaSettings.RESOURCE_LIST_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP;
javaSettings.RESOURCE_LIST_LPAREN_ON_NEXT_LINE = true;
indentOptions.USE_TAB_CHARACTER = false;
indentOptions.SMART_TABS = false;
indentOptions.TAB_SIZE = 3;
@@ -122,7 +145,6 @@ public class EclipseSettingsImportTest extends PlatformTestCase {
assertFalse(javaSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS);
assertEquals(0, javaSettings.BLANK_LINES_BEFORE_PACKAGE);
assertFalse(javaSettings.SPACE_WITHIN_FOR_PARENTHESES);
assertFalse(javaSettings.ALIGN_MULTILINE_ASSIGNMENT);
assertFalse(javaSettings.SPACE_BEFORE_METHOD_PARENTHESES);
assertFalse(javaSettings.SPACE_WITHIN_CATCH_PARENTHESES);
assertFalse(javaSettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES);
@@ -130,7 +152,6 @@ public class EclipseSettingsImportTest extends PlatformTestCase {
assertFalse(javaSettings.SPACE_AROUND_UNARY_OPERATOR);
assertTrue(javaSettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE);
assertFalse(editorSettings.isEnsureNewLineAtEOF());
assertFalse(javaSettings.ALIGN_MULTILINE_BINARY_OPERATION);
assertFalse(javaSettings.SPACE_WITHIN_TRY_PARENTHESES);
assertFalse(javaSettings.SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES);
assertFalse(javaSettings.WHILE_ON_NEW_LINE);
@@ -143,12 +164,9 @@ public class EclipseSettingsImportTest extends PlatformTestCase {
assertFalse(javaSettings.SPACE_WITHIN_SYNCHRONIZED_PARENTHESES);
assertTrue(javaSettings.SPACE_BEFORE_QUEST);
assertEquals(1, javaSettings.BLANK_LINES_BEFORE_IMPORTS);
assertFalse(javaSettings.ALIGN_MULTILINE_THROWS_LIST);
assertTrue(javaSettings.SPACE_AFTER_COLON);
assertFalse(javaSettings.SPACE_WITHIN_FOR_PARENTHESES);
assertTrue(javaSettings.SPACE_BEFORE_SYNCHRONIZED_PARENTHESES);
assertFalse(javaSettings.ALIGN_MULTILINE_PARAMETERS);
assertFalse(javaSettings.ALIGN_MULTILINE_RESOURCES);
assertTrue(javaSettings.SPACE_BEFORE_SWITCH_PARENTHESES);
assertFalse(javaSettings.SPACE_WITHIN_METHOD_CALL_PARENTHESES);
assertEquals(CommonCodeStyleSettings.END_OF_LINE, javaSettings.CLASS_BRACE_STYLE);
@@ -164,6 +182,33 @@ public class EclipseSettingsImportTest extends PlatformTestCase {
assertTrue(settings.FORMATTER_TAGS_ENABLED);
assertEquals("@off_tag", settings.FORMATTER_OFF_TAG);
assertEquals("@on_tag", settings.FORMATTER_ON_TAG);
assertEquals(CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM, javaSettings.FIELD_ANNOTATION_WRAP);
assertEquals(CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM, javaSettings.METHOD_ANNOTATION_WRAP);
assertEquals(CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM, javaSettings.VARIABLE_ANNOTATION_WRAP);
assertEquals(CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM, javaSettings.PARAMETER_ANNOTATION_WRAP);
assertEquals(CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM, javaSettings.CLASS_ANNOTATION_WRAP);
assertTrue(javaSettings.ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION);
assertEquals(CommonCodeStyleSettings.WRAP_AS_NEEDED, javaSettings.ARRAY_INITIALIZER_WRAP);
assertTrue(javaSettings.ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE);
assertFalse(javaSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS);
assertEquals(CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM, javaSettings.CALL_PARAMETERS_WRAP);
assertFalse(javaSettings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE);
assertTrue(javaSettings.ALIGN_MULTILINE_EXTENDS_LIST);
assertEquals(CommonCodeStyleSettings.WRAP_AS_NEEDED, javaSettings.EXTENDS_KEYWORD_WRAP);
assertEquals(CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM, javaSettings.EXTENDS_LIST_WRAP);
assertTrue(javaSettings.ALIGN_MULTILINE_ASSIGNMENT);
assertEquals(CommonCodeStyleSettings.WRAP_AS_NEEDED, javaSettings.ASSIGNMENT_WRAP);
assertFalse(javaSettings.ALIGN_MULTILINE_PARAMETERS);
assertEquals(CommonCodeStyleSettings.WRAP_AS_NEEDED, javaSettings.METHOD_PARAMETERS_WRAP);
assertTrue(javaSettings.METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE);
assertTrue(javaSettings.ALIGN_MULTILINE_BINARY_OPERATION);
assertEquals(CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM, javaSettings.BINARY_OPERATION_WRAP);
assertTrue(javaSettings.ALIGN_MULTILINE_THROWS_LIST);
assertEquals(CommonCodeStyleSettings.WRAP_AS_NEEDED, javaSettings.THROWS_KEYWORD_WRAP);
assertEquals(CommonCodeStyleSettings.WRAP_AS_NEEDED, javaSettings.THROWS_LIST_WRAP);
assertFalse(javaSettings.ALIGN_MULTILINE_RESOURCES);
assertEquals(CommonCodeStyleSettings.WRAP_AS_NEEDED, javaSettings.RESOURCE_LIST_WRAP);
assertFalse(javaSettings.RESOURCE_LIST_LPAREN_ON_NEXT_LINE);
}
finally {
inputStream.close();
@@ -1,6 +1,7 @@
package org.jetbrains.jps.maven.compiler;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.BuildOutputConsumer;
@@ -116,7 +117,13 @@ public class MavenResourcesBuilder extends TargetBuilder<MavenResourceRootDescri
private Pattern getDelimitersPattern() {
Pattern pattern = myDelimitersPattern;
if (pattern == null) {
pattern = Pattern.compile(config.delimitersPattern);
if (StringUtil.isEmpty(config.escapeString)) {
pattern = Pattern.compile(config.delimitersPattern);
}
else {
String quotedEscapeString = Pattern.quote(config.escapeString);
pattern = Pattern.compile("(" + quotedEscapeString + quotedEscapeString + ")|(?:(" + quotedEscapeString + ")?(" + config.delimitersPattern + "))");
}
myDelimitersPattern = pattern;
}
return pattern;
@@ -168,28 +175,31 @@ public class MavenResourcesBuilder extends TargetBuilder<MavenResourceRootDescri
Map<String, String> resolvedProperties = resolvedPropertiesParam;
final Matcher matcher = delimitersPattern.matcher(text);
boolean hasEscapeString = !StringUtil.isEmpty(moduleConfig.escapeString);
final int groupCount = matcher.groupCount();
final String escapeString = moduleConfig.escapeString;
int firstPropertyGroupIndex = hasEscapeString ? 3 : 0;
int last = 0;
while (matcher.find()) {
if (escapeString != null) {
int escapeStringStartIndex = matcher.start() - escapeString.length();
if (escapeStringStartIndex >= last) {
if (text.startsWith(escapeString, escapeStringStartIndex)) {
out.append(text, last, escapeStringStartIndex);
out.append(matcher.group());
last = matcher.end();
continue;
}
}
}
out.append(text, last, matcher.start());
last = matcher.end();
if (hasEscapeString) {
if (matcher.group(1) != null) {
out.append(moduleConfig.escapeString).append(moduleConfig.escapeString); // double escape string
continue;
}
else if (matcher.group(2) != null) {
out.append(matcher.group(3)); // escaped value
continue;
}
}
String propertyName = null;
for (int i = 0; i < groupCount; i++) {
for (int i = firstPropertyGroupIndex; i < groupCount; i++) {
propertyName = matcher.group(i + 1);
if (propertyName != null) {
break;
@@ -868,10 +868,15 @@ public abstract class ResourceFilteringTest extends MavenImportingTestCase {
}
public void testEscapingFiltering() throws Exception {
if (!useJps()) return;
createProjectSubFile("filters/filter.properties", "xxx=value");
createProjectSubFile("resources/file.properties",
"value1=\\${xxx}\n" +
"value2=${xxx}\n");
"value2=\\\\${xxx}\n" +
"value3=\\\\\\${xxx}\n" +
"value3=\\\\\\\\${xxx}\n" +
"value4=.\\.\\\\.\\\\\\.");
importProject("<groupId>test</groupId>" +
"<artifactId>project</artifactId>" +
@@ -901,7 +906,10 @@ public abstract class ResourceFilteringTest extends MavenImportingTestCase {
compileModules("project");
assertResult("target/classes/file.properties",
"value1=${xxx}\n" +
"value2=value\n");
"value2=\\\\value\n" +
"value3=\\\\${xxx}\n" +
"value3=\\\\\\\\value\n" +
"value4=.\\.\\\\.\\\\\\.");
}
public void testPropertyPriority() throws Exception {
+7
View File
@@ -6,6 +6,7 @@ argparse
array
ast
asynchat
asyncio
asyncore
atexit
audiodev
@@ -68,6 +69,8 @@ dummy_thread
dummy_threading
email
encodings
ensurepip
enum
errno
exceptions
fcntl
@@ -150,6 +153,7 @@ os
os2emxpath
ossaudiodev
parser
pathlib
pdb
pickle
pickletools
@@ -194,6 +198,7 @@ robotparser
runpy
sched
select
selectors
sets
sgmllib
sha
@@ -219,6 +224,7 @@ sre_parse
ssl
stat
statcache
statistics
statvfs
string
StringIO
@@ -254,6 +260,7 @@ token
tokenize
trace
traceback
tracemalloc
tty
turtle
turtledemo
@@ -136,11 +136,13 @@ public interface PyClass extends PsiNameIdentifierOwner, PyStatement, NameDefine
/**
* Finds a property with the specified name in the class or one of its ancestors.
*
*
* @param name of the property
* @param inherited
* @return descriptor of property accessors, or null if such property does not exist.
*/
@Nullable
Property findProperty(@NotNull String name);
Property findProperty(@NotNull String name, boolean inherited);
/**
* Apply a processor to every method, looking at superclasses in method resolution order as needed.
@@ -30,7 +30,7 @@ public interface PyTypeProvider {
ExtensionPointName<PyTypeProvider> EP_NAME = ExtensionPointName.create("Pythonid.typeProvider");
@Nullable
PyType getReferenceExpressionType(PyReferenceExpression referenceExpression, TypeEvalContext context);
PyType getReferenceExpressionType(@NotNull PyReferenceExpression referenceExpression, @NotNull TypeEvalContext context);
@Nullable
PyType getReferenceType(@NotNull PsiElement referenceTarget, TypeEvalContext context, @Nullable PsiElement anchor);
@@ -0,0 +1,22 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.psi.types;
/**
* @author vlan
*/
public interface PyOverridingAncestorsClassMembersProvider extends PyClassMembersProvider {
}
@@ -80,7 +80,7 @@ public class PyTypeProviderBase implements PyTypeProvider {
};
@Override
public PyType getReferenceExpressionType(PyReferenceExpression referenceExpression, TypeEvalContext context) {
public PyType getReferenceExpressionType(@NotNull PyReferenceExpression referenceExpression, @NotNull TypeEvalContext context) {
return null;
}
Binary file not shown.
+1 -1
View File
@@ -5,7 +5,7 @@
<body>
<p>You don't need to leave PyCharm to work with your favorite shell. Just choose
<p>You don't need to leave <span class="product">&productName;</span> to work with your favorite shell. Just choose
<span class="control">Tools | Open Terminal</span> on the main menu,
and enjoy using the embedded local terminal. </p>
<p class="image"><img src="images/terminal.png"></p>
@@ -37,7 +37,8 @@ import java.util.Set;
* @author yole
*/
public class PyStdlibTypeProvider extends PyTypeProviderBase {
private static final Set<String> OPEN_FUNCTIONS = ImmutableSet.of("__builtin__.open", "io.open", "os.fdopen");
private static final Set<String> OPEN_FUNCTIONS = ImmutableSet.of("__builtin__.open", "io.open", "os.fdopen",
"pathlib.Path.open");
private static final String BINARY_FILE_TYPE = "io.FileIO[bytes]";
private static final String TEXT_FILE_TYPE = "io.TextIOWrapper[unicode]";
@@ -134,7 +135,10 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase {
for (Map.Entry<PyExpression, PyNamedParameter> entry : arguments.entrySet()) {
final PyNamedParameter parameter = entry.getValue();
if ("mode".equals(parameter.getName())) {
final PyExpression argument = entry.getKey();
PyExpression argument = entry.getKey();
if (argument instanceof PyKeywordArgument) {
argument = ((PyKeywordArgument)argument).getValueExpression();
}
if (argument instanceof PyStringLiteralExpression) {
mode = ((PyStringLiteralExpression)argument).getStringValue();
break;
@@ -22,6 +22,7 @@ import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.PyTargetExpression;
import com.jetbrains.python.psi.types.PyClassMembersProviderBase;
import com.jetbrains.python.psi.types.PyClassType;
import com.jetbrains.python.psi.types.PyOverridingAncestorsClassMembersProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -33,7 +34,7 @@ import java.util.List;
/**
* @author vlan
*/
public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderBase {
public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderBase implements PyOverridingAncestorsClassMembersProvider {
@NotNull
@Override
public Collection<PyDynamicMember> getMembers(@NotNull PyClassType classType, PsiElement location) {
@@ -95,7 +95,7 @@ class PyDocumentationBuilder {
PyType type = context.getType(qual);
if (type instanceof PyClassType) {
cls = ((PyClassType)type).getPyClass();
Property property = cls.findProperty(elementName);
Property property = cls.findProperty(elementName, true);
if (property != null) {
is_property = true;
final AccessDirection dir = AccessDirection.of((PyElement)outer);
@@ -100,7 +100,7 @@ public class PyAttributeOutsideInitInspection extends PyInspection {
for (Map.Entry<String, PyTargetExpression> attribute : attributes.entrySet()) {
String attributeName = attribute.getKey();
if (attributeName == null) continue;
final Property property = containingClass.findProperty(attributeName);
final Property property = containingClass.findProperty(attributeName, true);
if (!attributesInInit.containsKey(attributeName) && property == null) {
registerProblem(attribute.getValue(), PyBundle.message("INSP.attribute.$0.outside.init", attributeName),
new PyMoveAttributeToInitQuickFix());
@@ -86,7 +86,7 @@ public class PyPropertyAccessInspection extends PyInspection {
property = myPropertyCache.get(key);
}
else {
property = cls.findProperty(name);
property = cls.findProperty(name, true);
}
myPropertyCache.put(key, property); // we store nulls, too, to know that a property does not exist
if (property != null) {
@@ -695,7 +695,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
if (overridesGetAttr(cls, myTypeEvalContext)) {
return true;
}
if (cls.findProperty(name) != null) {
if (cls.findProperty(name, true) != null) {
return true;
}
if (PyUtil.hasUnresolvedAncestors(cls, myTypeEvalContext)) {
@@ -585,7 +585,7 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
@Nullable
@Override
public Property findProperty(@NotNull final String name) {
public Property findProperty(@NotNull final String name, boolean inherited) {
Property property = findLocalProperty(name);
if (property != null) {
return property;
@@ -593,10 +593,12 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
if (findMethodByName(name, false) != null || findClassAttribute(name, false) != null) {
return null;
}
for (PyClass aClass : getAncestorClasses()) {
final Property ancestorProperty = ((PyClassImpl)aClass).findLocalProperty(name);
if (ancestorProperty != null) {
return ancestorProperty;
if (inherited) {
for (PyClass aClass : getAncestorClasses()) {
final Property ancestorProperty = ((PyClassImpl)aClass).findLocalProperty(name);
if (ancestorProperty != null) {
return ancestorProperty;
}
}
}
return null;
@@ -174,29 +174,28 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
@Nullable
@Override
public PyType getReturnType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
final PyType type = getGenericReturnType(context, callSite);
PyType type = getGenericReturnType(context, callSite);
if (callSite == null) {
return type;
}
final PyTypeChecker.AnalyzeCallResults results = PyTypeChecker.analyzeCallSite(callSite, context);
if (PyTypeChecker.hasGenerics(type, context)) {
if (results != null) {
final Map<PyGenericType, PyType> substitutions = PyTypeChecker.unifyGenericCall(this, results.getReceiver(), results.getArguments(),
context);
if (substitutions != null) {
return PyTypeChecker.substitute(type, substitutions, context);
}
type = substitutions != null ? PyTypeChecker.substitute(type, substitutions, context) : null;
}
return null;
else {
type = null;
}
}
if (results != null) {
type = replaceSelf(type, results.getReceiver(), context);
}
if (results != null && isDynamicallyEvaluated(results.getArguments().values(), context)) {
return PyUnionType.createWeakType(type);
}
else {
return type;
}
return type;
}
@Nullable
@@ -205,16 +204,36 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
*/
public PyType getReturnTypeWithoutCallSite(@NotNull TypeEvalContext context,
@Nullable PyExpression receiver) {
final PyType type = getGenericReturnType(context, null);
PyType type = getGenericReturnType(context, null);
if (PyTypeChecker.hasGenerics(type, context)) {
final Map<PyGenericType, PyType> substitutions =
PyTypeChecker.unifyGenericCall(this, receiver, Maps.<PyExpression, PyNamedParameter>newHashMap(), context);
final Map<PyGenericType, PyType> substitutions = PyTypeChecker.unifyGenericCall(this, receiver,
Maps.<PyExpression, PyNamedParameter>newHashMap(),
context);
if (substitutions != null) {
return PyTypeChecker.substitute(type, substitutions, context);
type = PyTypeChecker.substitute(type, substitutions, context);
}
else {
type = null;
}
return null;
}
return type;
return replaceSelf(type, receiver, context);
}
@Nullable
private PyType replaceSelf(@Nullable PyType returnType, @Nullable PyExpression receiver, @NotNull TypeEvalContext context) {
if (receiver != null) {
// TODO: Currently we substitute only simple subclass types, but we could handle union and collection types as well
if (returnType instanceof PyClassType) {
final PyClassType returnClassType = (PyClassType)returnType;
if (returnClassType.getPyClass() == getContainingClass()) {
final PyType receiverType = context.getType(receiver);
if (receiverType instanceof PyClassType && PyTypeChecker.match(returnType, receiverType, context)) {
return returnClassType.isDefinition() ? receiverType : ((PyClassType)receiverType).toInstance();
}
}
}
}
return returnType;
}
private static boolean isDynamicallyEvaluated(@NotNull Collection<PyNamedParameter> parameters, @NotNull TypeEvalContext context) {
@@ -265,7 +265,7 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
if (qualifierType instanceof PyClassType) {
final PyClassType classType = (PyClassType)qualifierType;
PyClass pyClass = classType.getPyClass();
Property property = pyClass.findProperty(name);
Property property = pyClass.findProperty(name, true);
if (property != null) {
if (classType.isDefinition()) {
return Ref.<PyType>create(PyBuiltinCache.getInstance(pyClass).getObjectType(PyNames.PROPERTY));
@@ -292,7 +292,7 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
}
@Nullable
private PyType getTypeFromProviders(TypeEvalContext context) {
private PyType getTypeFromProviders(@NotNull TypeEvalContext context) {
for (PyTypeProvider provider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
try {
final PyType type = provider.getReferenceExpressionType(this, context);
@@ -241,8 +241,8 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
if (exprType instanceof PyClassType) {
final PyClass cls = ((PyClassType)exprType).getPyClass();
final PyFunction enter = cls.findMethodByName(PyNames.ENTER, true);
if (enter != null) {
final PyType enterType = enter.getReturnType(context, null);
if (enter instanceof PyFunctionImpl) {
final PyType enterType = ((PyFunctionImpl)enter).getReturnTypeWithoutCallSite(context, expression);
if (enterType != null) {
return enterType;
}
@@ -23,6 +23,7 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiInvalidElementAccessException;
@@ -156,22 +157,9 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
}
if (resolveContext.allowProperties()) {
Property property = myClass.findProperty(name);
if (property != null) {
Maybe<Callable> accessor = property.getByDirection(direction);
if (accessor.isDefined()) {
Callable accessor_code = accessor.value();
ResolveResultList ret = new ResolveResultList();
if (accessor_code != null) ret.poke(accessor_code, RatedResolveResult.RATE_NORMAL);
PyTargetExpression site = property.getDefinitionSite();
if (site != null) ret.poke(site, RatedResolveResult.RATE_LOW);
if (ret.size() > 0) {
return ret;
}
else {
return null;
} // property is found, but the required accessor is explicitly absent
}
final Ref<ResolveResultList> resultRef = findProperty(name, direction, true);
if (resultRef != null) {
return resultRef.get();
}
}
@@ -198,6 +186,11 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
return ResolveResultList.to(classMember);
}
classMember = resolveByOverridingAncestorsMembersProviders(this, name, location);
if (classMember != null) {
return ResolveResultList.to(classMember);
}
if (inherited) {
for (PyClassLikeType type : myClass.getAncestorTypes(context)) {
if (type instanceof PyClassType) {
@@ -237,12 +230,10 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
for (PyClassLikeType type : myClass.getAncestorTypes(context)) {
if (type instanceof PyClassType) {
final PyClass pyClass = ((PyClassType)type).getPyClass();
if (pyClass != null) {
PsiElement superMember = resolveByMembersProviders(new PyClassTypeImpl(pyClass, isDefinition()), name, location);
PsiElement superMember = resolveByMembersProviders(new PyClassTypeImpl(pyClass, isDefinition()), name, location);
if (superMember != null) {
return ResolveResultList.to(superMember);
}
if (superMember != null) {
return ResolveResultList.to(superMember);
}
}
}
@@ -251,6 +242,28 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
return Collections.emptyList();
}
private Ref<ResolveResultList> findProperty(String name, AccessDirection direction, boolean inherited) {
Ref<ResolveResultList> resultRef = null;
Property property = myClass.findProperty(name, inherited);
if (property != null) {
Maybe<Callable> accessor = property.getByDirection(direction);
if (accessor.isDefined()) {
Callable accessor_code = accessor.value();
ResolveResultList ret = new ResolveResultList();
if (accessor_code != null) ret.poke(accessor_code, RatedResolveResult.RATE_NORMAL);
PyTargetExpression site = property.getDefinitionSite();
if (site != null) ret.poke(site, RatedResolveResult.RATE_LOW);
if (ret.size() > 0) {
resultRef = Ref.create(ret);
}
else {
resultRef = Ref.create();
} // property is found, but the required accessor is explicitly absent
}
}
return resultRef;
}
@Nullable
private PyClassType getMetaclassType() {
final PyClass metaClass = PyUtil.getMetaClass(myClass);
@@ -329,6 +342,17 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
return null;
}
@Nullable
private static PsiElement resolveByOverridingAncestorsMembersProviders(PyClassType type, String name, @Nullable PyExpression location) {
for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) {
if (provider instanceof PyOverridingAncestorsClassMembersProvider) {
final PsiElement resolveResult = provider.resolveMember(type, name, location);
if (resolveResult != null) return resolveResult;
}
}
return null;
}
@Nullable
private static PsiElement resolveInner(@NotNull PyClass cls,
boolean isDefinition,
@@ -0,0 +1,12 @@
class C(object):
def __enter__(self):
return self
class D(C):
def foo(self):
pass
with D() as cm:
cm.foo() # pass
@@ -0,0 +1,13 @@
class C(object):
def get_self(self):
return self
class D(C):
def foo(self):
pass
d = D()
print(d.foo())
print(d.get_self().foo()) # pass
@@ -38,7 +38,7 @@ public class PyClassicPropertyTest extends PyTestCase {
public void testV1() throws Exception {
Property p;
Maybe<Callable> accessor;
p = myClass.findProperty("v1");
p = myClass.findProperty("v1", true);
assertNotNull(p);
assertNull(p.getDoc());
PyTargetExpression site = p.getDefinitionSite();
@@ -62,7 +62,7 @@ public class PyClassicPropertyTest extends PyTestCase {
public void testV2() throws Exception {
Property p;
Maybe<Callable> accessor;
p = myClass.findProperty("v2");
p = myClass.findProperty("v2", true);
assertNotNull(p);
assertEquals("doc of v2", p.getDoc());
PyTargetExpression site = p.getDefinitionSite();
@@ -86,7 +86,7 @@ public class PyClassicPropertyTest extends PyTestCase {
public void testV3() throws Exception {
Maybe<Callable> accessor;
Property p = myClass.findProperty("v3");
Property p = myClass.findProperty("v3", true);
assertNotNull(p);
assertNull(p.getDoc());
PyTargetExpression site = p.getDefinitionSite();
@@ -35,7 +35,7 @@ public class PyDecoratedPropertyTest extends PyTestCase {
Property p;
Maybe<Callable> accessor;
final String name = "w1";
p = myClass.findProperty(name);
p = myClass.findProperty(name, true);
assertNotNull(p);
assertNull(p.getDoc());
assertNull(p.getDefinitionSite());
@@ -60,7 +60,7 @@ public class PyDecoratedPropertyTest extends PyTestCase {
Property p;
Maybe<Callable> accessor;
final String name = "w2";
p = myClass.findProperty(name);
p = myClass.findProperty(name, true);
assertNotNull(p);
assertNull(p.getDoc());
assertNull(p.getDefinitionSite());
@@ -118,12 +118,12 @@ public class PyStubsTest extends PyTestCase {
pyClass = classes.get(1);
assertEquals("BarClass", pyClass.getName());
Property prop = pyClass.findProperty("value");
Property prop = pyClass.findProperty("value", true);
Maybe<Callable> maybe_function = prop.getGetter();
assertTrue(maybe_function.isDefined());
assertEquals(pyClass.getMethods()[0], maybe_function.value());
Property setvalueProp = pyClass.findProperty("setvalue");
Property setvalueProp = pyClass.findProperty("setvalue", true);
Maybe<Callable> setter = setvalueProp.getSetter();
assertTrue(setter.isDefined());
assertEquals("__set", setter.value().getName());
@@ -131,7 +131,7 @@ public class PyStubsTest extends PyTestCase {
// properties by decorator
pyClass = classes.get(2);
assertEquals("BazClass", pyClass.getName());
prop = pyClass.findProperty("x");
prop = pyClass.findProperty("x", true);
maybe_function = prop.getGetter();
assertTrue(maybe_function.isDefined());
assertEquals(pyClass.getMethods()[0], maybe_function.value());
@@ -326,6 +326,16 @@ public class PyUnresolvedReferencesInspectionTest extends PyTestCase {
doTest();
}
// PY-10977
public void testContextManagerSubclass() {
doTest();
}
// PY-11413
public void testReturnSelfInSuperClass() {
doTest();
}
private void doTest() {
myFixture.configureByFile(TEST_DIRECTORY + getTestName(true) + ".py");
myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
+1 -1
View File
@@ -5,7 +5,7 @@
<body>
<p>You don't need to leave WebStorm to work with your favorite shell. Just choose
<p>You don't need to leave <span class="product">&productName;</span> to work with your favorite shell. Just choose
<span class="control">Tools | Open Terminal</span> on the main menu,
and enjoy using the embedded local terminal. </p>
<p class="image"><img src="images/terminal.png"></p>
+3 -7
View File
@@ -10,13 +10,6 @@
<xi:include href="/componentSets/IdeaComponents.xml" xpointer="xpointer(/components/*)"/>
<xi:include href="/idea/RichPlatformActions.xml" xpointer="xpointer(/component/*)"/>
<application-components>
<component>
<interface-class>com.intellij.ide.RecentProjectsManagerBase</interface-class>
<implementation-class>com.intellij.ide.RecentProjectsManager</implementation-class>
</component>
</application-components>
<project-components>
<component>
<implementation-class>com.intellij.framework.detection.impl.FrameworkDetectionManager</implementation-class>
@@ -133,6 +126,9 @@
<compiler implementation="com.intellij.packaging.impl.compiler.ArtifactsCompiler" id="artifactsCompiler"/>
<gotoRelatedProvider implementation="com.intellij.testIntegration.GotoTestRelatedProvider"/>
<applicationService serviceInterface="com.intellij.ide.RecentProjectsManagerBase"
serviceImplementation="com.intellij.ide.RecentProjectsManager"/>
<applicationService serviceInterface="com.intellij.util.descriptors.ConfigFileFactory"
serviceImplementation="com.intellij.util.descriptors.impl.ConfigFileFactoryImpl"/>
@@ -305,6 +305,7 @@ nominvalue
nomonitoring
nonatomic
noninfingement
nonnull
nonschema
noorder
noparallel