Merge remote-tracking branch 'origin/master' into IDEA-CR-10038

This commit is contained in:
Vladimir Krivosheev
2016-04-25 12:22:09 +02:00
183 changed files with 2646 additions and 1979 deletions
@@ -27,7 +27,11 @@ import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.*;
import com.intellij.util.PlatformIcons;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import org.jetbrains.annotations.NotNull;
@@ -128,6 +132,18 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer {
nodeIcon = AllIcons.Debugger.Value;
}
}
// if watches in variables enabled, always use watch icon
if (valueDescriptor instanceof WatchItemDescriptor && nodeIcon != AllIcons.Debugger.Watch) {
XDebugSession session = XDebuggerManager.getInstance(valueDescriptor.getProject()).getCurrentSession();
if (session != null) {
XDebugSessionTab tab = ((XDebugSessionImpl)session).getSessionTab();
if (tab != null && tab.isWatchesInVariables()) {
nodeIcon = AllIcons.Debugger.Watch;
}
}
}
final Icon valueIcon = valueDescriptor.getValueIcon();
if (nodeIcon != null && valueIcon != null) {
nodeIcon = new RowIcon(nodeIcon, valueIcon);
@@ -369,7 +369,7 @@ public abstract class JavaTestFrameworkRunnableState<T extends ModuleBasedConfig
protected void writeClassesPerModule(String packageName, JavaParameters javaParameters, Map<Module, List<String>> perModule)
throws FileNotFoundException, UnsupportedEncodingException, CantRunException {
if (perModule != null && perModule.size() > 1) {
if (perModule != null) {
final String classpath = getScope() == TestSearchScope.WHOLE_PROJECT
? null : javaParameters.getClassPath().getPathsString();
@@ -118,15 +118,12 @@ public class ParametersFolder {
PsiExpression mostRanked = null;
for (int i = mentionedInExpressions.size() - 1; i >= 0; i--) {
PsiExpression expression = mentionedInExpressions.get(i);
if (expression instanceof PsiArrayAccessExpression) {
mostRanked = expression;
if (!isConditional(expression, scope)) {
myFoldingSelectedByDefault = true;
break;
}
boolean arrayAccess = expression instanceof PsiArrayAccessExpression && !isConditional(expression, scope);
if (arrayAccess) {
myFoldingSelectedByDefault = true;
}
final int r = findUsedVariables(data, inputVariables, expression).size();
if (currentRank < r) {
if (currentRank < r || arrayAccess && currentRank == r) {
currentRank = r;
mostRanked = expression;
}
@@ -15,7 +15,10 @@
*/
package com.intellij.refactoring.util;
import com.intellij.psi.*;
import com.intellij.psi.LambdaUtil;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiVariable;
import com.intellij.psi.SmartTypePointerManager;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,7 +35,7 @@ public class VariableData extends AbstractVariableData {
public VariableData(@Nullable PsiVariable var, PsiType type) {
variable = var;
if (var != null) {
if (type instanceof PsiLambdaParameterType || type instanceof PsiLambdaExpressionType || type instanceof PsiMethodReferenceType) {
if (LambdaUtil.notInferredType(type)) {
type = PsiType.getJavaLangObject(var.getManager(), GlobalSearchScope.allScope(var.getProject()));
}
this.type = SmartTypePointerManager.getInstance(var.getProject()).createSmartTypePointer(type).getType();
@@ -125,7 +125,7 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
}
}
});
final List<PsiElement> cleanupElements = new ArrayList<PsiElement>();
final List<SmartPsiElementPointer<PsiElement>> cleanupElements = new ArrayList<>();
final List<PsiMethod> filtered = filterConstructorsIfFieldAlreadyAssigned(constructors, getField());
if (filtered.size() > 1) {
final PsiMethodMember[] members = new PsiMethodMember[filtered.size()];
@@ -188,7 +188,7 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
fieldsToFix.clear();
}
}
GlobalInspectionContextBase.cleanupElements(project, null, cleanupElements.toArray(new PsiElement[cleanupElements.size()]));
GlobalInspectionContextBase.cleanupElements(project, null, cleanupElements);
}
@NotNull
@@ -237,7 +237,8 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
final PsiFile file,
final Editor editor,
final PsiMethod constructor,
final PsiField[] fields, final List<PsiElement> cleanupElements) throws IncorrectOperationException {
final PsiField[] fields,
final List<SmartPsiElementPointer<PsiElement>> cleanupElements) throws IncorrectOperationException {
final PsiParameterList parameterList = constructor.getParameterList();
final PsiParameter[] parameters = parameterList.getParameters();
ParameterInfoImpl[] newParamInfos = new ParameterInfoImpl[parameters.length + fields.length];
@@ -328,13 +329,14 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
}
private static boolean doCreate(Project project, Editor editor, PsiParameter[] parameters, SmartPsiElementPointer constructorPointer,
ParameterInfoImpl[] parameterInfos, Map<PsiField, String> fields, List<PsiElement> cleanupElements) {
ParameterInfoImpl[] parameterInfos, Map<PsiField, String> fields, List<SmartPsiElementPointer<PsiElement>> cleanupElements) {
PsiMethod constructor = (PsiMethod)constructorPointer.getElement();
assert constructor != null;
PsiParameter[] newParameters = constructor.getParameterList().getParameters();
if (newParameters == parameters) return false; //user must have canceled dialog
// do not introduce assignment in chained constructor
if (JavaHighlightUtil.getChainedConstructors(constructor) == null) {
final SmartPointerManager manager = SmartPointerManager.getInstance(project);
boolean created = false;
for (PsiField field : fields.keySet()) {
final String defaultParamName = fields.get(field);
@@ -343,10 +345,10 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
continue;
}
NullableNotNullManager.getInstance(field.getProject()).copyNotNullAnnotation(field, parameter);
cleanupElements.add(parameter);
cleanupElements.add(manager.createSmartPsiElementPointer(parameter));
final PsiElement assignmentStatement = AssignFieldFromParameterAction.addFieldAssignmentStatement(project, field, parameter, editor);
if (assignmentStatement != null) {
cleanupElements.add(assignmentStatement);
cleanupElements.add(manager.createSmartPsiElementPointer(assignmentStatement));
}
created = true;
}
@@ -261,10 +261,7 @@ public class CreateFromUsageUtils {
names = new String[]{"p" + i};
}
if (argType == null || PsiType.NULL.equals(argType) ||
argType instanceof PsiLambdaExpressionType ||
argType instanceof PsiLambdaParameterType ||
argType instanceof PsiMethodReferenceType) {
if (argType == null || PsiType.NULL.equals(argType) || LambdaUtil.notInferredType(argType)) {
argType = PsiType.getJavaLangObject(psiManager, resolveScope);
} else if (argType instanceof PsiDisjunctionType) {
argType = ((PsiDisjunctionType)argType).getLeastUpperBound();
@@ -78,6 +78,9 @@ public class CreateLocalFromUsageFix extends CreateVarFromUsageFix {
final SmartTypePointer defaultType = SmartTypePointerManager.getInstance(project).createSmartTypePointer(expectedTypes[0]);
final PsiType preferredType = TypeSelectorManagerImpl.getPreferredType(expectedTypes, expectedTypes[0]);
PsiType type = preferredType != null ? preferredType : expectedTypes[0];
if (LambdaUtil.notInferredType(type)) {
type = PsiType.getJavaLangObject(myReferenceExpression.getManager(), targetClass.getResolveScope());
}
String varName = myReferenceExpression.getReferenceName();
PsiExpression initializer = null;
@@ -40,7 +40,6 @@ import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
import com.intellij.refactoring.changeSignature.OverriderUsageInfo;
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
import com.intellij.refactoring.typeMigration.TypeMigrationProcessor;
import com.intellij.refactoring.typeMigration.TypeMigrationRules;
import com.intellij.usageView.UsageInfo;
@@ -89,14 +88,16 @@ public class MethodReturnTypeFix extends LocalQuickFixAndIntentionActionOnPsiEle
@NotNull PsiElement endElement) {
final PsiMethod myMethod = (PsiMethod)startElement;
PsiType myReturnType = myReturnTypePointer.getType();
return myMethod.isValid()
&& myMethod.getManager().isInProject(myMethod)
&& myReturnType != null
&& myReturnType.isValid()
&& !TypeConversionUtil.isNullType(myReturnType)
&& myMethod.getReturnType() != null
&& !Comparing.equal(myReturnType, myMethod.getReturnType());
final PsiType myReturnType = myReturnTypePointer.getType();
if (myMethod.isValid() &&
myMethod.getManager().isInProject(myMethod) &&
myReturnType != null &&
myReturnType.isValid() &&
!TypeConversionUtil.isNullType(myReturnType)) {
final PsiType returnType = myMethod.getReturnType();
if (returnType != null && returnType.isValid() && !Comparing.equal(myReturnType, returnType)) return true;
}
return false;
}
@Override
@@ -309,7 +309,7 @@ public class JavaChangeInfoImpl extends UserDataHolderBase implements JavaChange
@Nullable
public PsiExpression getValue(int i, PsiCallExpression expr) throws IncorrectOperationException {
if (defaultValues[i] != null) return defaultValues[i];
final PsiElement valueAtCallSite = newParms[i].getActualValue(expr);
final PsiElement valueAtCallSite = newParms[i].getActualValue(expr, PsiSubstitutor.EMPTY);
return valueAtCallSite instanceof PsiExpression ? (PsiExpression)valueAtCallSite : null;
}
@@ -410,7 +410,8 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
//This methods works equally well for primary usages as well as for propagated callers' usages
private static void fixActualArgumentsList(PsiExpressionList list,
JavaChangeInfo changeInfo,
boolean toInsertDefaultValue, PsiSubstitutor substitutor) throws IncorrectOperationException {
boolean toInsertDefaultValue,
PsiSubstitutor substitutor) throws IncorrectOperationException {
final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory();
if (changeInfo.isParameterSetOrOrderChanged()) {
if (changeInfo instanceof JavaChangeInfoImpl && ((JavaChangeInfoImpl)changeInfo).isPropagationEnabled) {
@@ -418,7 +419,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
for (ParameterInfoImpl info : createdParmsInfo) {
PsiExpression newArg;
if (toInsertDefaultValue) {
newArg = createDefaultValue(changeInfo, factory, info, list);
newArg = createDefaultValue(changeInfo, factory, info, list, substitutor);
}
else {
newArg = factory.createExpressionFromText(info.getName(), list);
@@ -486,12 +487,12 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
continue;
}
}
newArgs[i] = createActualArgument(changeInfo, list, newParms[i], toInsertDefaultValue, args);
newArgs[i] = createActualArgument(changeInfo, list, newParms[i], toInsertDefaultValue, args, substitutor);
}
if (changeInfo.isArrayToVarargs()) {
if (newVarargInitializers == null) {
newArgs[newNonVarargCount] =
createActualArgument(changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args);
createActualArgument(changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args, substitutor);
}
else {
System.arraycopy(newVarargInitializers, 0, newArgs, newNonVarargCount, newVarargInitializers.length);
@@ -503,7 +504,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
for (int i = newNonVarargCount; i < newArgsLength; i++){
final int oldIndex = newParms[newNonVarargCount].getOldIndex();
if (oldIndex >= 0 && oldIndex != nonVarargCount) {
newArgs[i] = createActualArgument(changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args);
newArgs[i] = createActualArgument(changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args, substitutor);
} else {
System.arraycopy(args, nonVarargCount, newArgs, newNonVarargCount, newVarargCount);
break;
@@ -526,7 +527,8 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
final PsiExpressionList list,
final JavaParameterInfo info,
final boolean toInsertDefaultValue,
final PsiExpression[] args) throws IncorrectOperationException {
final PsiExpression[] args,
PsiSubstitutor substitutor) throws IncorrectOperationException {
final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory();
final int index = info.getOldIndex();
if (index >= 0 && index < args.length) {
@@ -534,7 +536,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
}
else {
if (toInsertDefaultValue) {
return createDefaultValue(changeInfo, factory, info, list);
return createDefaultValue(changeInfo, factory, info, list, substitutor);
}
else {
return factory.createExpressionFromText(info.getName(), list);
@@ -546,7 +548,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
private static PsiExpression createDefaultValue(JavaChangeInfo changeInfo,
final PsiElementFactory factory,
final JavaParameterInfo info,
final PsiExpressionList list)
final PsiExpressionList list, PsiSubstitutor substitutor)
throws IncorrectOperationException {
if (info.isUseAnySingleVariable()) {
final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(list.getProject()).getResolveHelper();
@@ -593,7 +595,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
}
final PsiCallExpression callExpression = PsiTreeUtil.getParentOfType(list, PsiCallExpression.class);
final String defaultValue = info.getDefaultValue();
return callExpression != null ? (PsiExpression)info.getActualValue(callExpression)
return callExpression != null ? (PsiExpression)info.getActualValue(callExpression, substitutor)
: !StringUtil.isEmpty(defaultValue) ? factory.createExpressionFromText(defaultValue, list) : null;
}
@@ -706,14 +708,13 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
private static void addDelegateArguments(JavaChangeInfo changeInfo, PsiElementFactory factory, final PsiCallExpression callExpression) throws IncorrectOperationException {
final JavaParameterInfo[] newParms = changeInfo.getNewParameters();
final String[] oldParameterNames = changeInfo.getOldParameterNames();
for (int i = 0; i < newParms.length; i++) {
JavaParameterInfo newParm = newParms[i];
for (JavaParameterInfo newParm : newParms) {
final PsiExpression actualArg;
if (newParm.getOldIndex() >= 0) {
actualArg = factory.createExpressionFromText(oldParameterNames[newParm.getOldIndex()], callExpression);
}
else {
actualArg = (PsiExpression)changeInfo.getActualValue(i, callExpression);
actualArg = (PsiExpression)newParm.getActualValue(callExpression, PsiSubstitutor.EMPTY);
}
final PsiExpressionList argumentList = callExpression.getArgumentList();
if (actualArg != null && argumentList != null) {
@@ -34,8 +34,7 @@ public interface JavaParameterInfo extends ParameterInfo {
PsiExpression getValue(PsiCallExpression callExpression);
@Nullable
@Override
default PsiElement getActualValue(PsiElement callExpression) {
default PsiElement getActualValue(PsiElement callExpression, Object substitutor) {
return callExpression instanceof PsiCallExpression ? getValue((PsiCallExpression)callExpression) : null;
}
@@ -16,8 +16,8 @@
package com.intellij.refactoring.inline;
import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInspection.sameParameterValue.SameParameterValueInspection;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
@@ -26,12 +26,18 @@ import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessorBase;
import com.intellij.refactoring.changeSignature.JavaChangeInfo;
import com.intellij.refactoring.changeSignature.JavaChangeInfoImpl;
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
import com.intellij.refactoring.util.CanonicalTypes;
import com.intellij.refactoring.util.InlineUtil;
import com.intellij.refactoring.util.RefactoringUIUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.VisibilityUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -53,6 +59,9 @@ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor
private final PsiCodeBlock myCallingBlock;
private final boolean myCreateLocal;
private JavaChangeInfo myChangeInfo;
private UsageInfo[] myChangeSignatureUsages;
public InlineParameterExpressionProcessor(final PsiCallExpression methodCall,
final PsiMethod method,
final PsiParameter parameter,
@@ -147,6 +156,28 @@ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor
}
}
final PsiParameter[] parameters = myMethod.getParameterList().getParameters();
final List<ParameterInfoImpl> psiParameters = new ArrayList<ParameterInfoImpl>();
int paramIdx = 0;
final String paramName = myParameter.getName();
for (PsiParameter param : parameters) {
if (!Comparing.strEqual(paramName, param.getName())) {
psiParameters.add(new ParameterInfoImpl(paramIdx, param.getName(), param.getType()));
}
paramIdx++;
}
PsiType returnType = myMethod.getReturnType();
myChangeInfo = new JavaChangeInfoImpl(VisibilityUtil.getVisibilityModifier(myMethod.getModifierList()), myMethod, myMethod.getName(),
returnType != null ? CanonicalTypes.createTypeWrapper(returnType) : null,
psiParameters.toArray(new ParameterInfoImpl[psiParameters.size()]),
null,
false,
Collections.emptySet(),
Collections.emptySet() );
myChangeSignatureUsages = ChangeSignatureProcessorBase.findUsages(myChangeInfo);
final UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]);
return UsageViewUtil.removeDuplicatedUsages(usageInfos);
}
@@ -267,7 +298,7 @@ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor
}
}
SameParameterValueInspection.InlineParameterValueFix.removeParameter(myMethod, myParameter);
ChangeSignatureProcessorBase.doChangeSignature(myChangeInfo, myChangeSignatureUsages);
if (!thrownExceptions.isEmpty()) {
for (PsiClassType exception : thrownExceptions) {
@@ -32,20 +32,19 @@ import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
import com.intellij.refactoring.introduceParameterObject.IntroduceParameterObjectClassDescriptor;
import com.intellij.refactoring.introduceParameterObject.IntroduceParameterObjectDelegate;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
public class JavaIntroduceParameterObjectClassDescriptor extends IntroduceParameterObjectClassDescriptor<PsiMethod, ParameterInfoImpl> {
private static final Logger LOG = Logger.getInstance("#" + JavaIntroduceParameterObjectClassDescriptor.class.getName());
private final Set<PsiTypeParameter> myTypeParameters = new HashSet<>();
private final Set<PsiTypeParameter> myTypeParameters = new LinkedHashSet<>();
private final Map<ParameterInfoImpl, ParameterBean> myExistingClassProperties = new HashMap<>();
private final MoveDestination myMoveDestination;
@@ -106,12 +105,7 @@ public class JavaIntroduceParameterObjectClassDescriptor extends IntroduceParame
public String createFakeClassTypeText() {
String text = StringUtil.getQualifiedName(getPackageName(), getClassName());
if (!myTypeParameters.isEmpty()) {
text += "<" + StringUtil.join(myTypeParameters, new Function<PsiTypeParameter, String>() {
@Override
public String fun(PsiTypeParameter parameter) {
return parameter.getName();
}
}, ", ") + ">";
text += "<" + StringUtil.join(myTypeParameters, PsiNamedElement::getName, ", ") + ">";
}
return text;
}
@@ -22,6 +22,7 @@ import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.impl.PsiDiamondTypeUtil;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
@@ -42,6 +43,7 @@ import com.intellij.util.VisibilityUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -86,9 +88,9 @@ public class JavaIntroduceParameterObjectDelegate
return new ParameterInfoImpl(-1, paramName, facade.getElementFactory().createTypeFromText(classTypeText, method), null) {
@Nullable
@Override
public PsiElement getActualValue(PsiElement exp) {
public PsiElement getActualValue(PsiElement exp, Object substitutor) {
final IntroduceParameterObjectDelegate<PsiNamedElement, ParameterInfo, IntroduceParameterObjectClassDescriptor<PsiNamedElement, ParameterInfo>> delegate = findDelegate(exp);
return delegate != null ? delegate.createNewParameterInitializerAtCallSite(exp, descriptor, oldMethodParameters) : null;
return delegate != null ? delegate.createNewParameterInitializerAtCallSite(exp, descriptor, oldMethodParameters, substitutor) : null;
}
};
}
@@ -96,7 +98,8 @@ public class JavaIntroduceParameterObjectDelegate
@Override
public PsiElement createNewParameterInitializerAtCallSite(PsiElement callExpression,
IntroduceParameterObjectClassDescriptor descriptor,
List<? extends ParameterInfo> oldMethodParameters) {
List<? extends ParameterInfo> oldMethodParameters,
Object substitutor) {
if (callExpression instanceof PsiCallExpression) {
final PsiCallExpression expr = (PsiCallExpression)callExpression;
final JavaPsiFacade facade = JavaPsiFacade.getInstance(expr.getProject());
@@ -109,16 +112,31 @@ public class JavaIntroduceParameterObjectDelegate
final PsiExpression[] args = argumentList.getExpressions();
StringBuilder newExpression = new StringBuilder();
final JavaResolveResult resolvant = expr.resolveMethodGenerics();
final PsiSubstitutor substitutor = resolvant.getSubstitutor();
newExpression.append("new ")
.append(JavaPsiFacade.getElementFactory(expr.getProject()).createType(existingClass, substitutor).getCanonicalText());
newExpression.append("new ").append(existingClass.getQualifiedName());
if (descriptor instanceof JavaIntroduceParameterObjectClassDescriptor) {
List<String> types = new ArrayList<>();
for (PsiTypeParameter parameter : ((JavaIntroduceParameterObjectClassDescriptor)descriptor).getTypeParameters()) {
PsiType type = ((PsiSubstitutor)substitutor).substitute(parameter);
if (type == null) {
types.clear();
break;
}
types.add(type.getCanonicalText());
}
if (!types.isEmpty()) {
newExpression.append("<").append(StringUtil.join(types, ", ")).append(">");
}
}
newExpression.append('(');
newExpression.append(getMergedArgs(descriptor, oldMethodParameters, args));
newExpression.append(')');
return JavaCodeStyleManager.getInstance(callExpression.getProject())
PsiNewExpression newClassExpression = (PsiNewExpression)JavaCodeStyleManager.getInstance(callExpression.getProject())
.shortenClassReferences(facade.getElementFactory().createExpressionFromText(newExpression.toString(), expr));
if (PsiDiamondTypeUtil.canChangeContextForDiamond(newClassExpression, newClassExpression.getType())) {
PsiDiamondTypeUtil.replaceExplicitWithDiamond(newClassExpression.getClassOrAnonymousClassReference().getParameterList());
}
return newClassExpression;
}
return null;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -137,8 +137,8 @@ class ParameterObjectBuilder {
out.append(CodeStyleSettingsManager.getSettings(myProject).GENERATE_FINAL_PARAMETERS ? " final " : "");
final String parameterName = parameter.getName();
final PsiType type = field.getType();
final PsiType fieldType = parameter.isVarArgs() && type instanceof PsiArrayType ?
PsiEllipsisType.createEllipsis(((PsiArrayType)type).getComponentType(), PsiAnnotation.EMPTY_ARRAY) : type;
final PsiType fieldType = parameter.isVarArgs() && type instanceof PsiArrayType ?
new PsiEllipsisType(((PsiArrayType)type).getComponentType()) : type;
out.append(' ' + fieldType.getCanonicalText() + ' ' + parameterName);
if (iterator.hasNext()) {
out.append(", ");
@@ -385,7 +385,7 @@ public class RefactoringUtil {
public static PsiType getTypeByExpressionWithExpectedType(PsiExpression expr) {
PsiElementFactory factory = JavaPsiFacade.getInstance(expr.getProject()).getElementFactory();
PsiType type = getTypeByExpression(expr, factory);
final boolean isFunctionalType = type instanceof PsiLambdaExpressionType || type instanceof PsiMethodReferenceType || type instanceof PsiLambdaParameterType;
final boolean isFunctionalType = LambdaUtil.notInferredType(type);
final boolean isDenotable = PsiTypesUtil.isDenotableType(expr.getType());
if (type != null && !isFunctionalType && isDenotable) {
return type;
@@ -404,9 +404,7 @@ public class RefactoringUtil {
public static PsiType getTypeByExpression(PsiExpression expr) {
PsiElementFactory factory = JavaPsiFacade.getInstance(expr.getProject()).getElementFactory();
PsiType type = getTypeByExpression(expr, factory);
if (type instanceof PsiLambdaParameterType ||
type instanceof PsiLambdaExpressionType ||
type instanceof PsiMethodReferenceType) {
if (LambdaUtil.notInferredType(type)) {
type = factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, expr.getResolveScope());
}
return type;
@@ -59,8 +59,6 @@ public class JavaAllOverridingMethodsSearcher implements QueryExecutor<Pair<PsiM
for (String name : potentials.keySet()) {
ProgressManager.checkCanceled();
if (inheritor.findMethodsByName(name, true).length == 0) continue;
for (PsiMethod superMethod : potentials.get(name)) {
ProgressManager.checkCanceled();
if (superMethod.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) &&
@@ -16,10 +16,8 @@
package com.intellij.psi.impl.search;
import com.intellij.lang.spi.SPILanguage;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.QueryExecutorBase;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.GlobalSearchScope;
@@ -30,73 +28,46 @@ import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
public class SPIReferencesSearcher extends QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters> {
public SPIReferencesSearcher() {
super(true);
}
@Override
public void processQuery(@NotNull final ReferencesSearch.SearchParameters p, @NotNull final Processor<PsiReference> consumer) {
final SearchScope scope = ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
@Override
public SearchScope compute() {
return p.getEffectiveSearchScope();
}
});
if (!(scope instanceof GlobalSearchScope)) return;
final PsiElement element = p.getElementToSearch();
if (!element.isValid()) return;
final SearchScope scope = p.getEffectiveSearchScope();
if (!(scope instanceof GlobalSearchScope)) return;
if (element instanceof PsiClass) {
final PsiClass aClass = (PsiClass)element;
final String jvmClassName = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
@Override
public String compute() {
return ClassUtil.getJVMClassName(aClass);
}
});
final String jvmClassName = ClassUtil.getJVMClassName(aClass);
if (jvmClassName == null) return;
final PsiFile[] files = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile[]>() {
@Override
public PsiFile[] compute() {
return FilenameIndex.getFilesByName(aClass.getProject(), jvmClassName, (GlobalSearchScope)scope);
}
});
final PsiFile[] files = FilenameIndex.getFilesByName(aClass.getProject(), jvmClassName, (GlobalSearchScope)scope);
for (PsiFile file : files) {
if (file.getLanguage() == SPILanguage.INSTANCE) {
final PsiReference reference = file.getReference();
if (reference != null) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
consumer.process(reference);
}
});
consumer.process(reference);
}
}
}
} else if (element instanceof PsiPackage) {
}
else if (element instanceof PsiPackage) {
final String qualifiedName = ((PsiPackage)element).getQualifiedName();
final Project project = element.getProject();
final String[] filenames = ApplicationManager.getApplication().runReadAction(new Computable<String[]>() {
@Override
public String[] compute() {
return FilenameIndex.getAllFilenames(project);
}
});
final String[] filenames = FilenameIndex.getAllFilenames(project);
for (final String filename : filenames) {
if (filename.startsWith(qualifiedName + ".")) {
final PsiFile[] files = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile[]>() {
@Override
public PsiFile[] compute() {
return FilenameIndex.getFilesByName(project, filename, (GlobalSearchScope)scope);
}
});
final PsiFile[] files = FilenameIndex.getFilesByName(project, filename, (GlobalSearchScope)scope);
for (PsiFile file : files) {
if (file.getLanguage() == SPILanguage.INSTANCE) {
final PsiReference[] references = file.getReferences();
for (final PsiReference reference : references) {
if (reference.getCanonicalText().equals(qualifiedName)) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
consumer.process(reference);
}
});
consumer.process(reference);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -376,11 +376,14 @@ public class GenericsUtil {
LOG.assertTrue(toPut == null || toPut.isValid(), toPut);
substitutor = substitutor.put(typeParameter, toPut);
}
final PsiAnnotation[] applicableAnnotations = classType.getApplicableAnnotations();
if (substitutor == PsiSubstitutor.EMPTY && !toExtend && applicableAnnotations.length == 0 && !(aClass instanceof PsiTypeParameter)) return classType;
PsiAnnotation[] applicableAnnotations = classType.getApplicableAnnotations();
if (substitutor == PsiSubstitutor.EMPTY && !toExtend && applicableAnnotations.length == 0 && !(aClass instanceof PsiTypeParameter)) {
return classType;
}
PsiManager manager = aClass.getManager();
PsiType result = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory()
.createType(aClass, substitutor, PsiUtil.getLanguageLevel(aClass), applicableAnnotations);
.createType(aClass, substitutor, PsiUtil.getLanguageLevel(aClass))
.annotate(TypeAnnotationProvider.Static.create(applicableAnnotations));
if (toExtend) result = PsiWildcardType.createExtends(manager, result);
return result;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@ public interface JVMElementFactory {
*
* @param name the name of the class to create.
* @return the created class instance.
* @throws com.intellij.util.IncorrectOperationException
* @throws IncorrectOperationException
* if <code>name</code> is not a valid Java identifier.
*/
@NotNull
@@ -175,7 +175,7 @@ public interface JVMElementFactory {
*
* @param name the name of the annotation type to create.
* @return the created annotation type instance.
* @throws com.intellij.util.IncorrectOperationException if <code>name</code> is not a valid Java identifier.
* @throws IncorrectOperationException if <code>name</code> is not a valid Java identifier.
*/
@NotNull
PsiClass createAnnotationType(@NotNull @NonNls String name) throws IncorrectOperationException;
@@ -201,13 +201,20 @@ public interface JVMElementFactory {
@NotNull
PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor);
/*
additional languageLevel parameter to memorize language level for allowing/prohibiting boxing/unboxing
*/
/**
* Creates a class type for the specified class, using the specified substitutor
* to replace generic type parameters on the class.
*
* @param resolve the class for which the class type is created.
* @param substitutor the substitutor to use.
* @param languageLevel to memorize language level for allowing/prohibiting boxing/unboxing.
* @return the class type instance.
*/
@NotNull
PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor, @NotNull LanguageLevel languageLevel);
@NotNull
/** @deprecated use {@link PsiType#annotate(TypeAnnotationProvider)} (to be removed in IDEA 18) */
@SuppressWarnings("unused")
PsiClassType createType(@NotNull PsiClass resolve,
@NotNull PsiSubstitutor substitutor,
@NotNull LanguageLevel languageLevel,
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -26,24 +26,26 @@ import org.jetbrains.annotations.NotNull;
public class PsiArrayType extends PsiType.Stub {
private final PsiType myComponentType;
/**
* Creates an array type with the specified component type.
*
* @param componentType the type of the array component.
*/
public PsiArrayType(@NotNull PsiType componentType) {
this(componentType, PsiAnnotation.EMPTY_ARRAY);
this(componentType, TypeAnnotationProvider.EMPTY);
}
public PsiArrayType(@NotNull PsiType componentType, @NotNull PsiAnnotation[] annotations) {
super(annotations);
myComponentType = componentType;
}
public PsiArrayType(@NotNull PsiType componentType, @NotNull TypeAnnotationProvider annotations) {
super(annotations);
public PsiArrayType(@NotNull PsiType componentType, @NotNull TypeAnnotationProvider provider) {
super(provider);
myComponentType = componentType;
}
@NotNull
@Override
public PsiArrayType annotate(@NotNull TypeAnnotationProvider provider) {
return provider == getAnnotationProvider() ? this : new PsiArrayType(myComponentType, provider);
}
@NotNull
@Override
public String getPresentableText() {
@@ -117,13 +119,15 @@ public class PsiArrayType extends PsiType.Stub {
return myComponentType;
}
@Override
public boolean equals(Object obj) {
return obj instanceof PsiArrayType &&
(this instanceof PsiEllipsisType == obj instanceof PsiEllipsisType) &&
myComponentType.equals(((PsiArrayType)obj).getComponentType());
}
@Override
public int hashCode() {
return myComponentType.hashCode() * 3;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -48,7 +48,7 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
private PsiCapturedWildcardType(@NotNull PsiWildcardType existential,
@NotNull PsiElement context,
@Nullable PsiTypeParameter parameter) {
super(PsiAnnotation.EMPTY_ARRAY);
super(TypeAnnotationProvider.EMPTY);
myExistential = existential;
myContext = context;
myParameter = parameter;
@@ -208,4 +208,4 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
public PsiTypeParameter getTypeParameter() {
return myParameter;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,9 +30,6 @@ import org.jetbrains.annotations.Nullable;
* @author max
*/
public abstract class PsiClassType extends PsiType {
/**
* The empty array of PSI class types which can be reused to avoid unnecessary allocations.
*/
public static final PsiClassType[] EMPTY_ARRAY = new PsiClassType[0];
public static final ArrayFactory<PsiClassType> ARRAY_FACTORY = new ArrayFactory<PsiClassType>() {
@NotNull
@@ -53,11 +50,17 @@ public abstract class PsiClassType extends PsiType {
myLanguageLevel = languageLevel;
}
public PsiClassType(LanguageLevel languageLevel, @NotNull TypeAnnotationProvider annotations) {
super(annotations);
public PsiClassType(LanguageLevel languageLevel, @NotNull TypeAnnotationProvider provider) {
super(provider);
myLanguageLevel = languageLevel;
}
@NotNull
@Override
public PsiClassType annotate(@NotNull TypeAnnotationProvider provider) {
return (PsiClassType)super.annotate(provider);
}
/**
* Resolves the class reference and returns the resulting class.
*
@@ -221,7 +224,7 @@ public abstract class PsiClassType extends PsiType {
public abstract PsiClassType rawType();
/**
* Overrides {@link com.intellij.psi.PsiType#getResolveScope()} to narrow specify @NotNull.
* Overrides {@link PsiType#getResolveScope()} to narrow specify @NotNull.
*/
@Override
@NotNull
@@ -314,4 +317,4 @@ public abstract class PsiClassType extends PsiType {
@Override
public abstract String getCanonicalText(boolean annotated);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -26,8 +26,8 @@ import java.util.List;
public abstract class PsiDiamondType extends PsiType {
public static final RecursionGuard ourDiamondGuard = RecursionManager.createGuard("diamondInference");
public PsiDiamondType(PsiAnnotation[] annotations) {
super(annotations);
public PsiDiamondType() {
super(TypeAnnotationProvider.EMPTY);
}
public abstract DiamondInferenceResult resolveInferredTypes();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -39,7 +39,7 @@ public class PsiDisjunctionType extends PsiType.Stub {
private final CachedValue<PsiType> myLubCache;
public PsiDisjunctionType(@NotNull List<PsiType> types, @NotNull PsiManager psiManager) {
super(PsiAnnotation.EMPTY_ARRAY);
super(TypeAnnotationProvider.EMPTY);
myManager = psiManager;
myTypes = Collections.unmodifiableList(types);
@@ -168,4 +168,4 @@ public class PsiDisjunctionType extends PsiType.Stub {
return true;
}
}
}
@@ -178,12 +178,6 @@ public interface PsiElementFactory extends PsiJavaParserFacade, JVMElementFactor
@Override
@NotNull PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel languageLevel);
@Override
@NotNull PsiClassType createType(@NotNull PsiClass resolve,
@NotNull PsiSubstitutor substitutor,
@Nullable LanguageLevel languageLevel,
@NotNull PsiAnnotation[] annotations);
/**
* Creates a class type for the specified reference pointing to a class.
*
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -23,11 +23,6 @@ import org.jetbrains.annotations.NotNull;
* @author ven
*/
public class PsiEllipsisType extends PsiArrayType {
/**
* Creates an ellipsis type instance with the specified component type.
*
* @param componentType the type of the varargs array component.
*/
public PsiEllipsisType(@NotNull PsiType componentType) {
super(componentType);
}
@@ -35,11 +30,19 @@ public class PsiEllipsisType extends PsiArrayType {
public PsiEllipsisType(@NotNull PsiType componentType, @NotNull PsiAnnotation[] annotations) {
super(componentType, annotations);
}
public PsiEllipsisType(@NotNull PsiType componentType, @NotNull TypeAnnotationProvider annotations) {
super(componentType, annotations);
public PsiEllipsisType(@NotNull PsiType componentType, @NotNull TypeAnnotationProvider provider) {
super(componentType, provider);
}
@NotNull
@Override
public PsiEllipsisType annotate(@NotNull TypeAnnotationProvider provider) {
return provider == getAnnotationProvider() ? this : new PsiEllipsisType(getComponentType(), provider);
}
/** @deprecated use {@link #annotate(TypeAnnotationProvider)} (to be removed in IDEA 18) */
@SuppressWarnings("unused")
public static PsiType createEllipsis(@NotNull PsiType componentType, @NotNull PsiAnnotation[] annotations) {
return new PsiEllipsisType(componentType, annotations);
}
@@ -82,7 +85,8 @@ public class PsiEllipsisType extends PsiArrayType {
return visitor.visitEllipsisType(this);
}
@Override
public int hashCode() {
return super.hashCode() * 5;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -35,7 +35,7 @@ public class PsiIntersectionType extends PsiType.Stub {
private final PsiType[] myConjuncts;
private PsiIntersectionType(@NotNull PsiType[] conjuncts) {
super(PsiAnnotation.EMPTY_ARRAY);
super(TypeAnnotationProvider.EMPTY);
myConjuncts = conjuncts;
}
@@ -176,6 +176,7 @@ public class PsiIntersectionType extends PsiType.Stub {
return myConjuncts[0];
}
@Override
public boolean equals(final Object obj) {
if (this == obj) return true;
if (!(obj instanceof PsiIntersectionType)) return false;
@@ -190,6 +191,7 @@ public class PsiIntersectionType extends PsiType.Stub {
return true;
}
@Override
public int hashCode() {
return myConjuncts[0].hashCode();
}
@@ -221,4 +223,4 @@ public class PsiIntersectionType extends PsiType.Stub {
}
return null;
}
}
}
@@ -235,11 +235,14 @@ public interface PsiJavaParserFacade {
/**
* Creates a Java type from the specified text.
*
* @param text the text of the type to create (a primitive type keyword).
* @param annotations array (possible empty) of annotations to annotate the created type.
* @param text the text of the type to create (a primitive type keyword).
* @return the created type instance.
* @throws IncorrectOperationException if some of the parameters are not valid.
*/
@NotNull
PsiType createPrimitiveTypeFromText(@NotNull String text) throws IncorrectOperationException;
/** @deprecated use {@link PsiType#annotate(TypeAnnotationProvider)} (to be removed in IDEA 18) */
@SuppressWarnings("unused")
PsiType createPrimitiveType(@NotNull String text, @NotNull PsiAnnotation[] annotations) throws IncorrectOperationException;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -26,7 +26,7 @@ public class PsiLambdaExpressionType extends PsiType {
private final PsiLambdaExpression myExpression;
public PsiLambdaExpressionType(PsiLambdaExpression expression) {
super(PsiAnnotation.EMPTY_ARRAY);
super(TypeAnnotationProvider.EMPTY);
myExpression = expression;
}
@@ -77,4 +77,4 @@ public class PsiLambdaExpressionType extends PsiType {
public PsiLambdaExpression getExpression() {
return myExpression;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -26,7 +26,7 @@ public class PsiLambdaParameterType extends PsiType {
private final PsiParameter myParameter;
public PsiLambdaParameterType(PsiParameter parameter) {
super(PsiAnnotation.EMPTY_ARRAY);
super(TypeAnnotationProvider.EMPTY);
myParameter = parameter;
}
@@ -77,4 +77,4 @@ public class PsiLambdaParameterType extends PsiType {
public PsiParameter getParameter() {
return myParameter;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -19,7 +19,6 @@ import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -36,23 +35,30 @@ public class PsiPrimitiveType extends PsiType.Stub {
private final String myName;
PsiPrimitiveType(@NonNls @NotNull String name, @NonNls String boxedName) {
this(name, PsiAnnotation.EMPTY_ARRAY);
PsiPrimitiveType(@NotNull String name, String boxedName) {
this(name, TypeAnnotationProvider.EMPTY);
if (boxedName != null) {
ourQNameToUnboxed.put(boxedName, this);
ourUnboxedToQName.put(this, boxedName);
}
}
public PsiPrimitiveType(@NonNls @NotNull String name, @NotNull PsiAnnotation[] annotations) {
public PsiPrimitiveType(@NotNull String name, @NotNull PsiAnnotation[] annotations) {
super(annotations);
myName = name;
}
public PsiPrimitiveType(@NonNls @NotNull String name, @NotNull TypeAnnotationProvider annotations) {
super(annotations);
public PsiPrimitiveType(@NotNull String name, @NotNull TypeAnnotationProvider provider) {
super(provider);
myName = name;
}
@NotNull
@Override
public PsiPrimitiveType annotate(@NotNull TypeAnnotationProvider provider) {
return provider == getAnnotationProvider() ? this : new PsiPrimitiveType(myName, provider);
}
@NotNull
@Override
public String getPresentableText() {
@@ -119,19 +125,18 @@ public class PsiPrimitiveType extends PsiType.Stub {
@Nullable
public static PsiPrimitiveType getUnboxedType(PsiType type) {
if (!(type instanceof PsiClassType)) return null;
assert type.isValid() : type;
LanguageLevel languageLevel = ((PsiClassType)type).getLanguageLevel();
if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_5)) return null;
assert type.isValid() : type;
PsiClass psiClass = ((PsiClassType)type).resolve();
if (psiClass == null) return null;
PsiPrimitiveType unboxed = ourQNameToUnboxed.get(psiClass.getQualifiedName());
PsiAnnotation[] annotations = type.getAnnotations();
if (unboxed != null && annotations.length > 0) {
unboxed = new PsiPrimitiveType(unboxed.myName, annotations);
}
return unboxed;
if (unboxed == null) return null;
return unboxed.annotate(type.getAnnotationProvider());
}
public String getBoxedTypeName() {
@@ -146,31 +151,30 @@ public class PsiPrimitiveType extends PsiType.Stub {
* it was not possible to resolve the reference to the class.
*/
@Nullable
public PsiClassType getBoxedType(PsiElement context) {
public PsiClassType getBoxedType(@NotNull PsiElement context) {
PsiFile file = context.getContainingFile();
LanguageLevel languageLevel = PsiUtil.getLanguageLevel(file);
if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_5)) return null;
String boxedQName = getBoxedTypeName();
//[ven]previous call returns null for NULL, VOID
if (boxedQName == null) return null;
JavaPsiFacade facade = JavaPsiFacade.getInstance(file.getProject());
PsiClass aClass = facade.findClass(boxedQName, file.getResolveScope());
if (aClass == null) return null;
PsiElementFactory factory = facade.getElementFactory();
return factory.createType(aClass, PsiSubstitutor.EMPTY, languageLevel, getAnnotations());
return factory.createType(aClass, PsiSubstitutor.EMPTY, languageLevel).annotate(getAnnotationProvider());
}
@Nullable
public PsiClassType getBoxedType(final PsiManager manager, final GlobalSearchScope resolveScope) {
final String boxedQName = getBoxedTypeName();
//[ven]previous call returns null for NULL, VOID
public PsiClassType getBoxedType(@NotNull PsiManager manager, @NotNull GlobalSearchScope resolveScope) {
String boxedQName = getBoxedTypeName();
if (boxedQName == null) return null;
final PsiClass aClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(boxedQName, resolveScope);
PsiClass aClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(boxedQName, resolveScope);
if (aClass == null) return null;
return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createType(aClass);
}
@@ -187,4 +191,4 @@ public class PsiPrimitiveType extends PsiType.Stub {
public boolean equals(Object obj) {
return obj instanceof PsiPrimitiveType && myName.equals(((PsiPrimitiveType)obj).myName);
}
}
}
@@ -56,13 +56,7 @@ public abstract class PsiType implements PsiAnnotationOwner {
* Constructs a PsiType with given annotations
*/
protected PsiType(@NotNull final PsiAnnotation[] annotations) {
this(annotations.length == 0 ? TypeAnnotationProvider.EMPTY : new TypeAnnotationProvider() {
@NotNull
@Override
public PsiAnnotation[] getAnnotations() {
return annotations;
}
});
this(TypeAnnotationProvider.Static.create(annotations));
}
/**
@@ -72,6 +66,11 @@ public abstract class PsiType implements PsiAnnotationOwner {
myAnnotationProvider = annotations;
}
@NotNull
public PsiType annotate(@NotNull TypeAnnotationProvider provider) {
throw new UnsupportedOperationException("Not implemented for " + getClass());
}
/**
* Creates array type with this type as a component.
*/
@@ -80,10 +79,8 @@ public abstract class PsiType implements PsiAnnotationOwner {
return new PsiArrayType(this);
}
/**
* Creates array type with this type as a component.
*/
@NotNull
/** @deprecated use {@link #annotate(TypeAnnotationProvider)} (to be removed in IDEA 18) */
@SuppressWarnings("unused")
public PsiArrayType createArrayType(@NotNull PsiAnnotation... annotations) {
return new PsiArrayType(this, annotations);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -31,7 +31,7 @@ public class PsiWildcardType extends PsiType.Stub {
public static final String EXTENDS_PREFIX = "? extends ";
public static final String SUPER_PREFIX = "? super ";
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.PsiWildcardType");
private static final Logger LOG = Logger.getInstance(PsiWildcardType.class);
private static final Key<PsiWildcardType> UNBOUNDED_WILDCARD = new Key<PsiWildcardType>("UNBOUNDED_WILDCARD");
private final PsiManager myManager;
@@ -39,14 +39,14 @@ public class PsiWildcardType extends PsiType.Stub {
private final PsiType myBound;
private PsiWildcardType(@NotNull PsiManager manager, boolean isExtending, @Nullable PsiType bound) {
super(PsiAnnotation.EMPTY_ARRAY);
super(TypeAnnotationProvider.EMPTY);
myManager = manager;
myIsExtending = isExtending;
myBound = bound;
}
private PsiWildcardType(@NotNull PsiWildcardType type, @NotNull TypeAnnotationProvider annotations) {
super(annotations);
private PsiWildcardType(@NotNull PsiWildcardType type, @NotNull TypeAnnotationProvider provider) {
super(provider);
myManager = type.myManager;
myIsExtending = type.myIsExtending;
myBound = type.myBound;
@@ -75,20 +75,16 @@ public class PsiWildcardType extends PsiType.Stub {
return new PsiWildcardType(manager, false, bound);
}
@NotNull
/** @deprecated use {@link #annotate(TypeAnnotationProvider)} (to be removed in IDEA 18) */
@SuppressWarnings("unused")
public PsiWildcardType annotate(@NotNull final PsiAnnotation[] annotations) {
return annotations.length == 0 ? this : new PsiWildcardType(this, new TypeAnnotationProvider() {
@NotNull
@Override
public PsiAnnotation[] getAnnotations() {
return annotations;
}
});
return annotations.length == 0 ? this : new PsiWildcardType(this, TypeAnnotationProvider.Static.create(annotations));
}
@NotNull
public PsiWildcardType annotate(@NotNull final TypeAnnotationProvider annotations) {
return new PsiWildcardType(this, annotations);
@Override
public PsiWildcardType annotate(@NotNull TypeAnnotationProvider provider) {
return provider == getAnnotationProvider() ? this : new PsiWildcardType(this, provider);
}
@NotNull
@@ -261,4 +257,4 @@ public class PsiWildcardType extends PsiType.Stub {
public PsiType getSuperBound() {
return myBound == null || myIsExtending ? NULL : myBound;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -36,4 +36,24 @@ public interface TypeAnnotationProvider {
@NotNull
PsiAnnotation[] getAnnotations();
}
class Static implements TypeAnnotationProvider {
private final PsiAnnotation[] myAnnotations;
private Static(PsiAnnotation[] annotations) {
myAnnotations = annotations;
}
@NotNull
@Override
public PsiAnnotation[] getAnnotations() {
return myAnnotations;
}
@NotNull
public static TypeAnnotationProvider create(@NotNull PsiAnnotation[] annotations) {
return annotations.length == 0 ? EMPTY : new Static(annotations);
}
}
}
@@ -142,8 +142,9 @@ public abstract class PsiAugmentProvider {
}
private static void forEach(Project project, Processor<PsiAugmentProvider> processor) {
boolean dumb = DumbService.isDumb(project);
for (PsiAugmentProvider provider : Extensions.getExtensions(EP_NAME)) {
if (!DumbService.isDumb(project) || DumbService.isDumbAware(provider)) {
if (!dumb || DumbService.isDumbAware(provider)) {
try {
boolean goOn = processor.process(provider);
if (!goOn) break;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -25,7 +25,7 @@ public class Bottom extends PsiType {
public static final Bottom BOTTOM = new Bottom();
private Bottom() {
super(PsiAnnotation.EMPTY_ARRAY);
super(TypeAnnotationProvider.EMPTY);
}
@NotNull
@@ -56,12 +56,9 @@ public class Bottom extends PsiType {
return text.equals("_");
}
@Override
public boolean equals(Object o) {
if (o instanceof Bottom) {
return true;
}
return false;
return o instanceof Bottom;
}
@Override
@@ -84,4 +81,4 @@ public class Bottom extends PsiType {
public GlobalSearchScope getResolveScope() {
return null;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -47,13 +47,12 @@ import java.util.*;
* @since Jul 30, 2010
*/
public class PsiDiamondTypeImpl extends PsiDiamondType {
private static final Logger LOG = Logger.getInstance("#" + PsiDiamondTypeImpl.class.getName());
private static final Logger LOG = Logger.getInstance(PsiDiamondTypeImpl.class);
private final PsiManager myManager;
private final PsiTypeElement myTypeElement;
public PsiDiamondTypeImpl(PsiManager manager, PsiTypeElement psiTypeElement) {
super(PsiAnnotation.EMPTY_ARRAY);
myManager = manager;
myTypeElement = psiTypeElement;
}
@@ -134,9 +133,9 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
final DiamondInferenceResult inferenceResult = resolveInferredTypesNoCheck(newExpression, context);
if (anonymousClass != null && PsiUtil.isLanguageLevel9OrHigher(newExpression)) {
final InferredAnonymTypeVisitor anonymTypeVisitor = new InferredAnonymTypeVisitor(context);
final InferredAnonymousTypeVisitor anonymousTypeVisitor = new InferredAnonymousTypeVisitor(context);
for (PsiType type : inferenceResult.getInferredTypes()) {
final Boolean accepted = type.accept(anonymTypeVisitor);
final Boolean accepted = type.accept(anonymousTypeVisitor);
if (accepted != null && !accepted.booleanValue()) {
return PsiDiamondTypeImpl.DiamondInferenceResult.ANONYMOUS_INNER_RESULT;
}
@@ -150,17 +149,16 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
final PsiSubstitutor inferredSubstitutor = ourDiamondGuard.doPreventingRecursion(context, false, new Computable<PsiSubstitutor>() {
@Override
public PsiSubstitutor compute() {
final JavaResolveResult staticFactoryCandidateInfo = context == newExpression ?
CachedValuesManager.getCachedValue(newExpression,
new CachedValueProvider<JavaResolveResult>() {
@Nullable
@Override
public Result<JavaResolveResult> compute() {
return new Result<JavaResolveResult>(getStaticFactoryCandidateInfo(newExpression, newExpression),
PsiModificationTracker.MODIFICATION_COUNT);
}
})
: getStaticFactoryCandidateInfo(newExpression, context);
final JavaResolveResult staticFactoryCandidateInfo =
context == newExpression
? CachedValuesManager.getCachedValue(newExpression, new CachedValueProvider<JavaResolveResult>() {
@Nullable
@Override
public Result<JavaResolveResult> compute() {
return new Result<JavaResolveResult>(getStaticFactoryCandidateInfo(newExpression, newExpression), PsiModificationTracker.MODIFICATION_COUNT);
}
})
: getStaticFactoryCandidateInfo(newExpression, context);
staticFactoryRef.set(staticFactoryCandidateInfo);
if (staticFactoryCandidateInfo != null) {
PsiSubstitutor substitutor = staticFactoryCandidateInfo.getSubstitutor();
@@ -515,10 +513,10 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
* The term "subexpression" includes type arguments of parameterized types (4.5), bounds of wildcards (4.5.1), and element types of array types (10.1).
* It excludes bounds of type variables.
*/
private static class InferredAnonymTypeVisitor extends PsiTypeVisitor<Boolean> {
private static class InferredAnonymousTypeVisitor extends PsiTypeVisitor<Boolean> {
private final PsiElement myExpression;
public InferredAnonymTypeVisitor(PsiElement expression) {
public InferredAnonymousTypeVisitor(PsiElement expression) {
myExpression = expression;
}
@@ -564,4 +562,4 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
return true;
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -22,7 +22,7 @@ import org.jetbrains.annotations.NotNull;
*/
public abstract class PsiTypeVariable extends PsiType {
protected PsiTypeVariable() {
super(PsiAnnotation.EMPTY_ARRAY);
super(TypeAnnotationProvider.EMPTY);
}
public abstract int getIndex();
@@ -37,4 +37,4 @@ public abstract class PsiTypeVariable extends PsiType {
return visitor.visitType(this);
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -383,13 +383,18 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade {
}
@NotNull
@Override
public PsiType createPrimitiveType(@NotNull final String text, @NotNull final PsiAnnotation[] annotations) throws IncorrectOperationException {
final PsiPrimitiveType primitiveType = getPrimitiveType(text);
public PsiType createPrimitiveTypeFromText(@NotNull String text) throws IncorrectOperationException {
PsiPrimitiveType primitiveType = getPrimitiveType(text);
if (primitiveType == null) {
throw new IncorrectOperationException("Incorrect primitive type '" + text + "'");
}
return annotations.length == 0 ? primitiveType : new PsiPrimitiveType(text, annotations);
return primitiveType;
}
@NotNull
@Override
public PsiType createPrimitiveType(@NotNull String text, @NotNull PsiAnnotation[] annotations) throws IncorrectOperationException {
return createPrimitiveTypeFromText(text).annotate(TypeAnnotationProvider.Static.create(annotations));
}
public static PsiPrimitiveType getPrimitiveType(final String text) {
@@ -42,7 +42,7 @@ class TypeCorrector extends PsiTypeMapper {
@Override
public PsiType visitType(PsiType type) {
if (type instanceof PsiLambdaParameterType || type instanceof PsiLambdaExpressionType || type instanceof PsiMethodReferenceType) {
if (LambdaUtil.notInferredType(type)) {
return type;
}
return super.visitType(type);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,8 +42,8 @@ public class PsiClassReferenceType extends PsiClassType.Stub {
myReference = reference;
}
public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel level, @NotNull TypeAnnotationProvider annotations) {
super(level, annotations);
public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel level, @NotNull TypeAnnotationProvider provider) {
super(level, provider);
myReference = reference;
}
@@ -58,6 +58,12 @@ public class PsiClassReferenceType extends PsiClassType.Stub {
return result == null ? PsiAnnotation.EMPTY_ARRAY : result.toArray(new PsiAnnotation[result.size()]);
}
@NotNull
@Override
public PsiClassReferenceType annotate(@NotNull TypeAnnotationProvider provider) {
return provider == getAnnotationProvider() ? this : new PsiClassReferenceType(myReference, myLanguageLevel, provider);
}
@Override
public boolean isValid() {
return myReference.isValid();
@@ -222,4 +228,4 @@ public class PsiClassReferenceType extends PsiClassType.Stub {
public PsiJavaCodeReferenceElement getReference() {
return myReference;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -79,11 +79,11 @@ public class PsiImmediateClassType extends PsiClassType.Stub {
};
public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor) {
this(aClass, substitutor, null, PsiAnnotation.EMPTY_ARRAY);
this(aClass, substitutor, null, TypeAnnotationProvider.EMPTY);
}
public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel level) {
this(aClass, substitutor, level, PsiAnnotation.EMPTY_ARRAY);
this(aClass, substitutor, level, TypeAnnotationProvider.EMPTY);
}
public PsiImmediateClassType(@NotNull PsiClass aClass,
@@ -96,17 +96,24 @@ public class PsiImmediateClassType extends PsiClassType.Stub {
mySubstitutor = substitutor;
assert substitutor.isValid();
}
public PsiImmediateClassType(@NotNull PsiClass aClass,
@NotNull PsiSubstitutor substitutor,
@Nullable LanguageLevel level,
@NotNull TypeAnnotationProvider annotations) {
super(level, annotations);
@NotNull TypeAnnotationProvider provider) {
super(level, provider);
myClass = aClass;
myManager = aClass.getManager();
mySubstitutor = substitutor;
assert substitutor.isValid();
}
@NotNull
@Override
public PsiImmediateClassType annotate(@NotNull TypeAnnotationProvider provider) {
return provider == getAnnotationProvider() ? this : new PsiImmediateClassType(myClass, mySubstitutor, myLanguageLevel, provider);
}
@Override
public PsiClass resolve() {
return myClass;
@@ -116,6 +123,7 @@ public class PsiImmediateClassType extends PsiClassType.Stub {
public String getClassName() {
return myClass.getName();
}
@Override
@NotNull
public PsiType[] getParameters() {
@@ -127,12 +135,10 @@ public class PsiImmediateClassType extends PsiClassType.Stub {
List<PsiType> lst = new ArrayList<PsiType>();
for (PsiTypeParameter parameter : parameters) {
PsiType substituted = mySubstitutor.substitute(parameter);
if (substituted != null) {
lst.add(substituted);
}
else {
if (substituted == null) {
return PsiType.EMPTY_ARRAY;
}
lst.add(substituted);
}
return lst.toArray(createArray(lst.size()));
}
@@ -313,4 +319,4 @@ public class PsiImmediateClassType extends PsiClassType.Stub {
public PsiClassType setLanguageLevel(@NotNull LanguageLevel level) {
return level.equals(myLanguageLevel) ? this : new PsiImmediateClassType(myClass, mySubstitutor, level, getAnnotationProvider());
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -48,7 +48,7 @@ public class JavaSharedImplUtil {
List<PsiAnnotation[]> allAnnotations = collectAnnotations(anchor, stopAt);
if (allAnnotations == null) return null;
for (PsiAnnotation[] annotations : allAnnotations) {
type = type.createArrayType(annotations);
type = type.createArrayType().annotate(TypeAnnotationProvider.Static.create(annotations));
}
return type;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -73,20 +73,22 @@ public class PsiNewExpressionImpl extends ExpressionPsiElement implements PsiNew
else if (ElementType.PRIMITIVE_TYPE_BIT_SET.contains(elementType)) {
assert type == null : this;
PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
type = factory.createPrimitiveType(child.getText(), ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true));
PsiAnnotation[] copy = ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true);
type = factory.createPrimitiveTypeFromText(child.getText()).annotate(TypeAnnotationProvider.Static.create(copy));
if (stop) return type;
}
else if (elementType == JavaTokenType.LBRACKET) {
assert type != null : this;
type = type.createArrayType(ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true));
PsiAnnotation[] copy = ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true);
type = type.createArrayType().annotate(TypeAnnotationProvider.Static.create(copy));
if (stop) return type;
}
else if (elementType == JavaElementType.ANONYMOUS_CLASS) {
PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
PsiClass aClass = (PsiClass)child.getPsi();
PsiSubstitutor substitutor = aClass instanceof PsiTypeParameter ? PsiSubstitutor.EMPTY : factory.createRawSubstitutor(aClass);
type = factory.createType(aClass, substitutor, PsiUtil.getLanguageLevel(aClass),
ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true));
PsiAnnotation[] copy = ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true);
type = factory.createType(aClass, substitutor, PsiUtil.getLanguageLevel(aClass)).annotate(TypeAnnotationProvider.Static.create(copy));
if (stop) return type;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -50,10 +50,10 @@ public class CanonicalTypes {
}
private abstract static class AnnotatedType extends Type {
protected final PsiAnnotation[] myAnnotations;
protected final TypeAnnotationProvider myProvider;
protected AnnotatedType(@NotNull PsiAnnotation[] annotations) {
myAnnotations = annotations;
public AnnotatedType(@NotNull TypeAnnotationProvider provider) {
myProvider = TypeAnnotationProvider.Static.create(provider.getAnnotations());
}
}
@@ -61,14 +61,14 @@ public class CanonicalTypes {
private final PsiPrimitiveType myType;
private Primitive(@NotNull PsiPrimitiveType type) {
super(type.getAnnotations());
super(type.getAnnotationProvider());
myType = type;
}
@NotNull
@Override
public PsiType getType(PsiElement context, PsiManager manager) {
return myAnnotations.length == 0 ? myType : new PsiPrimitiveType(myType.getCanonicalText(false), myAnnotations);
return myType.annotate(myProvider);
}
@Override
@@ -81,14 +81,14 @@ public class CanonicalTypes {
protected final Type myComponentType;
private Array(@NotNull PsiType original, @NotNull Type componentType) {
super(original.getAnnotations());
super(original.getAnnotationProvider());
myComponentType = componentType;
}
@NotNull
@Override
public PsiType getType(PsiElement context, PsiManager manager) throws IncorrectOperationException {
return myComponentType.getType(context, manager).createArrayType(myAnnotations);
return myComponentType.getType(context, manager).createArrayType().annotate(myProvider);
}
@Override
@@ -115,7 +115,7 @@ public class CanonicalTypes {
@NotNull
@Override
public PsiType getType(PsiElement context, PsiManager manager) throws IncorrectOperationException {
return new PsiEllipsisType(myComponentType.getType(context, manager), myAnnotations);
return new PsiEllipsisType(myComponentType.getType(context, manager)).annotate(myProvider);
}
@Override
@@ -129,7 +129,7 @@ public class CanonicalTypes {
private final Type myBound;
private WildcardType(@NotNull PsiType original, boolean isExtending, @Nullable Type bound) {
super(original.getAnnotations());
super(original.getAnnotationProvider());
myIsExtending = isExtending;
myBound = bound;
}
@@ -147,7 +147,7 @@ public class CanonicalTypes {
else {
type = PsiWildcardType.createSuper(manager, myBound.getType(context, manager));
}
return type.annotate(myAnnotations);
return type.annotate(myProvider);
}
@Override
@@ -205,7 +205,7 @@ public class CanonicalTypes {
private final Map<String, Type> mySubstitutor;
private ClassType(@NotNull PsiType original, @NotNull String classQName, @NotNull Map<String, Type> substitutor) {
super(original.getAnnotations());
super(original.getAnnotationProvider());
myPresentableText = original.getPresentableText();
myClassQName = classQName;
mySubstitutor = substitutor;
@@ -227,7 +227,7 @@ public class CanonicalTypes {
Type substitute = mySubstitutor.get(typeParameter.getName());
substitutionMap.put(typeParameter, substitute != null ? substitute.getType(context, manager) : null);
}
return factory.createType(aClass, factory.createSubstitutor(substitutionMap), null, myAnnotations);
return factory.createType(aClass, factory.createSubstitutor(substitutionMap), null).annotate(myProvider);
}
@Override
@@ -326,7 +326,7 @@ public class CanonicalTypes {
PsiType substitute = substitutor.substitute(typeParameter);
substitutionMap.put(typeParameter.getName(), substitute != null ? substitute.accept(this) : null);
}
String qualifiedName = ObjectUtils.notNull(aClass.getQualifiedName(), aClass.getName());
String qualifiedName = ObjectUtils.notNull(aClass.getQualifiedName(), ObjectUtils.assertNotNull(aClass.getName()));
return new ClassType(type, qualifiedName, substitutionMap);
}
}
@@ -358,4 +358,4 @@ public class CanonicalTypes {
public static Type createTypeWrapper(@NotNull PsiType type) {
return type.accept(Creator.INSTANCE);
}
}
}
@@ -0,0 +1,8 @@
// "Create local variable 'a'" "true"
class C {
void foo() {
(s) -> {
Object a = s;
};
}
}
@@ -0,0 +1,8 @@
// "Create local variable 'a'" "true"
class C {
void foo() {
(s) -> {
<caret>a = s;
};
}
}
@@ -0,0 +1,13 @@
// "Replace method call on lambda with lambda body" "false"
import java.util.function.Supplier;
class Test {
{
System.out.println(((Supplier<String>)() -> {
switch () {
default:
return "";
}
}).g<caret>et());
}
}
@@ -0,0 +1,8 @@
class Test {
{
int i = 0;
double[] doubles = null;
<selection>double progressResult = doubles[0] / i;</selection>
}
}
@@ -0,0 +1,12 @@
class Test {
{
int i = 0;
double[] doubles = null;
newMethod(doubles[0] / i);
}
private void newMethod(double v) {
double progressResult = v;
}
}
@@ -0,0 +1,13 @@
import java.util.List;
public class Param<T> {
private final List<T> y;
public Param(List<T> y) {
this.y = y;
}
public List<T> getY() {
return y;
}
}
@@ -0,0 +1,11 @@
import java.util.List;
public class Test {
public static <T> String foo(Param<T> param) {
return null;
}
void bar(List<Integer> list) {
System.out.println(foo(new Param<>(list)));
}
}
@@ -0,0 +1,12 @@
import java.util.Collection;
import java.util.List;
public class Test {
public static <T> String foo(List<T> y) {
return null;
}
void bar(List<Integer> list) {
System.out.println(foo(list));
}
}
@@ -500,6 +500,10 @@ public class ExtractMethodTest extends LightCodeInsightTestCase {
doTest();
}
public void testArrayAccessWithTopExpression() throws Exception {
doTest();
}
public void testArrayAccessWithDuplicates() throws Exception {
doDuplicatesTest();
}
@@ -22,7 +22,9 @@ package com.intellij.refactoring;
import com.intellij.JavaTestUtil;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.changeSignature.JavaMethodDescriptor;
@@ -132,6 +134,18 @@ public class IntroduceParameterObjectTest extends MultiFileTestCase{
doTest();
}
public void testTypeParametersWithSubstitution() throws Exception {
final LanguageLevelProjectExtension projectExtension = LanguageLevelProjectExtension.getInstance(getProject());
final LanguageLevel oldLevel = projectExtension.getLanguageLevel();
try {
projectExtension.setLanguageLevel(LanguageLevel.HIGHEST);
doTest();
}
finally {
projectExtension.setLanguageLevel(oldLevel);
}
}
public void testSameTypeAndVarargs() throws Exception {
doTest(false, false, method -> {
final PsiParameter[] parameters = method.getParameterList().getParameters();
@@ -1041,50 +1041,94 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
final PsiReferenceExpression mcallRef1 = mcall.getMethodExpression();
final PsiReferenceExpression mcallRef2 = mcall2.getMethodExpression();
final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(mcallRef1.getReferenceNameElement());
final PsiElement patternMethodName = mcallRef1.getReferenceNameElement();
final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(patternMethodName);
if (!myMatchingVisitor.matchText(mcallRef1.getReferenceNameElement(), mcallRef2.getReferenceNameElement()) && !isTypedVar) {
if (!isTypedVar && !myMatchingVisitor.matchText(patternMethodName, mcallRef2.getReferenceNameElement())) {
myMatchingVisitor.setResult(false);
return;
}
final PsiExpression qualifier = mcallRef1.getQualifierExpression();
final PsiExpression elementQualifier = mcallRef2.getQualifierExpression();
if (qualifier != null) {
final PsiExpression patternQualifier = mcallRef1.getQualifierExpression();
final PsiExpression matchedQualifier = mcallRef2.getQualifierExpression();
if (patternQualifier != null) {
if (elementQualifier != null) {
myMatchingVisitor.setResult(myMatchingVisitor.match(qualifier, elementQualifier));
if (matchedQualifier != null) {
myMatchingVisitor.setResult(myMatchingVisitor.match(patternQualifier, matchedQualifier));
if (!myMatchingVisitor.getResult()) return;
}
else {
final PsiMethod method = mcall2.resolveMethod();
if (method != null) {
if (qualifier instanceof PsiThisExpression) {
if (patternQualifier instanceof PsiThisExpression) {
myMatchingVisitor.setResult(!method.hasModifierProperty(PsiModifier.STATIC));
return;
}
}
final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(qualifier);
final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(patternQualifier);
matchImplicitQualifier(handler, method, myMatchingVisitor.getMatchContext());
if (!myMatchingVisitor.getResult()) {
return;
}
}
}
else if (elementQualifier != null) {
else if (matchedQualifier != null) {
myMatchingVisitor.setResult(false);
return;
}
myMatchingVisitor.setResult(myMatchingVisitor.matchSons(mcall.getArgumentList(), mcall2.getArgumentList()));
if (myMatchingVisitor.getResult()) {
myMatchingVisitor.setResult(matchTypeParameters(mcallRef1, mcallRef2));
}
if (myMatchingVisitor.getResult() && isTypedVar) {
boolean res = myMatchingVisitor.getResult();
res &= myMatchingVisitor.handleTypedElement(mcallRef1.getReferenceNameElement(), mcallRef2.getReferenceNameElement());
res &= myMatchingVisitor.handleTypedElement(patternMethodName, mcallRef2.getReferenceNameElement());
myMatchingVisitor.setResult(res);
}
}
private boolean matchTypeParameters(PsiJavaCodeReferenceElement mcallRef1, PsiJavaCodeReferenceElement mcallRef2) {
final PsiReferenceParameterList patternParameterList = mcallRef1.getParameterList();
if (patternParameterList == null) {
return true;
}
final PsiTypeElement[] patternTypeElements = patternParameterList.getTypeParameterElements();
if (patternTypeElements.length == 0) {
return true;
}
PsiReferenceParameterList matchedParameterList = mcallRef2.getParameterList();
if (matchedParameterList == null) {
return false;
}
if (matchedParameterList.getFirstChild() == null) { // check inferred type parameters
final JavaResolveResult resolveResult = mcallRef2.advancedResolve(false);
final PsiMethod targetMethod = (PsiMethod)resolveResult.getElement();
if (targetMethod == null) {
return false;
}
final PsiTypeParameterList typeParameterList = targetMethod.getTypeParameterList();
if (typeParameterList == null) {
return false;
}
final PsiTypeParameter[] typeParameters = typeParameterList.getTypeParameters();
final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
matchedParameterList = (PsiReferenceParameterList)matchedParameterList.copy();
for (final PsiTypeParameter typeParameter : typeParameters) {
final PsiType type = substitutor.substitute(typeParameter);
if (type == null) {
return false;
}
final PsiTypeElement matchedTypeElement = JavaPsiFacade.getElementFactory(mcallRef1.getProject()).createTypeElement(type);
matchedParameterList.add(matchedTypeElement);
}
}
final PsiTypeElement[] matchedTypeElements = matchedParameterList.getTypeParameterElements();
return myMatchingVisitor.matchSequentially(patternTypeElements, matchedTypeElements);
}
@Override
public void visitExpressionStatement(final PsiExpressionStatement expr) {
final PsiElement other = myMatchingVisitor.getElement();
@@ -412,6 +412,12 @@ public class GlobalInspectionContextBase extends UserDataHolderBase implements G
elements.add(manager.createSmartPsiElementPointer(element));
}
cleanupElements(project, runnable, elements);
}
public static void cleanupElements(@NotNull final Project project,
@Nullable final Runnable runnable,
final List<SmartPsiElementPointer<PsiElement>> elements) {
Runnable cleanupRunnable = new Runnable() {
@Override
public void run() {
@@ -441,7 +447,7 @@ public class GlobalInspectionContextBase extends UserDataHolderBase implements G
}
}
public void close(boolean noSuspisiousCodeFound) {
public void close(boolean noSuspisiousCodeFound) {
cleanup();
}
@@ -94,7 +94,7 @@ public class PluginManagerCore {
if (ourBuildNumber == null) {
ourBuildNumber = BUILD_NUMBER == null ? null : BuildNumber.fromString(BUILD_NUMBER);
if (ourBuildNumber == null) {
ourBuildNumber = BuildNumber.fromString("SNAPSHOT");
ourBuildNumber = BuildNumber.currentVersion();
}
}
return ourBuildNumber;
@@ -60,6 +60,7 @@ public class TransactionGuardImpl extends TransactionGuard {
public void finish() {
Queue<Transaction> queue = getQueue(prevTransaction);
queue.addAll(myCurrentTransaction.myQueue);
myCurrentTransaction.myQueue = queue;
if (!queue.isEmpty()) {
pollQueueLater();
}
@@ -72,14 +73,7 @@ public class TransactionGuardImpl extends TransactionGuard {
@NotNull
private Queue<Transaction> getQueue(@Nullable TransactionIdImpl transaction) {
if (transaction == null) {
return myQueue;
}
if (myCurrentTransaction != null && transaction.myStartCounter > myCurrentTransaction.myStartCounter) {
// transaction is finished already, it makes no sense to add to its queue
return myCurrentTransaction.myQueue;
}
return transaction.myQueue;
return transaction == null ? myQueue : transaction.myQueue;
}
private void pollQueueLater() {
@@ -304,7 +298,7 @@ public class TransactionGuardImpl extends TransactionGuard {
private static class TransactionIdImpl implements TransactionId {
private static final AtomicLong ourTransactionCounter = new AtomicLong();
final long myStartCounter = ourTransactionCounter.getAndIncrement();
final Queue<Transaction> myQueue = new LinkedBlockingQueue<Transaction>();
Queue<Transaction> myQueue = new LinkedBlockingQueue<Transaction>();
@Override
public String toString() {
@@ -52,13 +52,4 @@ public interface ChangeInfo {
String getNewName();
Language getLanguage();
/**
* For added parameters, return expression to be inserted as argument at the parameter position in callExpression.
* Based on parameter default value {@link ParameterInfo#getActualValue(PsiElement)}
*/
default PsiElement getActualValue(int i, PsiElement callExpression) {
final ParameterInfo[] parameters = getNewParameters();
return i < parameters.length ? parameters[i].getActualValue(callExpression) : null;
}
}
@@ -55,7 +55,7 @@ public interface ParameterInfo {
* Could be overridden to provide values which depend on the call site
*/
@Nullable
default PsiElement getActualValue(PsiElement callExpression) {
default PsiElement getActualValue(PsiElement callExpression, Object substitutor) {
return null;
}
@@ -211,7 +211,7 @@ public class FontOptions extends JPanel implements OptionsPanel{
Object source = event.getSource();
if (source instanceof FontComboBox) {
FontComboBox combo = (FontComboBox)source;
if (combo.isEnabled() && combo.getSelectedItem() != null) {
if (combo.isEnabled() && combo.isShowing() && combo.getSelectedItem() != null) {
syncFontFamilies();
}
}
@@ -186,7 +186,6 @@ public class CodeFoldingManagerImpl extends CodeFoldingManager implements Projec
Document document = editor.getDocument();
PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
if (file == null || !file.getViewProvider().isPhysical() || !file.isValid()) return;
PsiDocumentManager.getInstance(myProject).commitDocument(document);
Editor[] otherEditors = EditorFactory.getInstance().getEditors(document, myProject);
if (otherEditors.length == 0 && !editor.isDisposed()) {
@@ -80,9 +80,7 @@ class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState {
LOG.assertTrue(!editor.isDisposed());
clear();
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
documentManager.commitDocument(editor.getDocument());
PsiFile file = documentManager.getPsiFile(editor.getDocument());
PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument());
SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(myProject);
EditorFoldingInfo info = EditorFoldingInfo.get(editor);
@@ -59,7 +59,7 @@ public class CreateFileFromTemplateDialog extends DialogWrapper {
@Override
protected ValidationInfo doValidate() {
if (myInputValidator != null) {
final String text = myNameField.getText();
final String text = myNameField.getText().trim();
final boolean canClose = myInputValidator.canClose(text);
if (!canClose) {
String errorText = LangBundle.message("incorrect.name");
@@ -137,7 +137,6 @@ public class PsiAwareTextEditorProvider extends TextEditorProvider implements As
if (FileEditorStateLevel.FULL == level) {
// Folding
if (project != null && !project.isDisposed() && !editor.isDisposed() && project.isInitialized()) {
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
state.setFoldingState(CodeFoldingManager.getInstance(project).saveFoldingState(editor));
}
else {
@@ -154,7 +153,7 @@ public class PsiAwareTextEditorProvider extends TextEditorProvider implements As
// Folding
final CodeFoldingState foldState = state.getFoldingState();
if (project != null && foldState != null) {
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
LOG.assertTrue(PsiDocumentManager.getInstance(project).isCommitted(editor.getDocument()));
editor.getFoldingModel().runBatchFoldingOperation(
() -> CodeFoldingManager.getInstance(project).restoreFoldingState(editor, foldState)
);
@@ -64,13 +64,7 @@ public abstract class ParameterTableModelBase<P extends ParameterInfo, TableItem
}
public void setValueAtWithoutUpdate(Object aValue, int rowIndex, int columnIndex) {
super.setValueAt(aValue, rowIndex, columnIndex);
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
super.setValueAt(aValue, rowIndex, columnIndex);
fireTableCellUpdated(rowIndex, columnIndex); // to update signature
setValueAt(aValue, rowIndex, columnIndex, false);
}
protected static abstract class ColumnInfoBase<P extends ParameterInfo, TableItem extends ParameterTableModelItemBase<P>, Aspect>
@@ -100,10 +100,12 @@ public abstract class IntroduceParameterObjectDelegate<M extends PsiNamedElement
/**
* Call site should be updated according to the selected parameters, which correspond to the parameters to merge ({@link IntroduceParameterObjectClassDescriptor#getParamsToMerge()})
* E.g. for the call foo(a, b, c) and parameter class which corresponds to the first 2 parameters, actual value should represent foo(new P(a, b), c)
* @param substitutor should contain call substitutor before change signature replaced parameters
*/
public abstract PsiElement createNewParameterInitializerAtCallSite(PsiElement callExpression,
IntroduceParameterObjectClassDescriptor descriptor,
List<? extends ParameterInfo> oldMethodParameters);
List<? extends ParameterInfo> oldMethodParameters,
Object substitutor);
/**
* Pass new parameter infos to the change info constructor which corresponds to the language of this delegate
@@ -313,23 +313,18 @@ public class SafeDeleteProcessor extends BaseRefactoringProcessor {
@Override
public void run() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
myUsageView.close();
ArrayList<PsiElement> elements = new ArrayList<PsiElement>();
for (SmartPsiElementPointer pointer : myPointers) {
final PsiElement element = pointer.getElement();
if (element != null) {
elements.add(element);
}
}
if(!elements.isEmpty()) {
SafeDeleteHandler.invoke(myProject, PsiUtilCore.toPsiElementArray(elements), true);
}
}
});
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
myUsageView.close();
ArrayList<PsiElement> elements = new ArrayList<PsiElement>();
for (SmartPsiElementPointer pointer : myPointers) {
final PsiElement element = pointer.getElement();
if (element != null) {
elements.add(element);
}
}
if(!elements.isEmpty()) {
SafeDeleteHandler.invoke(myProject, PsiUtilCore.toPsiElementArray(elements), true);
}
}
}
@@ -17,6 +17,7 @@ package com.intellij.ui.components;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
@@ -177,8 +178,9 @@ public class JBScrollPane extends JScrollPane {
}
private static void updateInputMap(InputMap map, String prefix, String... actions) {
if (map != null) {
if (map != null && null != ApplicationManager.getApplication()) {
ActionManager manager = ActionManager.getInstance();
if (manager != null)
for (String action : actions) {
KeyboardShortcut shortcut = manager.getKeyboardShortcut(prefix + action);
if (shortcut != null) map.put(shortcut.getFirstKeyStroke(), action);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -787,7 +787,7 @@ public class IdeEventQueue extends EventQueue {
if (e instanceof WindowEvent) {
final WindowEvent we = (WindowEvent)e;
ApplicationActivationStateManager.get().updateState(we);
ApplicationActivationStateManager.updateState(we);
storeLastFocusedComponent(we);
}
@@ -4413,7 +4413,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
return;
}
if (getMouseEventArea(e) == EditorMouseEventArea.LINE_MARKERS_AREA) {
EditorMouseEventArea eventArea = getMouseEventArea(e);
if (eventArea == EditorMouseEventArea.LINE_MARKERS_AREA ||
eventArea == EditorMouseEventArea.FOLDING_OUTLINE_AREA && !isInsideGutterWhitespaceArea(e)) {
// The general idea is that we don't want to change caret position on gutter marker area click (e.g. on setting a breakpoint)
// but do want to allow bulk selection on gutter marker mouse drag. However, when a drag is performed, the first event is
// a 'mouse pressed' event, that's why we remember target line on 'mouse pressed' processing and use that information on
@@ -5857,7 +5859,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myExpectedCaretOffset = -1;
}
if (event.getArea() == EditorMouseEventArea.LINE_MARKERS_AREA) {
if (event.getArea() == EditorMouseEventArea.LINE_MARKERS_AREA ||
event.getArea() == EditorMouseEventArea.FOLDING_OUTLINE_AREA && !isInsideGutterWhitespaceArea(e)) {
myDragOnGutterSelectionStartLine = EditorUtil.yPositionToLogicalLine(EditorImpl.this, e);
}
@@ -216,4 +216,18 @@ class TransactionTest extends LightPlatformTestCase {
assert log == ['1', '2', '3', '4', '5']
}
public void "test don't add transaction to outdated queue"() {
TransactionGuard.submitTransaction testRootDisposable, {
log << '1'
guard.submitTransactionLater testRootDisposable, { log << '3' }
log << '2'
}
TransactionGuard.submitTransaction testRootDisposable, {
UIUtil.dispatchAllInvocationEvents()
assert log == ['1', '2']
}
UIUtil.dispatchAllInvocationEvents()
assert log == ['1', '2', '3']
}
}
@@ -23,6 +23,7 @@ import junit.framework.TestCase;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import static com.intellij.openapi.util.Conditions.not;
@@ -227,6 +228,20 @@ public class TreeTraverserTest extends TestCase {
assertEquals(Arrays.asList(1, 2), list);
}
public void testIteratorContractsSkipAndStop() {
final AtomicInteger count = new AtomicInteger(0);
JBIterator<Integer> it = new JBIterator<Integer>() {
@Override
protected Integer nextImpl() {
return count.get() < 0 ? stop() :
count.incrementAndGet() < 10 ? skip() :
(Integer)count.addAndGet(-count.get() - 1);
}
};
assertEquals(JBIterable.of(-1).toList(), JBIterable.once(it).toList());
}
// JBIterable ----------------------------------------------
public void testAppend() {
@@ -270,7 +270,9 @@ public class GeneralIdBasedToSMTRunnerEventsConvertor extends GeneralTestEventsP
String stackTrace = testFailedEvent.getStacktrace();
if (comparisonFailureActualText != null && comparisonFailureExpectedText != null) {
testProxy.setTestComparisonFailed(failureMessage, stackTrace,
comparisonFailureActualText, comparisonFailureExpectedText, testFailedEvent.getFilePath());
comparisonFailureActualText, comparisonFailureExpectedText,
testFailedEvent.getExpectedFilePath(),
testFailedEvent.getActualFilePath());
} else if (comparisonFailureActualText == null && comparisonFailureExpectedText == null) {
testProxy.setTestFailed(failureMessage, stackTrace, testFailedEvent.isTestError());
} else {
@@ -409,7 +409,7 @@ public class GeneralToSMTRunnerEventsConvertor extends GeneralTestEventsProcesso
if (comparisionFailureActualText != null && comparisionFailureExpectedText != null) {
testProxy.setTestComparisonFailed(localizedMessage, stackTrace,
comparisionFailureActualText, comparisionFailureExpectedText,
testFailedEvent.getFilePath(), testFailedEvent.getActualFilePath());
testFailedEvent.getExpectedFilePath(), testFailedEvent.getActualFilePath());
}
else if (comparisionFailureActualText == null && comparisionFailureExpectedText == null) {
testProxy.setTestFailed(localizedMessage, stackTrace, isTestError);
@@ -27,17 +27,20 @@ public class TestFailedEvent extends TreeNodeEvent {
private final boolean myTestError;
private final String myComparisonFailureActualText;
private final String myComparisonFailureExpectedText;
private final String myFilePath;
private final String myExpectedFilePath;
private final String myActualFilePath;
private final long myDurationMillis;
public TestFailedEvent(@NotNull TestFailed testFailed, boolean testError) {
this(testFailed, testError, null);
}
public TestFailedEvent(@NotNull TestFailed testFailed, boolean testError, String filePath) {
this(testFailed, testError, filePath, null);
public TestFailedEvent(@NotNull TestFailed testFailed, boolean testError, @Nullable String expectedFilePath) {
this(testFailed, testError, expectedFilePath, null);
}
public TestFailedEvent(@NotNull TestFailed testFailed, boolean testError, String filePath, String actualFilePath) {
public TestFailedEvent(@NotNull TestFailed testFailed,
boolean testError,
@Nullable String expectedFilePath,
@Nullable String actualFilePath) {
super(testFailed.getTestName(), TreeNodeEvent.getNodeId(testFailed));
if (testFailed.getFailureMessage() == null) throw new NullPointerException();
myLocalizedFailureMessage = testFailed.getFailureMessage();
@@ -45,7 +48,7 @@ public class TestFailedEvent extends TreeNodeEvent {
myTestError = testError;
myComparisonFailureActualText = testFailed.getActual();
myComparisonFailureExpectedText = testFailed.getExpected();
myFilePath = filePath;
myExpectedFilePath = expectedFilePath;
myActualFilePath = actualFilePath;
myDurationMillis = parseDuration(testFailed.getAttributes().get("duration"));
}
@@ -85,7 +88,7 @@ public class TestFailedEvent extends TreeNodeEvent {
boolean testError,
@Nullable String comparisonFailureActualText,
@Nullable String comparisonFailureExpectedText,
@Nullable String expectedTextFilePath,
@Nullable String expectedFilePath,
long durationMillis) {
super(testName, id);
myLocalizedFailureMessage = localizedFailureMessage;
@@ -93,7 +96,7 @@ public class TestFailedEvent extends TreeNodeEvent {
myTestError = testError;
myComparisonFailureActualText = comparisonFailureActualText;
myComparisonFailureExpectedText = comparisonFailureExpectedText;
myFilePath = expectedTextFilePath;
myExpectedFilePath = expectedFilePath;
myActualFilePath = null;
myDurationMillis = durationMillis;
}
@@ -131,10 +134,19 @@ public class TestFailedEvent extends TreeNodeEvent {
append(buf, "comparisonFailureExpectedText", myComparisonFailureExpectedText);
}
/**
* @deprecated use {@link #getExpectedFilePath()} instead
*/
public String getFilePath() {
return myFilePath;
return myExpectedFilePath;
}
@Nullable
public String getExpectedFilePath() {
return myExpectedFilePath;
}
@Nullable
public String getActualFilePath() {
return myActualFilePath;
}
@@ -3443,4 +3443,23 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
assertEquals("any variable can be final", 3, findMatchesCount(source, "@Modifier(\"final\") '_T '_a;"));
assertEquals("parameters and local variables are not instance fields", 1, findMatchesCount(source, "@Modifier(\"Instance\") '_T '_a;"));
}
public void testFindParameterizedMethodCalls() {
String source = "interface Foo {" +
" <T> T bar();" +
" <S, T> void bar2(S, T);" +
"}" +
"class X {" +
" void x(Foo foo) {" +
" foo.<String>bar();" +
" foo.<Integer>bar();" +
" String s = foo.bar();" +
" foo.bar2(1, 2);" +
" }" +
"}";
assertEquals("find parameterized method calls 1", 1, findMatchesCount(source, "foo.<Integer>bar()"));
assertEquals("find parameterized method calls 2", 2, findMatchesCount(source, "foo.<String>bar()"));
assertEquals("find parameterized method calls 3", 3, findMatchesCount(source, "'_a.<'_b>'_c('_d*)"));
assertEquals("find parameterized method calls 4", 4, findMatchesCount(source, "'_a.<'_b+>'_c('_d*)"));
}
}
@@ -96,7 +96,7 @@ public class BuildNumber implements Comparable<BuildNumber> {
if (BUILD_NUMBER.equals(version) || SNAPSHOT.equals(version)) {
final String productCode = name != null ? name : "";
return new BuildNumber(productCode, Holder.CURRENT_VERSION.myComponents);
return new BuildNumber(productCode, currentVersion().myComponents);
}
String code = version;
@@ -171,9 +171,17 @@ public class BuildNumber implements Comparable<BuildNumber> {
}
catch (IOException ignored) { }
return fallback();
return fromString(FALLBACK_VERSION);
}
/**
* This method is for internal platform use only. In regular code use {@link com.intellij.openapi.application.ApplicationInfo#getBuild()} instead.
*/
public static BuildNumber currentVersion() {
return Holder.CURRENT_VERSION;
}
@Deprecated
public static BuildNumber fallback() {
return fromString(FALLBACK_VERSION);
}
@@ -45,7 +45,7 @@ import java.util.NoSuchElementException;
*
* @author gregsh
*
* @noinspection unchecked
* @noinspection unchecked, AssignmentToForLoopParameter
*/
public abstract class JBIterator<E> implements Iterator<E> {
private static final Object NONE = new String("#none");
@@ -137,18 +137,14 @@ public abstract class JBIterator<E> implements Iterator<E> {
private void peekNext() {
if (myNext != NONE) return;
Object o = nextImpl();
if (myNext == STOP) return;
Op op = myFirstOp.nextOp;
while (op != null) {
o = op.apply(o);
Object o = NONE;
for (Op op = myFirstOp; op != null; op = op == null ? myFirstOp : op.nextOp) {
o = op == myFirstOp ? nextImpl() : op.apply(o);
if (myNext == SKIP) {
myNext = NONE;
o = nextImpl();
op = myFirstOp;
o = myNext = NONE;
op = null;
}
if (myNext == STOP) return;
op = op.nextOp;
}
myNext = o;
}
@@ -113,10 +113,23 @@ public class ListTableModel<Item> extends TableViewModel<Item> implements Editab
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
setValueAt(aValue, rowIndex, columnIndex, true);
}
/**
* Sets the value in the cell at {@code columnIndex} and {@code rowIndex} to {@code aValue}.
* This method allows to choose will the model listeners notified or not.
*
* @param aValue the new value
* @param rowIndex the row whose value is to be changed
* @param columnIndex the column whose value is to be changed
* @param notifyListeners indicates whether the model listeners are notified
*/
public void setValueAt(Object aValue, int rowIndex, int columnIndex, boolean notifyListeners) {
if (rowIndex < myItems.size()) {
myColumnInfos[columnIndex].setValue(getItem(rowIndex), aValue);
}
fireTableCellUpdated(rowIndex, columnIndex);
if (notifyListeners) fireTableCellUpdated(rowIndex, columnIndex);
}
/**
@@ -129,12 +129,12 @@ public class BuildNumberTest {
}
@Test
public void fallbackVersion() throws Exception {
assertParsed(BuildNumber.fallback(), 999, BuildNumber.SNAPSHOT_VALUE, "999.SNAPSHOT");
assertTrue(BuildNumber.fallback().isSnapshot());
public void currentVersion() throws Exception {
BuildNumber current = BuildNumber.currentVersion();
assertTrue(current.isSnapshot());
assertTrue(BuildNumber.fallback().compareTo(BuildNumber.fromString("7512")) > 0);
assertTrue(BuildNumber.fallback().compareTo(BuildNumber.fromString("145")) > 0);
assertTrue(BuildNumber.fallback().compareTo(BuildNumber.fromString("145.12")) > 0);
assertTrue(current.compareTo(BuildNumber.fromString("7512")) > 0);
assertTrue(current.compareTo(BuildNumber.fromString("145")) > 0);
assertTrue(current.compareTo(BuildNumber.fromString("145.12")) > 0);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,8 +20,6 @@ import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Query;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.InspectionGadgetsFix;
import org.jetbrains.annotations.NotNull;
@@ -90,7 +88,7 @@ public class ConvertToVarargsMethodFix extends InspectionGadgetsFix {
final PsiArrayType arrayType = (PsiArrayType)type;
final PsiType componentType = arrayType.getComponentType();
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(method.getProject());
final PsiType ellipsisType = PsiEllipsisType.createEllipsis(componentType, type.getAnnotations());
final PsiType ellipsisType = new PsiEllipsisType(componentType, TypeAnnotationProvider.Static.create(type.getAnnotations()));
final PsiTypeElement newTypeElement = factory.createTypeElement(ellipsisType);
final PsiTypeElement typeElement = lastParameter.getTypeElement();
if (typeElement != null) {
@@ -39,36 +39,35 @@ public class TrivialFunctionalExpressionUsageInspection extends BaseJavaBatchLoc
@Override
public void visitMethodReferenceExpression(final PsiMethodReferenceExpression expression) {
doCheckMethodCallOnFunctionalExpression(expression, new Condition<PsiElement>() {
@Override
public boolean value(PsiElement element) {
return expression.resolve() != null;
}
});
doCheckMethodCallOnFunctionalExpression(expression, element -> expression.resolve() != null);
}
@Override
public void visitLambdaExpression(final PsiLambdaExpression expression) {
doCheckMethodCallOnFunctionalExpression(expression, new Condition<PsiElement>() {
@Override
public boolean value(PsiElement ggParent) {
final PsiElement body = expression.getBody();
if (!(body instanceof PsiCodeBlock) ||
((PsiCodeBlock)body).getStatements().length == 1) {
return true;
}
final List<PsiExpression> returnExpressions = LambdaUtil.getReturnExpressions(expression);
if (returnExpressions.size() > 1) {
return false;
}
final PsiElement callParent = ggParent.getParent();
if (returnExpressions.isEmpty()) {
return callParent instanceof PsiStatement;
}
return callParent instanceof PsiStatement ||
callParent instanceof PsiLocalVariable ||
callParent instanceof PsiExpression && PsiTreeUtil.getParentOfType(callParent, PsiStatement.class) != null;
doCheckMethodCallOnFunctionalExpression(expression, ggParent -> {
final PsiElement callParent = ggParent.getParent();
final PsiElement body = expression.getBody();
if (!(body instanceof PsiCodeBlock)) {
return callParent instanceof PsiStatement || callParent instanceof PsiLocalVariable || expression.isValueCompatible();
}
if (((PsiCodeBlock)body).getStatements().length == 1) {
return callParent instanceof PsiStatement
|| callParent instanceof PsiLocalVariable
|| ((PsiCodeBlock)body).getStatements()[0] instanceof PsiReturnStatement && expression.isValueCompatible();
}
final List<PsiExpression> returnExpressions = LambdaUtil.getReturnExpressions(expression);
if (returnExpressions.size() > 1) {
return false;
}
if (returnExpressions.isEmpty()) {
return callParent instanceof PsiStatement;
}
return callParent instanceof PsiStatement ||
callParent instanceof PsiLocalVariable;
});
}
@@ -76,20 +75,17 @@ public class TrivialFunctionalExpressionUsageInspection extends BaseJavaBatchLoc
public void visitAnonymousClass(final PsiAnonymousClass aClass) {
if (AnonymousCanBeLambdaInspection.canBeConvertedToLambda(aClass, false, Collections.emptySet())) {
final PsiElement newExpression = aClass.getParent();
doCheckMethodCallOnFunctionalExpression(new Condition<PsiElement>() {
@Override
public boolean value(PsiElement ggParent) {
final PsiMethod method = aClass.getMethods()[0];
final PsiCodeBlock body = method.getBody();
final PsiReturnStatement[] returnStatements = PsiUtil.findReturnStatements(body);
if (returnStatements.length > 1) {
return false;
}
final PsiElement callParent = ggParent.getParent();
return callParent instanceof PsiStatement ||
callParent instanceof PsiLocalVariable;
doCheckMethodCallOnFunctionalExpression(ggParent -> {
final PsiMethod method = aClass.getMethods()[0];
final PsiCodeBlock body = method.getBody();
final PsiReturnStatement[] returnStatements = PsiUtil.findReturnStatements(body);
if (returnStatements.length > 1) {
return false;
}
}, newExpression, aClass.getBaseClassType(), "Replace call with method body");
final PsiElement callParent = ggParent.getParent();
return callParent instanceof PsiStatement ||
callParent instanceof PsiLocalVariable;
}, newExpression, aClass.getBaseClassType(), new ReplaceAnonymousWithLambdaBodyFix());
}
}
@@ -99,16 +95,15 @@ public class TrivialFunctionalExpressionUsageInspection extends BaseJavaBatchLoc
if (parent instanceof PsiTypeCastExpression) {
final PsiType interfaceType = ((PsiTypeCastExpression)parent).getType();
doCheckMethodCallOnFunctionalExpression(elementContainerCondition, parent, interfaceType,
"Replace method call " +
(expression instanceof PsiLambdaExpression ? "on lambda with lambda body"
: "on method reference with corresponding method call"));
expression instanceof PsiLambdaExpression ? new ReplaceWithLambdaBodyFix()
: new ReplaceWithMethodReferenceFix());
}
}
private void doCheckMethodCallOnFunctionalExpression(Condition<PsiElement> elementContainerCondition,
PsiElement parent,
PsiType interfaceType,
String quickFixName) {
LocalQuickFix fix) {
final PsiElement gParent = PsiUtil.skipParenthesizedExprUp(parent.getParent());
if (gParent instanceof PsiReferenceExpression) {
final PsiElement ggParent = gParent.getParent();
@@ -123,8 +118,6 @@ public class TrivialFunctionalExpressionUsageInspection extends BaseJavaBatchLoc
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(interfaceType);
if (resolveMethod == interfaceMethod ||
interfaceMethod != null && MethodSignatureUtil.isSuperMethod(interfaceMethod, resolveMethod)) {
final ReplaceWithLambdaBodyFix fix =
new ReplaceWithLambdaBodyFix(quickFixName);
holder.registerProblem(referenceNameElement, "Method call can be simplified", fix);
}
}
@@ -134,25 +127,145 @@ public class TrivialFunctionalExpressionUsageInspection extends BaseJavaBatchLoc
};
}
private static class ReplaceWithLambdaBodyFix implements LocalQuickFix {
private String myName;
private static void replaceWithLambdaBody(PsiMethodCallExpression callExpression, PsiLambdaExpression element) {
inlineCallArguments(callExpression, element);
public ReplaceWithLambdaBodyFix(String name) {
myName = name;
final PsiElement body = element.getBody();
if (body instanceof PsiExpression) {
callExpression.replace(body);
}
else if (body instanceof PsiCodeBlock) {
final PsiElement parent = callExpression.getParent();
if (parent instanceof PsiStatement) {
final PsiElement gParent = parent.getParent();
restoreComments(gParent, parent, body);
for (PsiStatement statement : ((PsiCodeBlock)body).getStatements()) {
PsiElement toInsert;
if (statement instanceof PsiReturnStatement) {
toInsert = ((PsiReturnStatement)statement).getReturnValue();
}
else {
toInsert = statement;
}
@Nls
@NotNull
@Override
public String getName() {
return getFamilyName();
if (toInsert != null) {
gParent.addBefore(toInsert, parent);
}
}
parent.delete();
}
else {
final PsiStatement[] statements = ((PsiCodeBlock)body).getStatements();
if (statements.length > 0) {
final PsiStatement anchor = PsiTreeUtil.getParentOfType(parent, PsiStatement.class);
if (anchor != null) {
final PsiElement gParent = anchor.getParent();
restoreComments(gParent, anchor, body);
for (int i = 0; i < statements.length - 1; i++) {
gParent.addBefore(statements[i], anchor);
}
}
PsiStatement statement = statements[statements.length - 1];
final PsiExpression returnValue = ((PsiReturnStatement)statement).getReturnValue();
if (returnValue != null) {
callExpression.replace(returnValue);
}
}
}
}
}
private static void restoreComments(PsiElement gParent, PsiElement parent, PsiElement body) {
for (PsiElement comment : PsiTreeUtil.findChildrenOfType(body, PsiComment.class)) {
gParent.addBefore(comment, parent);
}
}
private static void inlineCallArguments(PsiMethodCallExpression callExpression, PsiLambdaExpression element) {
final PsiExpression[] args = callExpression.getArgumentList().getExpressions();
final PsiParameter[] parameters = element.getParameterList().getParameters();
for (int i = 0; i < parameters.length; i++) {
final PsiParameter parameter = parameters[i];
final PsiExpression initializer = args[i];
for (PsiReference reference : ReferencesSearch.search(parameter)) {
final PsiElement referenceElement = reference.getElement();
if (referenceElement instanceof PsiJavaCodeReferenceElement) {
InlineUtil.inlineVariable(parameter, initializer, (PsiJavaCodeReferenceElement)referenceElement);
}
}
}
}
private static class ReplaceWithLambdaBodyFix extends ReplaceFix {
@Nls
@NotNull
@Override
public String getFamilyName() {
return myName;
return "Replace method call on lambda with lambda body";
}
@Override
protected void fixExpression(PsiMethodCallExpression callExpression, PsiExpression qualifierExpression) {
if (qualifierExpression instanceof PsiTypeCastExpression) {
final PsiExpression element = ((PsiTypeCastExpression)qualifierExpression).getOperand();
if (element instanceof PsiLambdaExpression) {
replaceWithLambdaBody(callExpression, (PsiLambdaExpression)element);
}
}
}
}
private static class ReplaceWithMethodReferenceFix extends ReplaceFix {
@Nls
@NotNull
@Override
public String getFamilyName() {
return "Replace method call on method reference with corresponding method call";
}
@Override
protected void fixExpression(PsiMethodCallExpression callExpression, PsiExpression qualifierExpression) {
if (qualifierExpression instanceof PsiTypeCastExpression) {
final PsiExpression element = ((PsiTypeCastExpression)qualifierExpression).getOperand();
if (element instanceof PsiMethodReferenceExpression) {
final PsiLambdaExpression lambdaExpression =
LambdaRefactoringUtil.convertMethodReferenceToLambda((PsiMethodReferenceExpression)element, false, true);
if (lambdaExpression != null) {
replaceWithLambdaBody(callExpression, lambdaExpression);
}
}
}
}
}
private static class ReplaceAnonymousWithLambdaBodyFix extends ReplaceFix {
@Nls
@NotNull
@Override
public String getFamilyName() {
return "Replace call with method body";
}
@Override
protected void fixExpression(PsiMethodCallExpression callExpression, PsiExpression qualifierExpression) {
final PsiExpression cast = AnonymousCanBeLambdaInspection.replacePsiElementWithLambda(qualifierExpression, true, false);
if (cast instanceof PsiTypeCastExpression) {
final PsiExpression lambdaExpression = ((PsiTypeCastExpression)cast).getOperand();
if (lambdaExpression instanceof PsiLambdaExpression) {
replaceWithLambdaBody(callExpression, (PsiLambdaExpression)lambdaExpression);
}
}
}
}
private static abstract class ReplaceFix implements LocalQuickFix {
@Nls
@NotNull
@Override
public String getName() {
return getFamilyName();
}
@Override
@@ -161,98 +274,10 @@ public class TrivialFunctionalExpressionUsageInspection extends BaseJavaBatchLoc
if (!FileModificationService.getInstance().preparePsiElementForWrite(psiElement)) return;
final PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(psiElement, PsiMethodCallExpression.class);
if (callExpression != null) {
final PsiExpression qualifierExpression = PsiUtil.skipParenthesizedExprDown(callExpression.getMethodExpression().getQualifierExpression());
if (qualifierExpression instanceof PsiTypeCastExpression) {
final PsiExpression element = ((PsiTypeCastExpression)qualifierExpression).getOperand();
if (element instanceof PsiLambdaExpression) {
replaceWithLambdaBody(callExpression, (PsiLambdaExpression)element);
}
else if (element instanceof PsiMethodReferenceExpression) {
final PsiLambdaExpression lambdaExpression =
LambdaRefactoringUtil.convertMethodReferenceToLambda((PsiMethodReferenceExpression)element, false, true);
if (lambdaExpression != null) {
replaceWithLambdaBody(callExpression, lambdaExpression);
}
}
}
else if (qualifierExpression instanceof PsiNewExpression) {
final PsiExpression cast = AnonymousCanBeLambdaInspection.replacePsiElementWithLambda(qualifierExpression, true, false);
if (cast instanceof PsiTypeCastExpression) {
final PsiExpression lambdaExpression = ((PsiTypeCastExpression)cast).getOperand();
if (lambdaExpression instanceof PsiLambdaExpression) {
replaceWithLambdaBody(callExpression, (PsiLambdaExpression)lambdaExpression);
}
}
}
fixExpression(callExpression, PsiUtil.skipParenthesizedExprDown(callExpression.getMethodExpression().getQualifierExpression()));
}
}
private static void replaceWithLambdaBody(PsiMethodCallExpression callExpression, PsiLambdaExpression element) {
inlineCallArguments(callExpression, element);
final PsiElement body = element.getBody();
if (body instanceof PsiExpression) {
callExpression.replace(body);
}
else if (body instanceof PsiCodeBlock) {
final PsiElement parent = callExpression.getParent();
if (parent instanceof PsiStatement) {
final PsiElement gParent = parent.getParent();
restoreComments(gParent, parent, body);
for (PsiStatement statement : ((PsiCodeBlock)body).getStatements()) {
PsiElement toInsert;
if (statement instanceof PsiReturnStatement) {
toInsert = ((PsiReturnStatement)statement).getReturnValue();
}
else {
toInsert = statement;
}
if (toInsert != null) {
gParent.addBefore(toInsert, parent);
}
}
parent.delete();
}
else {
final PsiStatement[] statements = ((PsiCodeBlock)body).getStatements();
if (statements.length > 0) {
final PsiStatement anchor = PsiTreeUtil.getParentOfType(parent, PsiStatement.class);
if (anchor != null) {
final PsiElement gParent = anchor.getParent();
restoreComments(gParent, anchor, body);
for (int i = 0; i < statements.length - 1; i++) {
gParent.addBefore(statements[i], anchor);
}
}
final PsiExpression returnValue = ((PsiReturnStatement)statements[statements.length - 1]).getReturnValue();
if (returnValue != null) {
callExpression.replace(returnValue);
}
}
}
}
}
private static void restoreComments(PsiElement gParent, PsiElement parent, PsiElement body) {
for (PsiElement comment : PsiTreeUtil.findChildrenOfType(body, PsiComment.class)) {
gParent.addBefore(comment, parent);
}
}
private static void inlineCallArguments(PsiMethodCallExpression callExpression, PsiLambdaExpression element) {
final PsiExpression[] args = callExpression.getArgumentList().getExpressions();
final PsiParameter[] parameters = element.getParameterList().getParameters();
for (int i = 0; i < parameters.length; i++) {
final PsiParameter parameter = parameters[i];
final PsiExpression initializer = args[i];
for (PsiReference reference : ReferencesSearch.search(parameter)) {
final PsiElement referenceElement = reference.getElement();
if (referenceElement instanceof PsiJavaCodeReferenceElement) {
InlineUtil.inlineVariable(parameter, initializer, (PsiJavaCodeReferenceElement)referenceElement);
}
}
}
}
protected abstract void fixExpression(PsiMethodCallExpression callExpression, PsiExpression qualifierExpression);
}
}
@@ -48,7 +48,7 @@ public class MakeMethodVarargsIntention extends Intention {
final PsiElementFactory factory = JavaPsiFacade.getInstance(element.getProject()).getElementFactory();
final PsiTypeElement typeElement = lastParameter.getTypeElement();
LOG.assertTrue(typeElement != null);
final PsiType ellipsisType = PsiEllipsisType.createEllipsis(((PsiArrayType)type).getComponentType(), type.getAnnotations());
final PsiType ellipsisType = new PsiEllipsisType(((PsiArrayType)type).getComponentType(), TypeAnnotationProvider.Static.create(type.getAnnotations()));
typeElement.replace(factory.createTypeElement(ellipsisType));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -1131,6 +1131,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
return JavaPsiFacade.getElementFactory(myProject).createType(resolve, substitutor, languageLevel);
}
@SuppressWarnings("deprecation")
@NotNull
@Override
public PsiClassType createType(@NotNull PsiClass resolve,
@@ -336,7 +336,7 @@ public class GrChangeInfoImpl implements JavaChangeInfo {
@Override
public PsiExpression getValue(int i, PsiCallExpression callExpression) {
if (defaultValues[i] != null) return defaultValues[i];
final PsiElement valueAtCallSite = parameters.get(i).getActualValue(callExpression);
final PsiElement valueAtCallSite = parameters.get(i).getActualValue(callExpression, PsiSubstitutor.EMPTY);
return valueAtCallSite instanceof PsiExpression ? (PsiExpression)valueAtCallSite : null;
}
@@ -529,7 +529,7 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
argsToDelete.removeAll(map[index].args);
}
else {
values[i] = createDefaultValue(factory, changeInfo, parameter, argumentList);
values[i] = createDefaultValue(factory, changeInfo, parameter, argumentList, substitutor);
}
}
@@ -640,7 +640,8 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
private static GrExpression createDefaultValue(GroovyPsiElementFactory factory,
JavaChangeInfo changeInfo,
JavaParameterInfo info,
final GrArgumentList list) {
final GrArgumentList list,
PsiSubstitutor substitutor) {
if (info.isUseAnySingleVariable()) {
final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(list.getProject()).getResolveHelper();
final PsiType type = info.getTypeWrapper().getType(changeInfo.getMethod(), list.getManager());
@@ -689,7 +690,7 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
}
}
final PsiElement element = info.getActualValue(list.getParent());
final PsiElement element = info.getActualValue(list.getParent(), substitutor);
if (element instanceof GrExpression) {
return (GrExpression)element;
}
@@ -76,10 +76,10 @@ public class GroovyIntroduceParameterObjectDelegate
return new GrParameterInfo(descriptor.getClassName(), null, null, classType, -1, false) {
@Nullable
@Override
public PsiElement getActualValue(PsiElement callExpression) {
public PsiElement getActualValue(PsiElement callExpression, Object substitutor) {
final IntroduceParameterObjectDelegate<PsiNamedElement, ParameterInfo, IntroduceParameterObjectClassDescriptor<PsiNamedElement, ParameterInfo>>
delegate = findDelegate(callExpression);
return delegate != null ? delegate.createNewParameterInitializerAtCallSite(callExpression, descriptor, oldMethodParameters) : null;
return delegate != null ? delegate.createNewParameterInitializerAtCallSite(callExpression, descriptor, oldMethodParameters, substitutor) : null;
}
};
}
@@ -87,7 +87,8 @@ public class GroovyIntroduceParameterObjectDelegate
@Override
public PsiElement createNewParameterInitializerAtCallSite(PsiElement callExpression,
IntroduceParameterObjectClassDescriptor descriptor,
List<? extends ParameterInfo> oldMethodParameters) {
List<? extends ParameterInfo> oldMethodParameters,
Object substitutor) {
if (callExpression instanceof GrCallExpression) {
final GrArgumentList list = ((GrCallExpression)callExpression).getArgumentList();
if (list == null) {
@@ -7,9 +7,11 @@
<project-components>
<component>
<implementation-class>com.intellij.designer.DesignerToolWindowManager</implementation-class>
<headless-implementation-class></headless-implementation-class>
</component>
<component>
<implementation-class>com.intellij.designer.palette.PaletteToolWindowManager</implementation-class>
<headless-implementation-class></headless-implementation-class>
</component>
</project-components>
@@ -550,14 +550,7 @@ public class XPathEvalAction extends XPathAction {
public abstract static class EditExpressionAction implements Runnable {
@Override
public void run() {
Runnable runnable = new Runnable() {
@Override
public void run() {
execute();
}
};
SwingUtilities.invokeLater(runnable);
execute();
}
protected abstract void execute();
@@ -19,18 +19,17 @@
<projectService serviceImplementation="com.jetbrains.edu.coursecreator.CCProjectService"/>
<treeStructureProvider implementation="com.jetbrains.edu.coursecreator.projectView.CCTreeStructureProvider"/>
<refactoring.elementListenerProvider implementation="com.jetbrains.edu.coursecreator.CCRefactoringElementListenerProvider"/>
<refactoring.moveHandler implementation="com.jetbrains.edu.coursecreator.CCLessonMoveHandlerDelegate" order="first"/>
<refactoring.moveHandler implementation="com.jetbrains.edu.coursecreator.CCTaskMoveHandlerDelegate" order="first"/>
<renameHandler implementation="com.jetbrains.edu.coursecreator.CCTaskRenameHandler" order="first"/>
<renameHandler implementation="com.jetbrains.edu.coursecreator.CCLessonRenameHandler" order="first"/>
<refactoring.moveHandler implementation="com.jetbrains.edu.coursecreator.handlers.CCLessonMoveHandlerDelegate" order="first"/>
<refactoring.moveHandler implementation="com.jetbrains.edu.coursecreator.handlers.CCTaskMoveHandlerDelegate" order="first"/>
<renameHandler implementation="com.jetbrains.edu.coursecreator.handlers.CCTaskRenameHandler" order="first"/>
<renameHandler implementation="com.jetbrains.edu.coursecreator.handlers.CCLessonRenameHandler" order="first"/>
</extensions>
<extensions defaultExtensionNs="Edu">
<studyActionsProvider implementation="com.jetbrains.edu.coursecreator.CCStudyActionsProvider"/>
<studyActionListener implementation="com.jetbrains.edu.coursecreator.CCStudyActionListener"/>
</extensions>
<application-components>
<!-- Add your application components here -->
</application-components>
<project-components>
<!-- Add your project components here -->
<component>
<implementation-class>com.jetbrains.edu.coursecreator.CCProjectComponent</implementation-class>
</component>
@@ -46,49 +45,40 @@
<action id="CreateLesson" class="com.jetbrains.edu.coursecreator.actions.CCCreateLesson">
<add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewFile"/>
</action>
<action id="ChangeCourseInfo" class="com.jetbrains.edu.coursecreator.actions.CCChangeCourseInfo">
<add-to-group group-id="ProjectViewPopupMenu" anchor="before" relative-to-action="PackCourse"/>
</action>
<action id="CreateTask" class="com.jetbrains.edu.coursecreator.actions.CCCreateTask">
<add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewFile"/>
</action>
<action id="CreateTaskFile" class="com.jetbrains.edu.coursecreator.actions.CCCreateTaskFile">
<add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewFile"/>
</action>
<action id="AddTaskFile" class="com.jetbrains.edu.coursecreator.actions.CCAddAsTaskFile" text="Add As Task File">
<add-to-group group-id="ProjectViewPopupMenu" anchor="first"/>
</action>
<action id="AddTaskWindow" class="com.jetbrains.edu.coursecreator.actions.CCAddAnswerPlaceholder">
<add-to-group group-id="EditorPopupMenu" anchor="before" relative-to-action="CopyReference"/>
</action>
<action id="ShowTaskWindowDetails" class="com.jetbrains.edu.coursecreator.actions.CCShowAnswerPlaceholderDetails">
<add-to-group group-id="EditorPopupMenu" anchor="before" relative-to-action="CopyReference"/>
</action>
<action id="DeleteTaskWindow" class="com.jetbrains.edu.coursecreator.actions.CCDeleteAnswerPlaceholder">
<add-to-group group-id="EditorPopupMenu" anchor="before" relative-to-action="CopyReference"/>
</action>
<action id="ShowPreview" class="com.jetbrains.edu.coursecreator.actions.CCShowPreview">
<add-to-group group-id="ProjectViewPopupMenu" anchor="first"/>
<add-to-group group-id="EditorTabPopupMenu"/>
</action>
<action id="PackCourse" class="com.jetbrains.edu.coursecreator.actions.CCCreateCourseArchive">
<add-to-group group-id="ProjectViewPopupMenu" anchor="before" relative-to-action="CutCopyPasteGroup"/>
<add-to-group group-id="FileMenu" relative-to-action="FileMainSettingsGroup" anchor="before"/>
</action>
<action id="UnpackCourse" class="com.jetbrains.edu.coursecreator.actions.CCFromCourseArchive"/>
<action id="PushLesson" class="com.jetbrains.edu.coursecreator.actions.CCPushLesson">
<add-to-group group-id="ProjectViewPopupMenu" anchor="before" relative-to-action="CutCopyPasteGroup"/>
<add-to-group group-id="FileMenu" relative-to-action="FileMainSettingsGroup" anchor="before"/>
</action>
<action id="PushCourse" class="com.jetbrains.edu.coursecreator.actions.CCPushCourse">
<add-to-group group-id="ProjectViewPopupMenu" anchor="before" relative-to-action="CutCopyPasteGroup"/>
<add-to-group group-id="FileMenu" relative-to-action="FileMainSettingsGroup" anchor="before"/>
</action>
<action id="DeleteAllPlaceholders" class="com.jetbrains.edu.coursecreator.actions.CCDeleteAllAnswerPlaceholdersAction">
<group id="CCProjectViewGroup">
<action id="AddTaskFile" class="com.jetbrains.edu.coursecreator.actions.CCAddAsTaskFile" text="Add as Task File"/>
<action id="HideTaskFile" class="com.jetbrains.edu.coursecreator.actions.CCHideFromStudent" text="Hide from Student"/>
<action id="ShowPreview" class="com.jetbrains.edu.coursecreator.actions.CCShowPreview">
<add-to-group group-id="EditorTabPopupMenu"/>
</action>
<action id="DeleteAllPlaceholders" class="com.jetbrains.edu.coursecreator.actions.CCDeleteAllAnswerPlaceholdersAction"/>
<action id="PackCourse" class="com.jetbrains.edu.coursecreator.actions.CCCreateCourseArchive">
<add-to-group group-id="FileMenu" relative-to-action="FileMainSettingsGroup" anchor="before"/>
</action>
<action id="PushLesson" class="com.jetbrains.edu.coursecreator.actions.CCPushLesson">
<add-to-group group-id="FileMenu" relative-to-action="FileMainSettingsGroup" anchor="before"/>
</action>
<action id="PushCourse" class="com.jetbrains.edu.coursecreator.actions.CCPushCourse">
<add-to-group group-id="FileMenu" relative-to-action="FileMainSettingsGroup" anchor="before"/>
</action>
<action id="ChangeCourseInfo" class="com.jetbrains.edu.coursecreator.actions.CCChangeCourseInfo"/>
<separator/>
<add-to-group group-id="ProjectViewPopupMenu" anchor="before" relative-to-action="CutCopyPasteGroup"/>
<add-to-group group-id="EditorPopupMenu" anchor="after" relative-to-action="DeleteTaskWindow"/>
</action>
</group>
<group id="AnswerPlaceholderGroup">
<action id="EditAnswerPlaceholder" class="com.jetbrains.edu.coursecreator.actions.CCEditAnswerPlaceholder"/>
<action id="AddTaskWindow" class="com.jetbrains.edu.coursecreator.actions.CCAddAnswerPlaceholder"/>
<reference ref="DeleteAllPlaceholders"/>
<separator/>
<add-to-group group-id="EditorPopupMenu" anchor="first"/>
</group>
<action id="UnpackCourse" class="com.jetbrains.edu.coursecreator.actions.CCFromCourseArchive"/>
</actions>
</idea-plugin>
@@ -1,69 +0,0 @@
package com.jetbrains.edu.coursecreator;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorActionManager;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.event.EditorFactoryEvent;
import com.intellij.openapi.editor.event.EditorFactoryListener;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.learning.core.EduAnswerPlaceholderDeleteHandler;
import com.jetbrains.edu.learning.core.EduAnswerPlaceholderPainter;
import com.jetbrains.edu.learning.core.EduDocumentListener;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
import org.jetbrains.annotations.NotNull;
public class CCEditorFactoryListener implements EditorFactoryListener {
@Override
public void editorCreated(@NotNull EditorFactoryEvent event) {
Editor editor = event.getEditor();
Project project = editor.getProject();
if (project == null) {
return;
}
VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(editor.getDocument());
if (virtualFile == null) {
return;
}
final CCProjectService service = CCProjectService.getInstance(project);
Course course = service.getCourse();
if (course == null) {
return;
}
final VirtualFile taskDir = virtualFile.getParent();
if (taskDir == null || !taskDir.getName().contains(EduNames.TASK)) {
return;
}
final VirtualFile lessonDir = taskDir.getParent();
if (lessonDir == null) return;
final TaskFile taskFile = service.getTaskFile(virtualFile);
if (taskFile == null) {
return;
}
EduDocumentListener listener = new EduDocumentListener(taskFile, true, true);
CCProjectService.addDocumentListener(editor.getDocument(), listener);
editor.getDocument().addDocumentListener(listener);
EditorActionManager.getInstance()
.setReadonlyFragmentModificationHandler(editor.getDocument(), new EduAnswerPlaceholderDeleteHandler(editor));
service.drawAnswerPlaceholders(virtualFile, editor);
editor.getColorsScheme().setColor(EditorColors.READONLY_FRAGMENT_BACKGROUND_COLOR, null);
EduAnswerPlaceholderPainter.createGuardedBlocks(editor, taskFile, false);
}
@Override
public void editorReleased(@NotNull EditorFactoryEvent event) {
Editor editor = event.getEditor();
Document document = editor.getDocument();
EduDocumentListener listener = CCProjectService.getListener(document);
if (listener != null) {
document.removeDocumentListener(listener);
CCProjectService.removeListener(document);
}
editor.getMarkupModel().removeAllHighlighters();
editor.getSelectionModel().removeSelection();
}
}
@@ -3,6 +3,7 @@ package com.jetbrains.edu.coursecreator;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.lang.LanguageExtension;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -21,4 +22,8 @@ public interface CCLanguageManager {
FileTemplate getTestsTemplate(@NotNull final Project project);
boolean doNotPackFile(File pathname);
default boolean isTestFile(VirtualFile file) {
return false;
}
}
@@ -1,33 +1,40 @@
package com.jetbrains.edu.coursecreator;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.event.EditorFactoryEvent;
import com.intellij.openapi.editor.impl.EditorFactoryImpl;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.impl.text.PsiAwareTextEditorImpl;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.jetbrains.edu.learning.StudyProjectComponent;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.courseFormat.Course;
import org.jetbrains.annotations.NotNull;
public class CCProjectComponent implements ProjectComponent {
private final Project myProject;
private CCFileDeletedListener myListener;
import java.io.File;
public CCProjectComponent(Project project) {
public class CCProjectComponent extends AbstractProjectComponent {
private final CCVirtualFileListener myTaskFileLifeListener = new CCVirtualFileListener();
private final Project myProject;
protected CCProjectComponent(Project project) {
super(project);
myProject = project;
}
public void initComponent() {
VirtualFileManager.getInstance().addVirtualFileListener(myTaskFileLifeListener);
}
public void disposeComponent() {
public void migrateIfNeeded() {
Course studyCourse = StudyTaskManager.getInstance(myProject).getCourse();
Course course = CCProjectService.getInstance(myProject).getCourse();
if (studyCourse == null && course != null) {
course.setCourseMode(CCUtils.COURSE_MODE);
File coursesDir = new File(PathManager.getConfigPath(), "courses");
File courseDir = new File(coursesDir, course.getName() + "-" + myProject.getName());
course.setCourseDirectory(courseDir.getPath());
StudyTaskManager.getInstance(myProject).setCourse(course);
StudyProjectComponent.getInstance(myProject).registerStudyToolWindow(course);
}
}
@NotNull
@@ -36,36 +43,11 @@ public class CCProjectComponent implements ProjectComponent {
}
public void projectOpened() {
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new Runnable() {
@Override
public void run() {
final Course course = CCProjectService.getInstance(myProject).getCourse();
if (course != null) {
course.initCourse(true);
myListener = new CCFileDeletedListener(myProject);
VirtualFileManager.getInstance().addVirtualFileListener(myListener);
final CCEditorFactoryListener editorFactoryListener = new CCEditorFactoryListener();
EditorFactory.getInstance().addEditorFactoryListener(editorFactoryListener, myProject);
VirtualFile[] files = FileEditorManager.getInstance(myProject).getOpenFiles();
for (VirtualFile file : files) {
if (CCProjectService.getInstance(myProject).isTaskFile(file)) {
FileEditorManager.getInstance(myProject).closeFile(file);
continue;
}
FileEditor fileEditor = FileEditorManager.getInstance(myProject).getSelectedEditor(file);
if (fileEditor instanceof PsiAwareTextEditorImpl) {
Editor editor = ((PsiAwareTextEditorImpl)fileEditor).getEditor();
editorFactoryListener.editorCreated(new EditorFactoryEvent(new EditorFactoryImpl(ProjectManager.getInstance()), editor));
}
}
}
}
});
migrateIfNeeded();
VirtualFileManager.getInstance().addVirtualFileListener(myTaskFileLifeListener);
}
public void projectClosed() {
if (myListener != null) {
VirtualFileManager.getInstance().removeVirtualFileListener(myListener);
}
VirtualFileManager.getInstance().removeVirtualFileListener(myTaskFileLifeListener);
}
}
@@ -15,140 +15,24 @@
*/
package com.jetbrains.edu.coursecreator;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.JBColor;
import com.intellij.util.xmlb.XmlSerializerUtil;
import com.jetbrains.edu.learning.core.EduAnswerPlaceholderPainter;
import com.jetbrains.edu.learning.core.EduDocumentListener;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.core.EduUtils;
import com.jetbrains.edu.learning.courseFormat.*;
import com.jetbrains.edu.learning.courseFormat.Course;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@State(name = "CCProjectService", storages = @Storage("course_service.xml"))
public class CCProjectService implements PersistentStateComponent<CCProjectService> {
private Course myCourse;
private static final Map<Document, EduDocumentListener> myDocumentListeners = new HashMap<Document, EduDocumentListener>();
@Nullable
public TaskFile getTaskFile(@NotNull final VirtualFile virtualFile) {
VirtualFile taskDir = virtualFile.getParent();
if (taskDir == null) {
return null;
}
String taskDirName = taskDir.getName();
if (!taskDirName.contains(EduNames.TASK)) {
return null;
}
VirtualFile lessonDir = taskDir.getParent();
if (lessonDir == null) {
return null;
}
String lessonDirName = lessonDir.getName();
if (!lessonDirName.contains(EduNames.LESSON)) {
return null;
}
Lesson lesson = myCourse.getLesson(lessonDirName);
if (lesson == null) {
return null;
}
Task task = lesson.getTask(taskDir.getName());
if (task == null) {
return null;
}
return task.getTaskFile(virtualFile.getName());
}
public void drawAnswerPlaceholders(@NotNull final VirtualFile virtualFile, @NotNull final Editor editor) {
TaskFile taskFile = getTaskFile(virtualFile);
if (taskFile == null) {
return;
}
List<AnswerPlaceholder> answerPlaceholders = taskFile.getAnswerPlaceholders();
for (AnswerPlaceholder answerPlaceholder : answerPlaceholders) {
EduAnswerPlaceholderPainter.drawAnswerPlaceholder(editor, answerPlaceholder, false, JBColor.BLUE);
}
}
public static void addDocumentListener(Document document, EduDocumentListener listener) {
myDocumentListeners.put(document, listener);
}
public static EduDocumentListener getListener(Document document) {
return myDocumentListeners.get(document);
}
public static void removeListener(Document document) {
myDocumentListeners.remove(document);
}
@Nullable
public Task getTask(VirtualFile file) {
if (myCourse == null || file == null) {
return null;
}
VirtualFile taskDir = file.getParent();
if (taskDir != null) {
String taskDirName = taskDir.getName();
if (taskDirName.contains(EduNames.TASK)) {
VirtualFile lessonDir = taskDir.getParent();
if (lessonDir != null) {
String lessonDirName = lessonDir.getName();
int lessonIndex = EduUtils.getIndex(lessonDirName, EduNames.LESSON);
List<Lesson> lessons = myCourse.getLessons();
if (!EduUtils.indexIsValid(lessonIndex, lessons)) {
return null;
}
Lesson lesson = lessons.get(lessonIndex);
int taskIndex = EduUtils.getIndex(taskDirName, EduNames.TASK);
List<Task> tasks = lesson.getTaskList();
if (!EduUtils.indexIsValid(taskIndex, tasks)) {
return null;
}
return tasks.get(taskIndex);
}
}
}
return null;
}
public boolean isTaskFile(VirtualFile file) {
Task task = getTask(file);
return task != null && task.isTaskFile(file.getName());
}
public static boolean setCCActionAvailable(@NotNull AnActionEvent e) {
final Project project = e.getProject();
if (project == null) {
return false;
}
if (getInstance(project).getCourse() == null) {
EduUtils.enableAction(e, false);
return false;
}
EduUtils.enableAction(e, true);
return true;
}
public Course getCourse() {
return myCourse;
}
public void setCourse(@NotNull final Course course) {
public void setCourse(Course course) {
myCourse = course;
}
@@ -16,24 +16,30 @@
package com.jetbrains.edu.coursecreator;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.refactoring.listeners.RefactoringElementAdapter;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.refactoring.listeners.RefactoringElementListenerProvider;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.Lesson;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
import com.jetbrains.edu.coursecreator.actions.CCRunTestsAction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.Map;
public class CCRefactoringElementListenerProvider implements RefactoringElementListenerProvider {
private static final Logger LOG = Logger.getInstance(CCRefactoringElementListenerProvider.class);
@Nullable
@Override
public RefactoringElementListener getListener(PsiElement element) {
@@ -62,8 +68,7 @@ public class CCRefactoringElementListenerProvider implements RefactoringElementL
private static void tryToRenameTaskFile(PsiFile file, String oldName) {
final PsiDirectory taskDir = file.getContainingDirectory();
final CCProjectService service = CCProjectService.getInstance(file.getProject());
Course course = service.getCourse();
Course course = StudyTaskManager.getInstance(file.getProject()).getCourse();
if (course == null) {
return;
}
@@ -82,16 +87,29 @@ public class CCRefactoringElementListenerProvider implements RefactoringElementL
if (task == null) {
return;
}
Map<String, TaskFile> taskFiles = task.getTaskFiles();
TaskFile taskFile = task.getTaskFile(oldName);
if (taskFile == null) {
return;
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
CCRunTestsAction.clearTestEnvironment(taskDir.getVirtualFile(), taskDir.getProject());
VirtualFile patternFile = StudyUtils.getPatternFile(taskFile, oldName);
if (patternFile != null) {
try {
patternFile.delete(CCRefactoringElementListenerProvider.class);
}
catch (IOException e) {
LOG.info(e);
}
}
}
});
Map<String, TaskFile> taskFiles = task.getTaskFiles();
TaskFile taskFile = task.getTaskFile(oldName);
taskFiles.remove(oldName);
taskFiles.put(file.getName(), taskFile);
CCUtils.createResourceFile(file.getVirtualFile(), course, taskDir.getVirtualFile());
}
@Override
@@ -0,0 +1,36 @@
package com.jetbrains.edu.coursecreator;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.learning.StudyActionListener;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
public class CCStudyActionListener implements StudyActionListener {
@Override
public void beforeCheck(AnActionEvent event) {
Project project = event.getProject();
if (project == null) {
return;
}
VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(event.getDataContext());
if (virtualFile == null) {
return;
}
TaskFile taskFile = StudyUtils.getTaskFile(project, virtualFile);
if (taskFile == null) {
return;
}
Task task = taskFile.getTask();
VirtualFile taskDir = StudyUtils.getTaskDir(virtualFile);
if (taskDir == null) {
return;
}
CCUtils.createResources(project, task, taskDir);
}
}
@@ -0,0 +1,12 @@
package com.jetbrains.edu.coursecreator;
import com.intellij.openapi.actionSystem.AnAction;
import com.jetbrains.edu.coursecreator.actions.CCEditTaskTextAction;
import com.jetbrains.edu.learning.StudyActionsProvider;
public class CCStudyActionsProvider implements StudyActionsProvider{
@Override
public AnAction[] getActions() {
return new AnAction[]{new CCEditTaskTextAction()};
}
}

Some files were not shown because too many files have changed in this diff Show More