Merge remote-tracking branch 'origin/master'

This commit is contained in:
Sascha Weinreuter
2013-04-25 09:46:31 +02:00
129 changed files with 1510 additions and 634 deletions
+2 -2
View File
@@ -1,11 +1,11 @@
<component name="libraryTable">
<library name="gson">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/gson-2.2.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/gson-2.2.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/gson-2.2.1-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/src/gson-2.2.3-sources.jar!/" />
</SOURCES>
</library>
</component>
@@ -15,8 +15,8 @@
*/
package com.intellij.compiler.actions;
import org.jetbrains.jps.model.java.compiler.AnnotationProcessingConfiguration;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.compiler.CompilerWorkspaceConfiguration;
import com.intellij.compiler.impl.FileSetCompileScope;
import com.intellij.compiler.impl.ModuleCompileScope;
import com.intellij.compiler.impl.javaCompiler.AnnotationProcessingCompiler;
@@ -37,6 +37,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.java.compiler.AnnotationProcessingConfiguration;
import java.text.MessageFormat;
import java.util.ArrayList;
@@ -79,7 +80,13 @@ public class ProcessAnnotationsAction extends CompileActionBase {
return;
}
CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(project);
if (CompilerWorkspaceConfiguration.getInstance(project).useOutOfProcessBuild()) {
presentation.setEnabled(false);
return;
}
final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(project);
final Module module = LangDataKeys.MODULE.getData(dataContext);
final Module moduleContext = LangDataKeys.MODULE_CONTEXT.getData(dataContext);
@@ -854,17 +854,35 @@ public class CompileDriver {
if (refreshOutputRoots) {
// refresh on output roots is required in order for the order enumerator to see all roots via VFS
final Set<File> outputs = new HashSet<File>();
for (final String path : CompilerPathsEx.getOutputPaths(ModuleManager.getInstance(myProject).getModules())) {
final Module[] affectedModules = compileContext.getCompileScope().getAffectedModules();
for (final String path : CompilerPathsEx.getOutputPaths(affectedModules)) {
outputs.add(new File(path));
}
final LocalFileSystem lfs = LocalFileSystem.getInstance();
if (!outputs.isEmpty()) {
final ProgressIndicator indicator = compileContext.getProgressIndicator();
indicator.setText("Synchronizing output directories...");
LocalFileSystem.getInstance().refreshIoFiles(outputs, false, false, null);
lfs.refreshIoFiles(outputs, false, false, null);
indicator.setText("");
}
if (compileContext.isAnnotationProcessorsEnabled()) {
final Set<File> genSourceRoots = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
final CompilerConfiguration config = CompilerConfiguration.getInstance(myProject);
for (Module module : affectedModules) {
if (config.getAnnotationProcessingConfiguration(module).isEnabled()) {
final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
if (path != null) {
genSourceRoots.add(new File(path));
}
}
}
if (!genSourceRoots.isEmpty()) {
// refresh generates source roots asynchronously; needed for error highlighting update
lfs.refreshIoFiles(genSourceRoots, true, true, null);
}
}
}
SwingUtilities.invokeLater(new Runnable() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
int errorCount = 0;
int warningCount = 0;
@@ -21,6 +21,7 @@ import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.settings.*;
import com.intellij.debugger.ui.breakpoints.*;
import com.intellij.ide.DataManager;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
@@ -31,16 +32,17 @@ import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xdebugger.AbstractDebuggerSession;
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointItem;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
import com.intellij.xdebugger.impl.DebuggerSupport;
import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
import com.intellij.xdebugger.impl.actions.DebuggerToggleActionHandler;
import com.intellij.xdebugger.impl.actions.EditBreakpointActionHandler;
import com.intellij.xdebugger.impl.actions.MarkObjectActionHandler;
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointItem;
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointPanelProvider;
import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler;
import com.intellij.xdebugger.impl.settings.DebuggerSettingsPanelProvider;
@@ -212,15 +214,21 @@ public class JavaDebuggerSupport extends DebuggerSupport {
}
@Override
public void addListener(final BreakpointsListener listener, Project project) {
BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(getCurrentProject()).getBreakpointManager();
public void addListener(final BreakpointsListener listener, Project project, Disposable disposable) {
BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager();
final MyBreakpointManagerListener listener1 = new MyBreakpointManagerListener(listener, breakpointManager);
breakpointManager.addBreakpointManagerListener(listener1);
myListeners.add(listener1);
Disposer.register(disposable, new Disposable() {
@Override
public void dispose() {
removeListener(listener);
}
});
}
@Override
public void removeListener(BreakpointsListener listener) {
protected void removeListener(BreakpointsListener listener) {
for (MyBreakpointManagerListener managerListener : myListeners) {
if (managerListener.myListener == listener) {
BreakpointManager manager = managerListener.myBreakpointManager;
@@ -1357,9 +1357,9 @@ public class HighlightUtil extends HighlightUtilBase {
}
}
final PsiClass aClass;
PsiClass aClass;
if (qualifier != null) {
final PsiElement resolved = qualifier.resolve();
PsiElement resolved = qualifier.advancedResolve(true).getElement();
if (resolved != null && !(resolved instanceof PsiClass)) {
String description = JavaErrorMessages.message("class.expected");
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(qualifier).descriptionAndTooltip(description).create();
@@ -1393,7 +1393,7 @@ public class HighlightUtil extends HighlightUtilBase {
}
return null;
}
private static boolean isInsideDefaultMethod(PsiMethod method, PsiClass aClass) {
while (method != null && method.getContainingClass() != aClass) {
method = PsiTreeUtil.getParentOfType(method, PsiMethod.class, true);
@@ -156,7 +156,8 @@ public abstract class CreateClassFromUsageBaseFix extends BaseIntentionAction {
final PsiClassType.ClassResolveResult classResolveResult = PsiUtil.resolveGenericsClassInType(expectedTypes[0].getType());
final PsiClass psiClass = classResolveResult.getElement();
if (psiClass != null && CommonClassNames.JAVA_LANG_CLASS.equals(psiClass.getQualifiedName())) {
PsiType psiType = classResolveResult.getSubstitutor().substitute(psiClass.getTypeParameters()[0]);
final PsiTypeParameter[] typeParameters = psiClass.getTypeParameters();
PsiType psiType = typeParameters.length == 1 ? classResolveResult.getSubstitutor().substitute(typeParameters[0]) : null;
if (psiType instanceof PsiWildcardType && ((PsiWildcardType)psiType).isExtends()) {
psiType = ((PsiWildcardType)psiType).getExtendsBound();
}
@@ -155,7 +155,7 @@ public class CreateLocalFromUsageFix extends CreateVarFromUsageFix {
}
final PsiCodeBlock block = PsiTreeUtil.getParentOfType(parent, PsiCodeBlock.class, false);
LOG.assertTrue(block != null && block.getStatements().length > 0, block);
LOG.assertTrue(block != null && block.getStatements().length > 0, "block: " + block +"; parent: " + parent);
PsiStatement[] statements = block.getStatements();
for (int i = 1; i < statements.length; i++) {
if (statements[i].getTextRange().getStartOffset() > minOffset) return statements[i-1];
@@ -61,8 +61,7 @@ public class AddSingleMemberStaticImportAction extends PsiElementBaseIntentionAc
if (parent instanceof PsiMethodReferenceExpression) return null;
if (parent instanceof PsiJavaCodeReferenceElement && ((PsiJavaCodeReferenceElement)parent).getQualifier() != null) {
PsiJavaCodeReferenceElement refExpr = (PsiJavaCodeReferenceElement)parent;
PsiReferenceParameterList parameterList = refExpr.getParameterList();
if (parameterList != null && parameterList.getFirstChild() != null) return null;
if (checkParameterizedReference(refExpr)) return null;
PsiElement resolved = refExpr.resolve();
if (resolved instanceof PsiMember && ((PsiModifierListOwner)resolved).hasModifierProperty(PsiModifier.STATIC)) {
PsiClass aClass = getResolvedClass(element, (PsiMember)resolved);
@@ -99,6 +98,11 @@ public class AddSingleMemberStaticImportAction extends PsiElementBaseIntentionAc
return null;
}
private static boolean checkParameterizedReference(PsiJavaCodeReferenceElement refExpr) {
PsiReferenceParameterList parameterList = refExpr instanceof PsiReferenceExpression ? refExpr.getParameterList() : null;
return parameterList != null && parameterList.getFirstChild() != null;
}
@Nullable
private static PsiClass getResolvedClass(PsiElement element, PsiMember resolved) {
PsiClass aClass = resolved.getContainingClass();
@@ -158,58 +162,61 @@ public class AddSingleMemberStaticImportAction extends PsiElementBaseIntentionAc
@Override
public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
if (reference.getParameterList() != null &&
reference.getParameterList().getFirstChild() != null) return;
try {
if (checkParameterizedReference(reference)) return;
if (referenceName.equals(reference.getReferenceName()) && !(reference instanceof PsiMethodReferenceExpression)) {
final PsiElement qualifierExpression = reference.getQualifier();
PsiElement referent = reference.getUserData(TEMP_REFERENT_USER_DATA);
if (!reference.isQualified()) {
if (referent instanceof PsiMember && referent != reference.resolve()) {
PsiElementFactory factory = JavaPsiFacade.getInstance(reference.getProject()).getElementFactory();
try {
final PsiClass containingClass = ((PsiMember)referent).getContainingClass();
if (containingClass != null) {
PsiReferenceExpression copy = (PsiReferenceExpression)factory.createExpressionFromText("A." + reference.getReferenceName(), null);
reference = (PsiReferenceExpression)reference.replace(copy);
((PsiReferenceExpression)reference.getQualifier()).bindToElement(containingClass);
if (referenceName.equals(reference.getReferenceName()) && !(reference instanceof PsiMethodReferenceExpression)) {
final PsiElement qualifierExpression = reference.getQualifier();
PsiElement referent = reference.getUserData(TEMP_REFERENT_USER_DATA);
if (!reference.isQualified()) {
if (referent instanceof PsiMember && referent != reference.resolve()) {
PsiElementFactory factory = JavaPsiFacade.getInstance(reference.getProject()).getElementFactory();
try {
final PsiClass containingClass = ((PsiMember)referent).getContainingClass();
if (containingClass != null) {
PsiReferenceExpression copy = (PsiReferenceExpression)factory.createExpressionFromText("A." + reference.getReferenceName(), null);
reference = (PsiReferenceExpression)reference.replace(copy);
((PsiReferenceExpression)reference.getQualifier()).bindToElement(containingClass);
}
}
catch (IncorrectOperationException e) {
LOG.error (e);
}
}
catch (IncorrectOperationException e) {
LOG.error (e);
reference.putUserData(TEMP_REFERENT_USER_DATA, null);
} else {
if (qualifierExpression instanceof PsiJavaCodeReferenceElement) {
PsiElement aClass = ((PsiJavaCodeReferenceElement)qualifierExpression).resolve();
if (aClass instanceof PsiVariable) {
aClass = PsiUtil.resolveClassInClassTypeOnly(((PsiVariable)aClass).getType());
}
if (aClass instanceof PsiClass && InheritanceUtil.isInheritorOrSelf((PsiClass)aClass, resolvedClass, true)) {
boolean foundMemberByName = false;
if (referent instanceof PsiMember) {
final String memberName = ((PsiMember)referent).getName();
final PsiClass containingClass = PsiTreeUtil.getParentOfType(reference, PsiClass.class);
if (containingClass != null) {
foundMemberByName |= containingClass.findFieldByName(memberName, true) != null;
foundMemberByName |= containingClass.findMethodsByName(memberName, true).length > 0;
}
}
if (!foundMemberByName) {
try {
qualifierExpression.delete();
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
}
}
}
reference.putUserData(TEMP_REFERENT_USER_DATA, null);
} else {
if (qualifierExpression instanceof PsiJavaCodeReferenceElement) {
PsiElement aClass = ((PsiJavaCodeReferenceElement)qualifierExpression).resolve();
if (aClass instanceof PsiVariable) {
aClass = PsiUtil.resolveClassInClassTypeOnly(((PsiVariable)aClass).getType());
}
if (aClass instanceof PsiClass && InheritanceUtil.isInheritorOrSelf((PsiClass)aClass, resolvedClass, true)) {
boolean foundMemberByName = false;
if (referent instanceof PsiMember) {
final String memberName = ((PsiMember)referent).getName();
final PsiClass containingClass = PsiTreeUtil.getParentOfType(reference, PsiClass.class);
if (containingClass != null) {
foundMemberByName |= containingClass.findFieldByName(memberName, true) != null;
foundMemberByName |= containingClass.findMethodsByName(memberName, true).length > 0;
}
}
if (!foundMemberByName) {
try {
qualifierExpression.delete();
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
}
}
}
reference.putUserData(TEMP_REFERENT_USER_DATA, null);
}
super.visitReferenceElement(reference);
finally {
super.visitReferenceElement(reference);
}
}
});
}
@@ -18,6 +18,7 @@ package com.intellij.refactoring.safeDelete.usageInfo;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.IncorrectOperationException;
/**
@@ -50,15 +51,19 @@ public class SafeDeleteExtendsClassUsageInfo extends SafeDeleteReferenceUsageInf
if (extendsList != null) {
final PsiClassType[] referenceTypes = extendsList.getReferencedTypes();
final PsiReferenceList listToAddExtends = refClass.isInterface() == myExtendingClass.isInterface() ? myExtendingClass.getExtendsList() : extendingImplementsList;
final PsiClassType[] existingRefTypes = listToAddExtends.getReferencedTypes();
for (PsiClassType referenceType : referenceTypes) {
if (ArrayUtilRt.find(existingRefTypes, referenceType) > -1) continue;
listToAddExtends.add(elementFactory.createReferenceElementByType((PsiClassType)mySubstitutor.substitute(referenceType)));
}
}
final PsiReferenceList implementsList = refClass.getImplementsList();
if (implementsList != null) {
final PsiClassType[] referenceTypes = implementsList.getReferencedTypes();
final PsiClassType[] existingRefTypes = extendingImplementsList.getReferencedTypes();
PsiClassType[] referenceTypes = implementsList.getReferencedTypes();
for (PsiClassType referenceType : referenceTypes) {
if (ArrayUtilRt.find(existingRefTypes, referenceType) > -1) continue;
extendingImplementsList.add(elementFactory.createReferenceElementByType((PsiClassType)mySubstitutor.substitute(referenceType)));
}
}
@@ -184,4 +184,59 @@ public class PsiTypesUtil {
}
return null;
}
@Nullable
public static PsiType getExpectedTypeByParent(PsiExpression methodCall) {
final PsiElement parent = PsiUtil.skipParenthesizedExprUp(methodCall.getParent());
if (parent instanceof PsiVariable) {
if (checkSameExpression(methodCall, ((PsiVariable)parent).getInitializer())) {
return ((PsiVariable)parent).getType();
}
}
else if (parent instanceof PsiAssignmentExpression) {
if (checkSameExpression(methodCall, ((PsiAssignmentExpression)parent).getRExpression())) {
return ((PsiAssignmentExpression)parent).getLExpression().getType();
}
}
else if (parent instanceof PsiIfStatement) {
if (checkSameExpression(methodCall, ((PsiIfStatement)parent).getCondition())) {
return PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiWhileStatement) {
if (checkSameExpression(methodCall, ((PsiWhileStatement)parent).getCondition())) {
return PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiForStatement) {
if (checkSameExpression(methodCall, ((PsiForStatement)parent).getCondition())) {
return PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiDoWhileStatement) {
if (checkSameExpression(methodCall, ((PsiDoWhileStatement)parent).getCondition())) {
return PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiTypeCastExpression) {
return ((PsiTypeCastExpression)parent).getType();
}
else if (parent instanceof PsiReturnStatement) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class);
if (lambdaExpression != null) {
return LambdaUtil.getFunctionalInterfaceReturnType(lambdaExpression.getFunctionalInterfaceType());
}
else {
PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class);
if (method != null) {
return method.getReturnType();
}
}
}
return null;
}
private static boolean checkSameExpression(PsiExpression templateExpr, final PsiExpression expression) {
return templateExpr.equals(PsiUtil.skipParenthesizedExprDown(expression));
}
}
@@ -466,7 +466,8 @@ public final class PsiUtil extends PsiUtilCore {
final PsiParameter[] parms = method.getParameterList().getParameters();
if (args.length < parms.length - 1) return ApplicabilityLevel.NOT_APPLICABLE;
final boolean isRaw = isRawSubstitutor(method, substitutorForMethod);
final PsiClass containingClass = method.getContainingClass();
final boolean isRaw = containingClass != null && isRawSubstitutor(containingClass, substitutorForMethod);
if (!areFirstArgumentsApplicable(args, parms, languageLevel, substitutorForMethod, isRaw)) return ApplicabilityLevel.NOT_APPLICABLE;
if (args.length == parms.length) {
if (parms.length == 0) return ApplicabilityLevel.FIXED_ARITY;
@@ -16,11 +16,13 @@
package com.intellij.psi.impl.source;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.impl.source.tree.CompositePsiElement;
import com.intellij.psi.impl.source.tree.ElementType;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
@@ -36,8 +38,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeElement {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiTypeElementImpl");
private volatile PsiType myCachedType = null;
@SuppressWarnings({"UnusedDeclaration"})
@@ -120,22 +120,16 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
if (PsiUtil.isJavaToken(child, JavaTokenType.QUEST)) {
assert type == null : this;
PsiElement next = PsiTreeUtil.skipSiblingsForward(child, PsiComment.class, PsiWhiteSpace.class);
if (next == null) {
type = PsiWildcardType.createUnbounded(getManager());
PsiElement boundKind = PsiTreeUtil.skipSiblingsForward(child, PsiComment.class, PsiWhiteSpace.class);
PsiElement boundType = PsiTreeUtil.skipSiblingsForward(boundKind, PsiComment.class, PsiWhiteSpace.class);
if (PsiUtil.isJavaToken(boundKind, JavaTokenType.EXTENDS_KEYWORD) && boundType instanceof PsiTypeElement) {
type = PsiWildcardType.createExtends(getManager(), ((PsiTypeElement)boundType).getType());
}
else if (PsiUtil.isJavaToken(boundKind, JavaTokenType.SUPER_KEYWORD) && boundType instanceof PsiTypeElement) {
type = PsiWildcardType.createSuper(getManager(), ((PsiTypeElement)boundType).getType());
}
else {
PsiElement bound = PsiTreeUtil.skipSiblingsForward(next, PsiComment.class, PsiWhiteSpace.class);
if (PsiUtil.isJavaToken(next, JavaTokenType.EXTENDS_KEYWORD) && bound instanceof PsiTypeElement) {
type = PsiWildcardType.createExtends(getManager(), ((PsiTypeElement)bound).getType());
}
else if (PsiUtil.isJavaToken(next, JavaTokenType.SUPER_KEYWORD) && bound instanceof PsiTypeElement) {
type = PsiWildcardType.createSuper(getManager(), ((PsiTypeElement)bound).getType());
}
else {
LOG.error("next=" + next + " bound=" + bound + ": " + this);
type = PsiWildcardType.createUnbounded(getManager());
}
type = PsiWildcardType.createUnbounded(getManager());
}
PsiAnnotation[] array = ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true);
type = ((PsiWildcardType)type).annotate(array);
@@ -34,10 +34,7 @@ import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
import com.intellij.psi.scope.processor.MethodResolverProcessor;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.psi.util.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashMap;
@@ -1015,88 +1012,50 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
PsiSubstitutor substitutor,
ParameterTypeInferencePolicy policy) {
Pair<PsiType, ConstraintType> constraint = null;
PsiType expectedType = null;
PsiType expectedType = PsiTypesUtil.getExpectedTypeByParent(methodCall);
if (parent instanceof PsiVariable) {
if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(((PsiVariable)parent).getInitializer()))) {
expectedType = ((PsiVariable)parent).getType();
}
}
else if (parent instanceof PsiAssignmentExpression) {
if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(((PsiAssignmentExpression)parent).getRExpression()))) {
expectedType = ((PsiAssignmentExpression)parent).getLExpression().getType();
}
}
else if (parent instanceof PsiIfStatement) {
if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(((PsiIfStatement)parent).getCondition()))) {
expectedType = PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiWhileStatement) {
if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(((PsiWhileStatement)parent).getCondition()))) {
expectedType = PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiForStatement) {
if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(((PsiForStatement)parent).getCondition()))) {
expectedType = PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiDoWhileStatement) {
if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(((PsiDoWhileStatement)parent).getCondition()))) {
expectedType = PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiReturnStatement) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class);
if (lambdaExpression != null) {
expectedType = LambdaUtil.getFunctionalInterfaceReturnType(lambdaExpression.getFunctionalInterfaceType());
if (expectedType == null) {
if (expectedType == null) {
if (parent instanceof PsiReturnStatement) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class);
if (lambdaExpression != null) {
return getFailedInferenceConstraint(typeParameter);
}
} else {
PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class);
if (method != null) {
expectedType = method.getReturnType();
}
}
}
else if (parent instanceof PsiExpressionList) {
final PsiElement pParent = parent.getParent();
if (pParent instanceof PsiCallExpression && parent.equals(((PsiCallExpression)pParent).getArgumentList())) {
constraint = policy.inferTypeConstraintFromCallContext(methodCall, (PsiExpressionList)parent, (PsiCallExpression)pParent, typeParameter);
if (constraint == null && PsiUtil.isLanguageLevel8OrHigher(methodCall)) {
constraint = graphInferenceFromCallContext(methodCall, typeParameter, (PsiCallExpression)pParent);
if (constraint != null) {
final PsiType constraintFirst = constraint.getFirst();
if (constraintFirst == null || constraintFirst.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
constraint = null;
else if (parent instanceof PsiExpressionList) {
final PsiElement pParent = parent.getParent();
if (pParent instanceof PsiCallExpression && parent.equals(((PsiCallExpression)pParent).getArgumentList())) {
constraint = policy.inferTypeConstraintFromCallContext(methodCall, (PsiExpressionList)parent, (PsiCallExpression)pParent, typeParameter);
if (constraint == null && PsiUtil.isLanguageLevel8OrHigher(methodCall)) {
constraint = graphInferenceFromCallContext(methodCall, typeParameter, (PsiCallExpression)pParent);
if (constraint != null) {
final PsiType constraintFirst = constraint.getFirst();
if (constraintFirst == null || constraintFirst.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
constraint = null;
}
}
}
}
}
} else if (parent instanceof PsiLambdaExpression) {
expectedType = ourGraphGuard.doPreventingRecursion(methodCall, true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return LambdaUtil.getFunctionalInterfaceReturnType(((PsiLambdaExpression)parent).getFunctionalInterfaceType());
}
});
if (expectedType == null) {
return null;
}
} else if (parent instanceof PsiTypeCastExpression) {
expectedType = ((PsiTypeCastExpression)parent).getType();
} else if (parent instanceof PsiConditionalExpression) {
if (PsiUtil.isLanguageLevel8OrHigher(parent)) {
try {
final Pair<PsiType, ConstraintType> pair = inferFromConditionalExpression(parent, methodCall, typeParameter, substitutor, policy);
if (pair != null) {
return pair;
} else if (parent instanceof PsiLambdaExpression) {
expectedType = ourGraphGuard.doPreventingRecursion(methodCall, true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return LambdaUtil.getFunctionalInterfaceReturnType(((PsiLambdaExpression)parent).getFunctionalInterfaceType());
}
});
if (expectedType == null) {
return null;
}
finally {
GraphInferencePolicy.forget(parent);
} else if (parent instanceof PsiConditionalExpression) {
if (PsiUtil.isLanguageLevel8OrHigher(parent)) {
try {
final Pair<PsiType, ConstraintType> pair = inferFromConditionalExpression(parent, methodCall, typeParameter, substitutor, policy);
if (pair != null) {
return pair;
}
}
finally {
GraphInferencePolicy.forget(parent);
}
}
}
}
@@ -1196,6 +1155,10 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
return result;
}
private static boolean checkSameExpression(PsiExpression templateExpr, final PsiExpression expression) {
return templateExpr.equals(PsiUtil.skipParenthesizedExprDown(expression));
}
private static Pair<PsiType, ConstraintType> inferExceptionConstrains(PsiTypeParameter typeParameter,
PsiExpression expression,
PsiMethod method,
@@ -15,3 +15,10 @@ class R {
System.out.println(<error descr="'Z' is not an enclosing class">Z.super</error>.toString());
}
}
class W {
static String some = "";
static void m() {
synchronized (<error descr="Class name expected here">some</error>.this) { }
}
}
@@ -0,0 +1,17 @@
import java.util.Collection;
import java.util.Set;
class FooObject<T> {}
class FooId<T extends FooObject> {}
interface Bar {
<T extends FooObject, I extends FooId<? extends T>> T get(I key);
<T extends FooObject, I extends FooId<? extends T>> Collection<T> get(Collection<I> keys);
}
public class Target {
void foo(Bar bar) {
final Set<FooId<?>> keys = null;
final Collection<FooObject> values = bar.get(keys);
}
}
@@ -0,0 +1,6 @@
import foo.*;
class Class2 {
public static void main(String[] args) {
Class1.<String>f<caret>oo();
}
}
@@ -0,0 +1,6 @@
import foo.*;
class Class2 {
public static void main(String[] args) {
new Class1.Inn<caret>er2<Class1.Inner1>();
}
}
@@ -0,0 +1,6 @@
import foo.*;
class Class2 {
public static void main(String[] args) {
new Class1.Inner2<Class1.In<caret>ner1>();
}
}
@@ -0,0 +1,9 @@
import foo.*;
import static foo.Class1.Inner1;
class Class2 {
public static void main(String[] args) {
new Class1.Inner2<Inner1>();
}
}
@@ -0,0 +1,9 @@
import foo.*;
import static foo.Class1.Inner2;
class Class2 {
public static void main(String[] args) {
new Inner2<Class1.Inner1>();
}
}
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>Test.java</file>
<line>8</line>
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Redundant type cast</problem_class>
<description>Casting &lt;code&gt;2&lt;/code&gt; to &lt;code&gt;Integer&lt;/code&gt; is redundant</description>
</problem>
</problems>
@@ -0,0 +1,10 @@
//This is a test for JDK_15 LanguageLevel
public class Test {
private Integer foo(String s, Integer i) {
return s == null ? i : (Integer)2;
}
private int foo1(String s, Integer i) {
return s == null ? i : (Integer)2;
}
}
@@ -0,0 +1,3 @@
nterface Foo {}
interface Ba<caret>r extends Foo {}
class FooBarImpl implements Foo, Bar {}
@@ -0,0 +1,3 @@
nterface Foo {}
class FooBarImpl implements Foo {}
@@ -207,6 +207,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testIDEA103760(){ doTest5(false); }
public void testIDEA105846(){ doTest5(false); }
public void testIDEA105695(){ doTest5(false); }
public void testIDEA104992(){ doTest5(false); }
public void testWildcardsOnRawTypes() { doTest5(false); }
public void testDisableWithinBoundsCheckForSuperWildcards() {
@@ -28,24 +28,19 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
/**
* This class is for "lightweight" tests only, i.e. those which can run inside default light project set up
* For "heavyweight" tests use AdvHighlightingTest
* This class is for "lightweight" tests only, i.e. those which can run inside default light project set up.
* For "heavyweight" tests use AdvHighlightingTest.
*/
public class LightAdvHighlightingJdk6Test extends LightDaemonAnalyzerTestCase {
@NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/advHighlighting6";
private void doTest(boolean checkWarnings, boolean checkInfos, Class<?>... classes) {
setLanguageLevel(LanguageLevel.JDK_1_6);
setLanguageLevel(LanguageLevel.JDK_1_6);
((JavaVersionServiceImpl)JavaVersionService.getInstance()).setTestVersion(JavaSdkVersion.JDK_1_6, myTestRootDisposable);
enableInspectionTools(classes);
doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkInfos);
}
private void doTest(boolean checkWarnings, boolean checkWeakWarnings, boolean checkInfos, Class<?>... classes) {
enableInspectionTools(classes);
doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkWeakWarnings, checkInfos);
}
@NotNull
@Override
protected LocalInspectionTool[] configureLocalInspectionTools() {
@@ -57,6 +52,6 @@ public class LightAdvHighlightingJdk6Test extends LightDaemonAnalyzerTestCase {
};
}
public void testJavacQuirks() throws Exception { setLanguageLevel(LanguageLevel.JDK_1_6); doTest(true, false); }
public void testMethodReturnTypeSubstitutability() throws Exception { setLanguageLevel(LanguageLevel.JDK_1_6); doTest(true, false); }
public void testJavacQuirks() { setLanguageLevel(LanguageLevel.JDK_1_6); doTest(true, false); }
public void testMethodReturnTypeSubstitutability() { setLanguageLevel(LanguageLevel.JDK_1_6); doTest(true, false); }
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2013 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.
@@ -241,7 +241,7 @@ public class LightAdvHighlightingTest extends LightDaemonAnalyzerTestCase {
};
point.registerExtension(extension);
try {
UnusedDeclarationInspection deadCodeInspection = new UnusedDeclarationInspection();
enableInspectionTool(deadCodeInspection);
@@ -30,6 +30,45 @@ public class AddSingleStaticImportActionTest extends JavaCodeInsightFixtureTestC
myFixture.checkResultByFile(getTestName(false) + "_after.java");
}
public void testInsideParameterizedReference() {
myFixture.addClass("package foo; " +
"public class Class1 {" +
" public static class Inner1 {}\n" +
" public static class Inner2<T> {}" +
"}");
myFixture.configureByFile(getTestName(false) + ".java");
final IntentionAction intentionAction = myFixture.findSingleIntention("Add static import for 'foo.Class1.Inner2'");
assertNotNull(intentionAction);
myFixture.launchAction(intentionAction);
myFixture.checkResultByFile(getTestName(false) + "_after.java");
}
public void testInsideParameterizedReferenceInsideParameterizedReference() {
myFixture.addClass("package foo; " +
"public class Class1 {" +
" public static class Inner1 {}\n" +
" public static class Inner2<T> {}" +
"}");
myFixture.configureByFile(getTestName(false) + ".java");
final IntentionAction intentionAction = myFixture.findSingleIntention("Add static import for 'foo.Class1.Inner1'");
assertNotNull(intentionAction);
myFixture.launchAction(intentionAction);
myFixture.checkResultByFile(getTestName(false) + "_after.java");
}
public void testDisabledInsideParameterizedReference() {
myFixture.addClass("package foo; " +
"public class Class1 {" +
" public static <T> T foo(){return null;}\n" +
"}");
myFixture.configureByFile(getTestName(false) + ".java");
final IntentionAction intentionAction = myFixture.getAvailableIntention("Add static import for 'foo.Class1.foo'");
assertNull(intentionAction);
}
@Override
protected String getTestDataPath() {
@@ -19,7 +19,7 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.testFramework.LightIdeaTestCase
@SuppressWarnings(["GrUnresolvedAccess"])
@SuppressWarnings(["GrUnresolvedAccess", "GroovyAssignabilityCheck"])
class AnnotatedTypeTest extends LightIdeaTestCase {
public void testTypeComposition() {
@@ -55,6 +55,9 @@ class E2 extends Exception { }
psi = javaFacade.elementFactory.createStatementFromText("@A java.lang.@TA(1) String s", context)
assertEquals("@TA(1) String", psi.declaredElements[0].type.presentableText)
psi = javaFacade.elementFactory.createStatementFromText("Collection<? extends> s", context)
assertEquals("Collection<?>", psi.declaredElements[0].type.presentableText)
}
}
@@ -24,6 +24,8 @@ public class RedundantCast15Test extends InspectionTestCase {
public void testBoxingInRef() throws Exception { doTest(); }
public void testBoxingInConditional() throws Exception { doTest(); }
public void testInference1() throws Exception { doTest(); }
public void testInference2() throws Exception { doTest(); }
@@ -65,6 +65,10 @@ public class SafeDeleteTest extends MultiFileTestCase {
doTest("IFoo");
}
public void testUsageInExtendsList() throws Exception {
doSingleFileTest();
}
public void testParameterInHierarchy() throws Exception {
myDoCompare = false;
doTest("C2");
@@ -383,7 +383,9 @@ public class RedundantCastUtil {
PsiElement parent = typeCast.getParent();
if (parent instanceof PsiConditionalExpression) {
//branches need to be of the same type
if (!Comparing.equal(operand.getType(), ((PsiConditionalExpression)parent).getType())) {
final PsiType operandType = operand.getType();
final PsiType conditionalType = ((PsiConditionalExpression)parent).getType();
if (!Comparing.equal(operandType, conditionalType)) {
if (!PsiUtil.isLanguageLevel5OrHigher(typeCast)) {
return;
}
@@ -578,6 +580,12 @@ public class RedundantCastUtil {
if (firstOperand != null && otherOperand != null && wrapperCastChangeSemantics(firstOperand, otherOperand, operand)) {
return true;
}
} else if (parent instanceof PsiConditionalExpression) {
if (opType instanceof PsiPrimitiveType && !(((PsiConditionalExpression)parent).getType() instanceof PsiPrimitiveType)) {
if (PsiPrimitiveType.getUnboxedType(PsiTypesUtil.getExpectedTypeByParent((PsiExpression)parent)) != null) {
return true;
}
}
}
return false;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -37,16 +37,16 @@ public abstract class FileIndexFacade {
return ServiceManager.getService(project, FileIndexFacade.class);
}
public abstract boolean isInContent(VirtualFile file);
public abstract boolean isInSource(VirtualFile file);
public abstract boolean isInSourceContent(VirtualFile file);
public abstract boolean isInLibraryClasses(VirtualFile file);
public abstract boolean isInContent(@NotNull VirtualFile file);
public abstract boolean isInSource(@NotNull VirtualFile file);
public abstract boolean isInSourceContent(@NotNull VirtualFile file);
public abstract boolean isInLibraryClasses(@NotNull VirtualFile file);
public abstract boolean isInLibrarySource(VirtualFile file);
public abstract boolean isExcludedFile(VirtualFile file);
public abstract boolean isInLibrarySource(@NotNull VirtualFile file);
public abstract boolean isExcludedFile(@NotNull VirtualFile file);
@Nullable
public abstract Module getModuleForFile(VirtualFile file);
public abstract Module getModuleForFile(@NotNull VirtualFile file);
/**
* Checks if <code>file</code> is an ancestor of <code>baseDir</code> and none of the files
@@ -56,7 +56,7 @@ public abstract class FileIndexFacade {
* @param child the child directory or file to check for ancestry.
* @return true if it's a valid ancestor, false otherwise.
*/
public abstract boolean isValidAncestor(final VirtualFile baseDir, final VirtualFile child);
public abstract boolean isValidAncestor(@NotNull VirtualFile baseDir, @NotNull VirtualFile child);
public boolean shouldBeFound(GlobalSearchScope scope, VirtualFile virtualFile) {
return (scope.isSearchOutsideRootModel() || isInContent(virtualFile) || isInLibrarySource(virtualFile)) && !virtualFile.getFileType().isBinary();
@@ -63,7 +63,7 @@ public class MockFileIndexFacade extends FileIndexFacade {
}
@Override
public boolean isInLibrarySource(VirtualFile file) {
public boolean isInLibrarySource(@NotNull VirtualFile file) {
return false;
}
@@ -73,12 +73,12 @@ public class MockFileIndexFacade extends FileIndexFacade {
}
@Override
public Module getModuleForFile(VirtualFile file) {
public Module getModuleForFile(@NotNull VirtualFile file) {
return myModule;
}
@Override
public boolean isValidAncestor(VirtualFile baseDir, VirtualFile child) {
public boolean isValidAncestor(@NotNull VirtualFile baseDir, @NotNull VirtualFile child) {
return VfsUtilCore.isAncestor(baseDir, child, false);
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 984 B

After

Width:  |  Height:  |  Size: 667 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 461 B

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 604 B

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 624 B

After

Width:  |  Height:  |  Size: 607 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 654 B

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 637 B

After

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 928 B

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

@@ -164,7 +164,9 @@ public class JdkUtil {
commandLine.setExePath(exePath);
final ParametersList vmParametersList = javaParameters.getVMParametersList();
commandLine.setEnvironment(javaParameters.getEnv());
if (javaParameters.getEnv() != null) {
commandLine.getEnvironment().putAll(javaParameters.getEnv());
}
commandLine.setPassParentEnvironment(javaParameters.isPassParentEnvs());
final Class commandLineWrapper;
@@ -503,9 +503,6 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren
for (Tools currentTools : tools.values()) {
final InspectionTool defaultTool = (InspectionTool)currentTools.getDefaultState().getTool();
final HighlightDisplayKey key = HighlightDisplayKey.find(defaultTool.getShortName());
if (profile != null && !profile.isToolEnabled(key)) {
continue; //exclude disabled inspections from view
}
for (ScopeToolState state : currentTools.getTools()) {
final InspectionTool tool = (InspectionTool)state.getTool();
if (myProvider.checkReportedProblems(tool)) {
@@ -291,7 +291,11 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
final TextRange range = o.getPrimaryRange();
TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.TEXT_SEARCH_RESULT_ATTRIBUTES);
if (range.getLength() == 0) {
attributes = attributes.clone();
attributes.setEffectType(EffectType.BOXED);
attributes.setEffectColor(attributes.getBackgroundColor());
}
if (mySearchResults.isExcluded(o)) {
highlightRange(range, strikout(attributes), myHighlighters);
} else {
@@ -303,13 +303,16 @@ public class SearchResults implements DocumentListener {
private void findInRange(TextRange r, Editor editor, FindModel findModel, ArrayList<FindResult> results) {
VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(editor.getDocument());
CharSequence charSequence = editor.getDocument().getCharsSequence();
int offset = r.getStartOffset();
int maxOffset = Math.min(r.getEndOffset(), charSequence.length());
FindManager findManager = FindManager.getInstance(getProject());
while (true) {
FindManager findManager = FindManager.getInstance(getProject());
FindResult result;
try {
CharSequence bombedCharSequence = StringUtil.newBombedCharSequence(editor.getDocument().getCharsSequence(), 3000);
CharSequence bombedCharSequence = StringUtil.newBombedCharSequence(charSequence, 3000);
result = findManager.findString(bombedCharSequence, offset, findModel, virtualFile);
} catch(PatternSyntaxException e) {
result = null;
@@ -318,8 +321,17 @@ public class SearchResults implements DocumentListener {
}
if (result == null || !result.isStringFound()) break;
int newOffset = result.getEndOffset();
if (offset == newOffset || result.getEndOffset() > r.getEndOffset()) break;
offset = newOffset;
if (result.getEndOffset() > maxOffset) break;
if (offset == newOffset) {
if (offset < maxOffset - 1) {
offset++;
} else {
results.add(result);
break;
}
} else {
offset = newOffset;
}
results.add(result);
}
}
@@ -494,7 +506,7 @@ public class SearchResults implements DocumentListener {
private LiveOccurrence firstOccurrenceAfterOffset(int offset) {
LiveOccurrence afterCaret = null;
for (LiveOccurrence occurrence : getOccurrences()) {
if (occurrence.getPrimaryRange().getStartOffset() >= offset) {
if (occurrence.getPrimaryRange().getStartOffset() >= offset && occurrence.getPrimaryRange().getEndOffset() > offset) {
if (afterCaret == null || occurrence.getPrimaryRange().getStartOffset() < afterCaret.getPrimaryRange().getStartOffset() ) {
afterCaret = occurrence;
}
@@ -142,15 +142,16 @@ public class PsiAwareTextEditorProvider extends TextEditorProvider {
}
}
@NotNull
@Override
protected EditorWrapper createWrapperForEditor(final Editor editor) {
protected EditorWrapper createWrapperForEditor(@NotNull final Editor editor) {
return new PsiAwareEditorWrapper(editor);
}
private final class PsiAwareEditorWrapper extends EditorWrapper {
private final TextEditorBackgroundHighlighter myBackgroundHighlighter;
private PsiAwareEditorWrapper(final Editor editor) {
private PsiAwareEditorWrapper(@NotNull Editor editor) {
super(editor);
final Project project = editor.getProject();
myBackgroundHighlighter = project == null
@@ -20,6 +20,7 @@
package com.intellij.psi.stubs;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
@@ -90,12 +91,14 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
else {
final Throwable e = new Throwable();
// avoid direct forceRebuild as it produces dependency cycle (IDEA-105485)
ApplicationManager.getApplication().invokeLater(new Runnable() {
ApplicationManager.getApplication().invokeLater(
new Runnable() {
@Override
public void run() {
forceRebuild(e);
}
});
}, ModalityState.NON_MODAL
);
}
}
dropUnregisteredIndices();
@@ -48,7 +48,7 @@ public class GeneralCommandLine implements UserDataHolder {
private String myExePath = null;
private File myWorkDirectory = null;
private Map<String, String> myEnvParams = null;
private final Map<String, String> myEnvParams = ContainerUtil.newTroveMap();
private boolean myPassParentEnvironment = true;
private final ParametersList myProgramParams = new ParametersList();
private Charset myCharset = CharsetToolkit.getDefaultSystemCharset();
@@ -93,40 +93,22 @@ public class GeneralCommandLine implements UserDataHolder {
@NotNull
public Map<String, String> getEnvironment() {
return myEnvParams != null ? Collections.unmodifiableMap(myEnvParams) : Collections.<String, String>emptyMap();
return myEnvParams;
}
/** @deprecated use {@link #getEnvironment()} (to remove in IDEA 14) */
@SuppressWarnings("unused")
public Map<String, String> getEnvParams() {
return myEnvParams;
return getEnvironment();
}
public void setEnvironment(@Nullable Map<String, String> envVars) {
if (envVars != null) {
if (myEnvParams == null) myEnvParams = ContainerUtil.newHashMap();
myEnvParams.putAll(envVars);
}
}
public void setEnvironment(@NotNull String name, @NotNull String value) {
if (myEnvParams == null) myEnvParams = ContainerUtil.newHashMap();
myEnvParams.put(name, value);
}
public void removeEnvironment(@NotNull String name) {
if (myEnvParams != null) {
myEnvParams.remove(name);
if (myEnvParams.isEmpty()) {
myEnvParams = null;
}
}
}
/** @deprecated use {@link #setEnvironment(Map)} (to remove in IDEA 14) */
/** @deprecated use {@link #getEnvironment()} (to remove in IDEA 14) */
@SuppressWarnings("unused")
public void setEnvParams(@Nullable final Map<String, String> envParams) {
myEnvParams = envParams;
public void setEnvParams(@Nullable Map<String, String> envParams) {
myEnvParams.clear();
if (envParams != null) {
myEnvParams.putAll(envParams);
}
}
public void setPassParentEnvironment(boolean passParentEnvironment) {
@@ -271,7 +253,7 @@ public class GeneralCommandLine implements UserDataHolder {
environment.clear();
}
if (myEnvParams != null && !myEnvParams.isEmpty()) {
if (!myEnvParams.isEmpty()) {
if (SystemInfo.isWindows) {
THashMap<String, String> envVars = new THashMap<String, String>(CaseInsensitiveStringHashingStrategy.INSTANCE);
envVars.putAll(environment);
@@ -15,26 +15,29 @@
*/
package com.intellij.openapi.diff;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
abstract class DocumentsSynchonizer {
abstract class DocumentsSynchronizer {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.DocumentsSynchonizer");
private Document myOriginal = null;
private Document myCopy = null;
private final Project myProject;
private boolean myDuringModification = false;
private volatile boolean myDuringModification = false;
private int myAssignedCount = 0;
private final DocumentAdapter myOriginalListener = new DocumentAdapter() {
@Override
public void documentChanged(DocumentEvent e) {
if (myDuringModification) return;
onOriginalChanged(e, getCopy());
@@ -42,39 +45,47 @@ abstract class DocumentsSynchonizer {
};
private final DocumentAdapter myCopyListener = new DocumentAdapter() {
@Override
public void documentChanged(DocumentEvent e) {
if (myDuringModification) return;
onCopyChanged(e, getOriginal());
}
};
private final PropertyChangeListener myROListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (Document.PROP_WRITABLE.equals(evt.getPropertyName())) getCopy().setReadOnly(!getOriginal().isWritable());
}
};
protected DocumentsSynchonizer(Project project) {
protected DocumentsSynchronizer(Project project) {
myProject = project;
}
protected abstract void onCopyChanged(DocumentEvent event, Document original);
protected abstract void onCopyChanged(@NotNull DocumentEvent event, @NotNull Document original);
protected abstract void onOriginalChanged(DocumentEvent event, Document copy);
protected abstract void onOriginalChanged(@NotNull DocumentEvent event, @NotNull Document copy);
protected abstract void beforeListenersAttached(Document original, Document copy);
protected abstract void beforeListenersAttached(@NotNull Document original, @NotNull Document copy);
protected abstract Document createOriginal();
protected abstract Document createCopy();
protected void replaceString(final Document document, final int startOffset, final int endOffset, final String newText) {
protected void replaceString(@NotNull final Document document, final int startOffset, final int endOffset, @NotNull final String newText) {
LOG.assertTrue(!myDuringModification);
try {
myDuringModification = true;
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
@Override
public void run() {
LOG.assertTrue(endOffset <= document.getTextLength());
document.replaceString(startOffset, endOffset, newText);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
document.replaceString(startOffset, endOffset, newText);
}
});
}
}, DiffBundle.message("save.merge.result.command.name"), document);
}
@@ -23,11 +23,11 @@ import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
@@ -39,19 +39,16 @@ public class FragmentContent extends DiffContent {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.FragmentContent");
private final DiffContent myOriginal;
private final FileType myType;
private final MyDocumentsSynchonizer mySynchonizer;
private final MyDocumentsSynchronizer mySynchonizer;
public static final Key<Document> ORIGINAL_DOCUMENT = new Key<Document>("ORIGINAL_DOCUMENT");
public FragmentContent(DiffContent original, TextRange range, Project project, VirtualFile file) {
public FragmentContent(@NotNull DiffContent original, @NotNull TextRange range, Project project, VirtualFile file) {
this(original, range, project, file != null ? DiffContentUtil.getContentType(file) : null);
}
public FragmentContent(DiffContent original, TextRange range, Project project, FileType type) {
this(original.getDocument().createRangeMarker(range.getStartOffset(), range.getEndOffset(), true), original, type, project);
}
private FragmentContent(RangeMarker rangeMarker, DiffContent original, FileType fileType, Project project) {
mySynchonizer = new MyDocumentsSynchonizer(project, rangeMarker);
public FragmentContent(@NotNull DiffContent original, @NotNull TextRange range, Project project, FileType fileType) {
RangeMarker rangeMarker = original.getDocument().createRangeMarker(range.getStartOffset(), range.getEndOffset(), true);
mySynchonizer = new MyDocumentsSynchronizer(project, rangeMarker);
myOriginal = original;
myType = fileType;
}
@@ -65,27 +62,35 @@ public class FragmentContent extends DiffContent {
}
@Override
public void onAssigned(boolean isAssigned) {
myOriginal.onAssigned(isAssigned);
mySynchonizer.listenDocuments(isAssigned);
super.onAssigned(isAssigned);
}
@Override
public Document getDocument() {
return mySynchonizer.getCopy();
}
@Override
public OpenFileDescriptor getOpenFileDescriptor(int offset) {
return myOriginal.getOpenFileDescriptor(offset + mySynchonizer.getStartOffset());
}
public VirtualFile getFile() { return null; }
@Override
public VirtualFile getFile() {
return null;
}
@Override
@Nullable
public FileType getContentType() {
return myType != null ? myType : myOriginal.getContentType();
}
@Override
public byte[] getBytes() throws IOException {
return getDocument().getText().getBytes();
}
@@ -97,52 +102,59 @@ public class FragmentContent extends DiffContent {
return new FragmentContent(new DocumentContent(project, document), TextRange.create(rangeMarker), project, type);
}
private class MyDocumentsSynchonizer extends DocumentsSynchonizer {
private class MyDocumentsSynchronizer extends DocumentsSynchronizer {
private final RangeMarker myRangeMarker;
public MyDocumentsSynchonizer(Project project, RangeMarker originalRange) {
public MyDocumentsSynchronizer(Project project, @NotNull RangeMarker originalRange) {
super(project);
myRangeMarker = originalRange;
}
public int getStartOffset() { return myRangeMarker.getStartOffset(); }
public int getStartOffset() {
return myRangeMarker.getStartOffset();
}
protected void onOriginalChanged(DocumentEvent event, Document copy) {
@Override
protected void onOriginalChanged(@NotNull DocumentEvent event, @NotNull Document copy) {
if (!myRangeMarker.isValid()) {
fireContentInvalid();
return;
}
replaceString(copy, 0, copy.getTextLength(),
subText(event.getDocument(), myRangeMarker.getStartOffset(), getLength()));
replaceString(copy, 0, copy.getTextLength(), subText(event.getDocument(), myRangeMarker.getStartOffset(), getLength()));
}
protected void beforeListenersAttached(Document original, Document copy) {
@Override
protected void beforeListenersAttached(@NotNull Document original, @NotNull Document copy) {
boolean writable = copy.isWritable();
Document copyEx = copy;
if (!writable) copyEx.setReadOnly(false);
replaceString(copy, 0, copy.getTextLength(),
subText(original, myRangeMarker.getStartOffset(), getLength()));
copyEx.setReadOnly(!writable);
if (!writable) {
copy.setReadOnly(false);
}
replaceString(copy, 0, copy.getTextLength(), subText(original, myRangeMarker.getStartOffset(), getLength()));
copy.setReadOnly(!writable);
}
private int getLength() {
return myRangeMarker.getEndOffset() - myRangeMarker.getStartOffset();
}
@Override
protected Document createOriginal() {
return myRangeMarker.getDocument();
}
@Override
protected Document createCopy() {
final Document originalDocument = myRangeMarker.getDocument();
String textInRange = originalDocument.getCharsSequence().subSequence(myRangeMarker.getStartOffset(), myRangeMarker.getEndOffset()).toString();
String textInRange =
originalDocument.getCharsSequence().subSequence(myRangeMarker.getStartOffset(), myRangeMarker.getEndOffset()).toString();
final Document result = EditorFactory.getInstance().createDocument(textInRange);
result.setReadOnly(!originalDocument.isWritable());
result.putUserData(ORIGINAL_DOCUMENT, originalDocument);
return result;
}
protected void onCopyChanged(DocumentEvent event, Document original) {
@Override
protected void onCopyChanged(@NotNull DocumentEvent event, @NotNull Document original) {
final int originalOffset = event.getOffset() + myRangeMarker.getStartOffset();
LOG.assertTrue(originalOffset >= 0);
if (!original.isWritable()) return;
@@ -186,7 +186,7 @@ public class StartupUtil {
try {
String shell = System.getenv("SHELL");
if (shell != null && new File(shell).canExecute()) {
String[] command = {shell, "-l", "-c", "/usr/bin/printenv -0"};
String[] command = {shell, "-l", "-c", "/usr/bin/printenv"};
Process process = Runtime.getRuntime().exec(command);
InputStream input = process.getInputStream();
@@ -194,7 +194,7 @@ public class StartupUtil {
ByteArrayOutputStream lineBuf = new ByteArrayOutputStream();
int b;
while ((b = input.read()) >= 0) {
if (b != 0) {
if (b != '\n') {
lineBuf.write(b);
}
else {
@@ -197,9 +197,11 @@ public class UiInspectorAction extends ToggleAction implements DumbAware {
}
private void switchInfo(Component c) {
myInspectorTable = new InspectorTable(c);
myWrapperPanel.removeAll();
myWrapperPanel.add(myInspectorTable, BorderLayout.CENTER);
if (c != null) {
myInspectorTable = new InspectorTable(c);
myWrapperPanel.add(myInspectorTable, BorderLayout.CENTER);
}
myWrapperPanel.revalidate();
myWrapperPanel.repaint();
}
@@ -319,6 +321,10 @@ public class UiInspectorAction extends ToggleAction implements DumbAware {
@Override
public void valueChanged(TreeSelectionEvent e) {
TreePath path = e.getNewLeadSelectionPath();
if (path == null) {
onComponentChanged(null);
return;
}
Object component = path.getLastPathComponent();
if (component instanceof ComponentNode) {
Component c = ((ComponentNode)component).getOwnComponent();
@@ -411,12 +417,14 @@ public class UiInspectorAction extends ToggleAction implements DumbAware {
}
private static class InspectorTable extends JPanel {
private JLabel myTitleLabel;
private InspectorTableModel myModel;
private DimensionsComponent myDimensionComponent;
private InspectorTable(@NotNull final Component component) {
setLayout(new BorderLayout());
myTitleLabel = new JLabel(component.getClass().getCanonicalName(), SwingConstants.CENTER);
myModel = new InspectorTableModel(component);
final StripeTable table = new StripeTable(myModel);
@@ -433,6 +441,7 @@ public class UiInspectorAction extends ToggleAction implements DumbAware {
table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
add(myTitleLabel, BorderLayout.NORTH);
add(new JBScrollPane(table), BorderLayout.CENTER);
myDimensionComponent = new DimensionsComponent(component);
add(myDimensionComponent, BorderLayout.SOUTH);
@@ -301,7 +301,7 @@ public class EditorUtil {
boolean useOptimization = true;
boolean hasNonTabs = false;
boolean hasTabs = false;
int scanEndOffset = Math.min(end, start + columnNumber - currentColumn[0]);
int scanEndOffset = Math.min(end, start + columnNumber - currentColumn[0] + 1);
for (int i = start; i < scanEndOffset; i++) {
char c = text.charAt(i);
if (debugBuffer != null) {
@@ -847,7 +847,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
}
// Restore selected editor
final FileEditorProvider selectedProvider = getSelectedFileEditorProvider(editorHistoryManager, file);
final FileEditorProvider selectedProvider = entry == null ? getSelectedFileEditorProvider(editorHistoryManager, file) : entry.mySelectedProvider;
if (selectedProvider != null) {
final FileEditor[] _editors = newSelectedComposite.getEditors();
final FileEditorProvider[] _providers = newSelectedComposite.getProviders();
@@ -25,14 +25,18 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.containers.HashMap;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Map;
final class HistoryEntry{
@NonNls public static final String TAG = "entry";
static final String TAG = "entry";
private static final String FILE_ATTR = "file";
private static final String PROVIDER_ELEMENT = "provider";
private static final String EDITOR_TYPE_ID_ATTR = "editor-type-id";
private static final String SELECTED_ATTR_VALUE = "selected";
private static final String STATE_ELEMENT = "state";
public final VirtualFile myFile;
/**
@@ -40,11 +44,6 @@ final class HistoryEntry{
*/
public FileEditorProvider mySelectedProvider;
private final HashMap<FileEditorProvider, FileEditorState> myProvider2State;
@NonNls public static final String FILE_ATTR = "file";
@NonNls public static final String PROVIDER_ATTR = "provider";
@NonNls public static final String EDITOR_TYPE_ID_ATTR = "editor-type-id";
@NonNls public static final String SELECTED_ATTR_VALUE = "selected";
@NonNls public static final String STATE_ELEMENT = "state";
public HistoryEntry(@NotNull VirtualFile file, @NotNull FileEditorProvider[] providers, @NotNull FileEditorState[] states, @NotNull FileEditorProvider selectedProvider){
myFile = file;
@@ -78,7 +77,7 @@ final class HistoryEntry{
FileDocumentManager.getInstance().getDocument(myFile);
}
List providers = e.getChildren(PROVIDER_ATTR);
List providers = e.getChildren(PROVIDER_ELEMENT);
for (final Object provider1 : providers) {
Element _e = (Element)provider1;
@@ -121,7 +120,7 @@ final class HistoryEntry{
for (final Map.Entry<FileEditorProvider, FileEditorState> entry : myProvider2State.entrySet()) {
FileEditorProvider provider = entry.getKey();
Element providerElement = new Element(PROVIDER_ATTR);
Element providerElement = new Element(PROVIDER_ELEMENT);
if (provider.equals(mySelectedProvider)) {
providerElement.setAttribute(SELECTED_ATTR_VALUE, Boolean.TRUE.toString());
}
@@ -65,6 +65,7 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
return ApplicationManager.getApplication().getComponent(TextEditorProvider.class);
}
@Override
public boolean accept(@NotNull Project project, @NotNull VirtualFile file) {
if (file.isDirectory() || !file.isValid()) {
return false;
@@ -77,16 +78,19 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
return !ft.isBinary() || BinaryFileTypeDecompilers.INSTANCE.forFileType(ft) != null;
}
@Override
@NotNull
public FileEditor createEditor(@NotNull Project project, @NotNull final VirtualFile file) {
LOG.assertTrue(accept(project, file));
return new TextEditorImpl(project, file, this);
}
@Override
public void disposeEditor(@NotNull FileEditor editor) {
Disposer.dispose(editor);
}
@Override
@NotNull
public FileEditorState readState(@NotNull Element element, @NotNull Project project, @NotNull VirtualFile file) {
TextEditorState state = new TextEditorState();
@@ -104,6 +108,7 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
return state;
}
@Override
public void writeState(@NotNull FileEditorState _state, @NotNull Project project, @NotNull Element element) {
TextEditorState state = (TextEditorState)_state;
@@ -114,11 +119,13 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
element.setAttribute(VERTICAL_SCROLL_PROPORTION_ATTR, Float.toString(state.VERTICAL_SCROLL_PROPORTION));
}
@Override
@NotNull
public String getEditorTypeId() {
return TYPE_ID;
}
@Override
@NotNull
public FileEditorPolicy getPolicy() {
return FileEditorPolicy.NONE;
@@ -135,7 +142,8 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
return textEditor;
}
protected EditorWrapper createWrapperForEditor(final Editor editor) {
@NotNull
protected EditorWrapper createWrapperForEditor(@NotNull Editor editor) {
return new EditorWrapper(editor);
}
@@ -210,77 +218,95 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
protected class EditorWrapper extends UserDataHolderBase implements TextEditor {
private final Editor myEditor;
public EditorWrapper(Editor editor) {
public EditorWrapper(@NotNull Editor editor) {
myEditor = editor;
}
@Override
@NotNull
public Editor getEditor() {
return myEditor;
}
@Override
@NotNull
public JComponent getComponent() {
return myEditor.getComponent();
}
@Override
public JComponent getPreferredFocusedComponent() {
return myEditor.getContentComponent();
}
@Override
@NotNull
public String getName() {
return "Text";
}
@Override
public StructureViewBuilder getStructureViewBuilder() {
VirtualFile file = FileDocumentManager.getInstance().getFile(myEditor.getDocument());
if (file == null) return null;
final Project project = myEditor.getProject();
LOG.assertTrue(project != null);
return StructureViewBuilder.PROVIDER.getStructureViewBuilder(file.getFileType(), file, project);
}
@Override
@NotNull
public FileEditorState getState(@NotNull FileEditorStateLevel level) {
return getStateImpl(null, myEditor, level);
}
@Override
public void setState(@NotNull FileEditorState state) {
setStateImpl(null, myEditor, (TextEditorState)state);
}
@Override
public boolean isModified() {
return false;
}
@Override
public boolean isValid() {
return true;
}
@Override
public void dispose() { }
@Override
public void selectNotify() { }
@Override
public void deselectNotify() { }
@Override
public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) { }
@Override
public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) { }
@Override
public BackgroundEditorHighlighter getBackgroundHighlighter() {
return null;
}
@Override
public FileEditorLocation getCurrentLocation() {
return null;
}
@Override
public boolean canNavigateTo(@NotNull final Navigatable navigatable) {
return false;
}
@Override
public void navigateTo(@NotNull final Navigatable navigatable) {
}
}
@@ -38,7 +38,6 @@ import com.intellij.util.ui.UIUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Comparator;
@@ -1005,7 +1004,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
}
}
private final class MyLayeredPane extends JLayeredPane{
private final class MyLayeredPane extends JBLayeredPane {
/*
* These images are used to perform animated showing and hiding of components.
* They are the member for performance reason.
@@ -1018,8 +1017,6 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
myTopImageRef=new SoftReference<BufferedImage>(null);
setOpaque(!UIUtil.isUnderDarcula());
add(splitter,JLayeredPane.DEFAULT_LAYER);
splitter.setBounds(0,0,getWidth(),getHeight());
enableEvents(ComponentEvent.COMPONENT_EVENT_MASK);
}
@Override
@@ -1067,8 +1064,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
/**
* When component size becomes larger then bottom and top images should be enlarged.
*/
protected final void processComponentEvent(final ComponentEvent e) {
if(ComponentEvent.COMPONENT_RESIZED==e.getID()){
public void doLayout() {
final int width=getWidth();
final int height=getHeight();
if(width<0||height<0){
@@ -1102,11 +1098,6 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
}
setBoundsInPaletteLayer(component, info.getAnchor(), weight);
}
validate();
repaint();
}else{
super.processComponentEvent(e);
}
}
public final void setBoundsInPaletteLayer(final Component component,final ToolWindowAnchor anchor,float weight){
@@ -229,7 +229,7 @@ public class GeneralCommandLineTest {
}
private static void checkEnvPassing(GeneralCommandLine commandLine, Map<String, String> testEnv, boolean passParentEnv) throws Exception {
commandLine.setEnvironment(testEnv);
commandLine.getEnvironment().putAll(testEnv);
commandLine.setPassParentEnvironment(passParentEnv);
String output = execAndGetOutput(commandLine, null);
@@ -16,11 +16,14 @@
package com.intellij.openapi.fileEditor;
import com.intellij.ide.ui.UISettings;
import com.intellij.mock.Mock;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ExpandMacroToPathMap;
import com.intellij.openapi.fileEditor.impl.EditorWithProviderComposite;
import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
@@ -30,8 +33,10 @@ import com.intellij.util.containers.ContainerUtil;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.serialization.PathMacroUtil;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
@@ -46,7 +51,6 @@ import java.util.concurrent.Future;
public class FileEditorManagerTest extends LightPlatformCodeInsightFixtureTestCase {
private FileEditorManagerImpl myManager;
@SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors")
public FileEditorManagerTest() {
PlatformTestCase.initPlatformLangPrefix();
@@ -54,7 +58,7 @@ public class FileEditorManagerTest extends LightPlatformCodeInsightFixtureTestCa
public void testTabOrder() throws Exception {
openFiles();
openFiles(STRING);
assertOpenFiles("1.txt", "foo.xml", "2.txt", "3.txt");
}
@@ -63,7 +67,7 @@ public class FileEditorManagerTest extends LightPlatformCodeInsightFixtureTestCa
int limit = UISettings.getInstance().EDITOR_TAB_LIMIT;
try {
UISettings.getInstance().EDITOR_TAB_LIMIT = 2;
openFiles();
openFiles(STRING);
// note that foo.xml is pinned
assertOpenFiles("foo.xml", "3.txt");
}
@@ -72,6 +76,65 @@ public class FileEditorManagerTest extends LightPlatformCodeInsightFixtureTestCa
}
}
public void testOpenRecentEditorTab() throws Exception {
PlatformTestUtil.registerExtension(FileEditorProvider.EP_FILE_EDITOR_PROVIDER, new MyFileEditorProvider(), getTestRootDisposable());
openFiles(" <component name=\"FileEditorManager\">\n" +
" <leaf>\n" +
" <file leaf-file-name=\"foo.xsd\" pinned=\"false\" current=\"true\" current-in-tab=\"true\">\n" +
" <entry selected=\"true\" file=\"file://$PROJECT_DIR$/src/1.txt\">\n" +
" <provider editor-type-id=\"mock\" selected=\"true\">\n" +
" <state />\n" +
" </provider>\n" +
" <provider editor-type-id=\"text-editor\">\n" +
" <state/>\n" +
" </provider>\n" +
" </entry>\n" +
" </file>\n" +
" </leaf>\n" +
" </component>\n");
FileEditor[] selectedEditors = myManager.getSelectedEditors();
assertEquals(1, selectedEditors.length);
assertEquals("mockEditor", selectedEditors[0].getName());
}
private static final String STRING = "<component name=\"FileEditorManager\">\n" +
" <leaf>\n" +
" <file leaf-file-name=\"1.txt\" pinned=\"false\" current=\"false\" current-in-tab=\"false\">\n" +
" <entry file=\"file://$PROJECT_DIR$/src/1.txt\">\n" +
" <provider selected=\"true\" editor-type-id=\"text-editor\">\n" +
" <state line=\"0\" column=\"0\" selection-start=\"0\" selection-end=\"0\" vertical-scroll-proportion=\"0.0\">\n" +
" </state>\n" +
" </provider>\n" +
" </entry>\n" +
" </file>\n" +
" <file leaf-file-name=\"foo.xml\" pinned=\"true\" current=\"false\" current-in-tab=\"false\">\n" +
" <entry file=\"file://$PROJECT_DIR$/src/foo.xml\">\n" +
" <provider selected=\"true\" editor-type-id=\"text-editor\">\n" +
" <state line=\"0\" column=\"0\" selection-start=\"0\" selection-end=\"0\" vertical-scroll-proportion=\"0.0\">\n" +
" </state>\n" +
" </provider>\n" +
" </entry>\n" +
" </file>\n" +
" <file leaf-file-name=\"2.txt\" pinned=\"false\" current=\"true\" current-in-tab=\"true\">\n" +
" <entry file=\"file://$PROJECT_DIR$/src/2.txt\">\n" +
" <provider selected=\"true\" editor-type-id=\"text-editor\">\n" +
" <state line=\"0\" column=\"0\" selection-start=\"0\" selection-end=\"0\" vertical-scroll-proportion=\"0.0\">\n" +
" </state>\n" +
" </provider>\n" +
" </entry>\n" +
" </file>\n" +
" <file leaf-file-name=\"3.txt\" pinned=\"false\" current=\"false\" current-in-tab=\"false\">\n" +
" <entry file=\"file://$PROJECT_DIR$/src/3.txt\">\n" +
" <provider selected=\"true\" editor-type-id=\"text-editor\">\n" +
" <state line=\"0\" column=\"0\" selection-start=\"0\" selection-end=\"0\" vertical-scroll-proportion=\"0.0\">\n" +
" </state>\n" +
" </provider>\n" +
" </entry>\n" +
" </file>\n" +
" </leaf>\n" +
" </component>\n";
private void assertOpenFiles(String... fileNames) {
EditorWithProviderComposite[] files = myManager.getSplitters().getEditorsComposites();
List<String> names = ContainerUtil.map(files, new Function<EditorWithProviderComposite, String>() {
@@ -83,43 +146,8 @@ public class FileEditorManagerTest extends LightPlatformCodeInsightFixtureTestCa
assertEquals(Arrays.asList(fileNames), names);
}
private void openFiles() throws IOException, JDOMException, InterruptedException, ExecutionException {
Document document = JDOMUtil.loadDocument(" <component name=\"FileEditorManager\">\n" +
" <leaf>\n" +
" <file leaf-file-name=\"1.txt\" pinned=\"false\" current=\"false\" current-in-tab=\"false\">\n" +
" <entry file=\"file://$PROJECT_DIR$/src/1.txt\">\n" +
" <provider selected=\"true\" editor-type-id=\"text-editor\">\n" +
" <state line=\"0\" column=\"0\" selection-start=\"0\" selection-end=\"0\" vertical-scroll-proportion=\"0.0\">\n" +
" </state>\n" +
" </provider>\n" +
" </entry>\n" +
" </file>\n" +
" <file leaf-file-name=\"foo.xml\" pinned=\"true\" current=\"false\" current-in-tab=\"false\">\n" +
" <entry file=\"file://$PROJECT_DIR$/src/foo.xml\">\n" +
" <provider selected=\"true\" editor-type-id=\"text-editor\">\n" +
" <state line=\"0\" column=\"0\" selection-start=\"0\" selection-end=\"0\" vertical-scroll-proportion=\"0.0\">\n" +
" </state>\n" +
" </provider>\n" +
" </entry>\n" +
" </file>\n" +
" <file leaf-file-name=\"2.txt\" pinned=\"false\" current=\"true\" current-in-tab=\"true\">\n" +
" <entry file=\"file://$PROJECT_DIR$/src/2.txt\">\n" +
" <provider selected=\"true\" editor-type-id=\"text-editor\">\n" +
" <state line=\"0\" column=\"0\" selection-start=\"0\" selection-end=\"0\" vertical-scroll-proportion=\"0.0\">\n" +
" </state>\n" +
" </provider>\n" +
" </entry>\n" +
" </file>\n" +
" <file leaf-file-name=\"3.txt\" pinned=\"false\" current=\"false\" current-in-tab=\"false\">\n" +
" <entry file=\"file://$PROJECT_DIR$/src/3.txt\">\n" +
" <provider selected=\"true\" editor-type-id=\"text-editor\">\n" +
" <state line=\"0\" column=\"0\" selection-start=\"0\" selection-end=\"0\" vertical-scroll-proportion=\"0.0\">\n" +
" </state>\n" +
" </provider>\n" +
" </entry>\n" +
" </file>\n" +
" </leaf>\n" +
" </component>\n");
private void openFiles(String s) throws IOException, JDOMException, InterruptedException, ExecutionException {
Document document = JDOMUtil.loadDocument(s);
Element rootElement = document.getRootElement();
ExpandMacroToPathMap map = new ExpandMacroToPathMap();
map.addMacroExpand(PathMacroUtil.PROJECT_DIR_MACRO_NAME, getTestDataPath());
@@ -156,4 +184,60 @@ public class FileEditorManagerTest extends LightPlatformCodeInsightFixtureTestCa
protected boolean isWriteActionRequired() {
return false;
}
private static class MyFileEditorProvider implements FileEditorProvider {
@NotNull
@Override
public String getEditorTypeId() {
return "mock";
}
@NotNull
@Override
public FileEditorState readState(@NotNull Element sourceElement, @NotNull Project project, @NotNull VirtualFile file) {
return FileEditorState.INSTANCE;
}
@Override
public void writeState(@NotNull FileEditorState state, @NotNull Project project, @NotNull Element targetElement) {
}
@Override
public boolean accept(@NotNull Project project, @NotNull VirtualFile file) {
return true;
}
@NotNull
@Override
public FileEditor createEditor(@NotNull Project project, @NotNull VirtualFile file) {
return new Mock.MyFileEditor() {
@Override
public boolean isValid() {
return true;
}
@NotNull
@Override
public JComponent getComponent() {
return new JLabel();
}
@NotNull
@Override
public String getName() {
return "mockEditor";
}
};
}
@Override
public void disposeEditor(@NotNull FileEditor editor) {
}
@NotNull
@Override
public FileEditorPolicy getPolicy() {
return FileEditorPolicy.PLACE_AFTER_DEFAULT_EDITOR;
}
}
}
@@ -70,12 +70,12 @@ public class ProjectFileIndexFacade extends FileIndexFacade {
@Nullable
@Override
public Module getModuleForFile(VirtualFile file) {
public Module getModuleForFile(@NotNull VirtualFile file) {
return myFileIndex.getModuleForFile(file);
}
@Override
public boolean isValidAncestor(final VirtualFile baseDir, VirtualFile childDir) {
public boolean isValidAncestor(@NotNull final VirtualFile baseDir, @NotNull VirtualFile childDir) {
if (!childDir.isDirectory()) {
childDir = childDir.getParent();
}
@@ -1,7 +1,6 @@
package com.intellij.util.containers;
import com.intellij.openapi.util.LowMemoryWatcher;
import com.intellij.util.containers.SLRUCache;
import jsr166e.SequenceLock;
import org.jetbrains.annotations.NotNull;
@@ -16,7 +15,9 @@ public class RecentStringInterner {
private final int myStripeMask;
private final SLRUCache<String, String>[] myInterns;
private final Lock[] myStripeLocks;
private final LowMemoryWatcher myClearingCallback;
// LowMemoryWatcher relies on field holding it
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
private final LowMemoryWatcher myLowMemoryWatcher;
public RecentStringInterner() {
this(8192);
@@ -24,6 +25,7 @@ public class RecentStringInterner {
public RecentStringInterner(int capacity) {
final int stripes = 16;
//noinspection unchecked
myInterns = new SLRUCache[stripes];
myStripeLocks = new Lock[myInterns.length];
for(int i = 0; i < myInterns.length; ++i) {
@@ -44,11 +46,11 @@ public class RecentStringInterner {
assert Integer.highestOneBit(stripes) == stripes;
myStripeMask = stripes - 1;
myClearingCallback = LowMemoryWatcher.register(new Runnable() {
myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() {
@Override
public void run() {
clear();
};
}
});
}
@@ -339,6 +339,7 @@ public class VcsChangeDetailsManager {
protected JPanel dataToPresentation(ValueWithVcsException<PreparedFragmentedContent> value) {
final PreparedFragmentedContent requestForChange;
try {
if (value == null) return noDifferences();
requestForChange = value.get();
if (requestForChange == null) return noDifferences();
if (requestForChange.isEmpty()) {
@@ -167,13 +167,20 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
((ProjectLevelVcsManagerImpl) vcsManager).addInitializationRequest(VcsInitObject.COMMITTED_CHANGES_CACHE, new Runnable() {
@Override
public void run() {
myTaskQueue.start();
myConnection.subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, vcsListener);
myConnection.subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED_IN_PLUGIN, vcsListener);
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
if (myProject.isDisposed()) return;
myTaskQueue.start();
myConnection.subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, vcsListener);
myConnection.subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED_IN_PLUGIN, vcsListener);
}
});
}
});
myVcsManager = vcsManager;
Disposer.register(project, new Disposable() {
@Override
public void dispose() {
cancelRefreshTimer();
myConnection.disconnect();
@@ -186,10 +193,12 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
return myBus;
}
@Override
public State getState() {
return myState;
}
@Override
public void loadState(State state) {
myState = state;
updateRefreshTimer();
@@ -246,6 +255,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
myErrorConsumer = errorConsumer;
}
@Override
public void run() {
for(AbstractVcs vcs: myVcsManager.getAllActiveVcss()) {
final CommittedChangesProvider provider = vcs.getCommittedChangesProvider();
@@ -289,6 +299,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
}
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
LOG.info("FINISHED CommittedChangesCache.getProjectChangesAsync - execution in queue");
if (myProject.isDisposed()) {
@@ -378,6 +389,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
public void hasCachesForAnyRoot(@Nullable final Consumer<Boolean> continuation) {
myTaskQueue.run(new Runnable() {
@Override
public void run() {
final Ref<Boolean> success = new Ref<Boolean>();
try {
@@ -387,6 +399,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
success.set(true);
}
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
continuation.consume(success.get());
}
@@ -407,6 +420,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
private boolean hasCachesWithEmptiness(final boolean emptiness) {
final Ref<Boolean> resultRef = new Ref<Boolean>(Boolean.FALSE);
myCachesHolder.iterateAllCaches(new NotNullFunction<ChangesCacheFile, Boolean>() {
@Override
@NotNull
public Boolean fun(final ChangesCacheFile changesCacheFile) {
try {
@@ -525,7 +539,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
});
}
// todo: fix - would externally loaded nesseccerily for file? i.e. just not efficient now
// todo: fix - would externally loaded nesseccerily for file? i.e. just not efficient now
private List<CommittedChangeList> refreshCache(final ChangesCacheFile cacheFile) throws VcsException, IOException {
final List<CommittedChangeList> newLists = new ArrayList<CommittedChangeList>();
@@ -586,6 +600,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
}
final Ref<IOException> ref = new Ref<IOException>();
final List<CommittedChangeList> savedChanges = ApplicationManager.getApplication().runReadAction(new Computable<List<CommittedChangeList>>() {
@Override
public List<CommittedChangeList> compute() {
try {
return cacheFile.writeChanges(newChanges); // skip duplicates;
@@ -655,7 +670,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
return result;
}
private class IncomingListsZipper extends VcsCommittedListsZipperAdapter {
private static class IncomingListsZipper extends VcsCommittedListsZipperAdapter {
private final VcsCommittedListsZipper myVcsZipper;
private IncomingListsZipper(final VcsCommittedListsZipper vcsZipper) {
@@ -663,6 +678,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
myVcsZipper = vcsZipper;
}
@Override
public Pair<List<RepositoryLocationGroup>, List<RepositoryLocation>> groupLocations(final List<RepositoryLocation> in) {
return myVcsZipper.groupLocations(in);
}
@@ -723,6 +739,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
public void loadIncomingChangesAsync(@Nullable final Consumer<List<CommittedChangeList>> consumer, final boolean inBackground) {
debug("Loading incoming changes");
final Runnable task = new Runnable() {
@Override
public void run() {
final List<CommittedChangeList> list = loadIncomingChanges(inBackground);
if (consumer != null) {
@@ -757,6 +774,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
public void processUpdatedFiles(final UpdatedFiles updatedFiles) {
final Runnable task = new Runnable() {
@Override
public void run() {
debug("Processing updated files");
final Collection<ChangesCacheFile> caches = myCachesHolder.getAllCaches();
@@ -799,6 +817,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
private void processUpdatedFilesAfterRefresh(final ChangesCacheFile cache, final UpdatedFiles updatedFiles) {
refreshCacheAsync(cache, false, new RefreshResultConsumer() {
@Override
public void receivedChanges(final List<CommittedChangeList> committedChangeLists) {
try {
debug("Processing updated files after refresh in " + cache.getLocation());
@@ -825,6 +844,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
}
}
@Override
public void receivedError(VcsException ex) {
notifyRefreshError(ex);
}
@@ -911,17 +931,19 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
debug("Refreshing incoming changes in background");
myRefreshingIncomingChanges = true;
final Runnable task = new Runnable() {
@Override
public void run() {
refreshIncomingChanges();
refreshIncomingUi();
}
};
myTaskQueue.run(task);
myTaskQueue.run(task);
}
private void refreshIncomingUi() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
myRefreshingIncomingChanges = false;
debug("Incoming changes refresh complete, clearing cached incoming changes");
@@ -932,6 +954,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
public void refreshAllCachesAsync(final boolean initIfEmpty, final boolean inBackground) {
final Runnable task = new Runnable() {
@Override
public void run() {
final List<ChangesCacheFile> files = myCachesHolder.getAllCaches();
final RefreshResultConsumer notifyConsumer = new RefreshResultConsumer() {
@@ -939,11 +962,13 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
private int myCount = 0;
private int totalChangesCount = 0;
@Override
public void receivedChanges(List<CommittedChangeList> changes) {
totalChangesCount += changes.size();
checkDone();
}
@Override
public void receivedError(VcsException ex) {
myError = ex;
checkDone();
@@ -998,6 +1023,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
return;
}
final Runnable task = new Runnable() {
@Override
public void run() {
try {
final List<CommittedChangeList> list;
@@ -1105,6 +1131,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
myCache = null;
}
@Override
public void run() {
final CommittedChangesCache cache = myCache;
if (cache == null) return;
@@ -56,7 +56,7 @@ public class DefaultFileIndexFacade extends FileIndexFacade {
}
@Override
public boolean isInLibrarySource(VirtualFile file) {
public boolean isInLibrarySource(@NotNull VirtualFile file) {
return false;
}
@@ -65,11 +65,11 @@ public class DefaultFileIndexFacade extends FileIndexFacade {
}
@Override
public Module getModuleForFile(VirtualFile file) {
public Module getModuleForFile(@NotNull VirtualFile file) {
return null;
}
public boolean isValidAncestor(final VirtualFile baseDir, final VirtualFile childDir) {
public boolean isValidAncestor(@NotNull final VirtualFile baseDir, @NotNull final VirtualFile childDir) {
return VfsUtil.isAncestor(baseDir, childDir, false);
}
@@ -42,10 +42,13 @@ public class VcsInitialization {
StartupManager.getInstance(myProject).registerPostStartupActivity(new DumbAwareRunnable() {
public void run() {
if (myProject.isDisposed()) return;
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
execute();
if (!myProject.isDisposed()) {
execute();
}
}
});
}
@@ -148,7 +148,7 @@ public class NewMappings {
mappingsChanged();
}
private void keepActiveVcs(final Runnable runnable) {
private void keepActiveVcs(@NotNull Runnable runnable) {
final MyVcsActivator activator;
synchronized (myLock) {
if (! myActivated) {
@@ -20,9 +20,7 @@ import com.intellij.ide.favoritesTreeView.AbstractFavoritesListProvider;
import com.intellij.ide.favoritesTreeView.FavoritesManager;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.pom.Navigatable;
import com.intellij.ui.CheckedTreeNode;
import com.intellij.ui.ColoredTreeCellRenderer;
@@ -68,14 +66,8 @@ public class BreakpointsFavoriteListProvider extends AbstractFavoritesListProvid
super(project, "Breakpoints");
myBreakpointPanelProviders = XBreakpointUtil.collectPanelProviders();
for (final BreakpointPanelProvider provider : myBreakpointPanelProviders) {
provider.addListener(this, myProject);
provider.addListener(this, myProject, myProject);
provider.createBreakpointsGroupingRules(myRulesAvailable);
Disposer.register(project, new Disposable() {
@Override
public void dispose() {
provider.removeListener(BreakpointsFavoriteListProvider.this);
}
});
}
myTreeController = new BreakpointItemsTreeController(myRulesAvailable);
myTree = new BreakpointsSimpleTree(myProject, myTreeController);
@@ -15,6 +15,7 @@
*/
package com.intellij.xdebugger.impl.breakpoints;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.editor.Document;
@@ -22,6 +23,7 @@ import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xdebugger.XDebuggerManager;
@@ -53,14 +55,20 @@ public class XBreakpointPanelProvider extends BreakpointPanelProvider<XBreakpoin
}
@Override
public void addListener(BreakpointsListener listener, Project project) {
public void addListener(final BreakpointsListener listener, Project project, Disposable disposable) {
final MyXBreakpointListener listener1 = new MyXBreakpointListener(listener);
XDebuggerManager.getInstance(project).getBreakpointManager().addBreakpointListener(listener1);
myListeners.add(listener1);
Disposer.register(disposable, new Disposable() {
@Override
public void dispose() {
removeListener(listener);
}
});
}
@Override
public void removeListener(BreakpointsListener listener) {
protected void removeListener(BreakpointsListener listener) {
for (MyXBreakpointListener breakpointListener : myListeners) {
if (breakpointListener.myListener == listener) {
myListeners.remove(breakpointListener);
@@ -15,6 +15,7 @@
*/
package com.intellij.xdebugger.impl.breakpoints.ui;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
@@ -36,9 +37,9 @@ public abstract class BreakpointPanelProvider<B> {
void breakpointsChanged();
}
public abstract void addListener(BreakpointsListener listener, Project project);
public abstract void addListener(BreakpointsListener listener, Project project, Disposable disposable);
public abstract void removeListener(BreakpointsListener listener);
protected abstract void removeListener(BreakpointsListener listener);
public abstract int getPriority();
@@ -15,6 +15,7 @@
*/
package com.intellij.xdebugger.impl.breakpoints.ui.tree;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.CheckboxAction;
import com.intellij.openapi.project.Project;
@@ -23,6 +24,7 @@ import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.JBPopupListener;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.popup.util.DetailView;
import com.intellij.ui.popup.util.DetailViewImpl;
@@ -177,8 +179,9 @@ public class BreakpointMasterDetailPopupBuilder {
}
};
final Disposable listenerDisposable = Disposer.newDisposable();
for (BreakpointPanelProvider provider : myBreakpointsPanelProviders) {
provider.addListener(listener, myProject);
provider.addListener(listener, myProject, listenerDisposable);
}
final MasterDetailPopupBuilder.Delegate delegate = new MasterDetailPopupBuilder.Delegate() {
@@ -247,9 +250,7 @@ public class BreakpointMasterDetailPopupBuilder {
@Override
public void onClosed(LightweightWindowEvent event) {
for (BreakpointPanelProvider provider : myBreakpointsPanelProviders) {
provider.removeListener(listener);
}
Disposer.dispose(listenerDisposable);
saveBreakpointsDialogState();
}
});
@@ -2297,6 +2297,10 @@
key="unnecessary.call.to.string.valueof.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.code.style.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.style.UnnecessaryCallToStringValueOfInspection"/>
<localInspection language="JAVA" shortName="UnnecessaryToStringCall" bundle="com.siyeh.InspectionGadgetsBundle"
key="unnecessary.tostring.call.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.code.style.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.style.UnnecessaryToStringCallInspection"/>
<localInspection language="JAVA" suppressId="RedundantNoArgConstructor" shortName="UnnecessaryConstructor" bundle="com.siyeh.InspectionGadgetsBundle"
key="unnecessary.constructor.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.code.style.issues" enabledByDefault="false" level="WARNING"
@@ -1682,7 +1682,9 @@ synchronization.on.method.parameter.problem.descriptor=Synchronization on method
too.broad.catch.quickfix=Add ''catch'' clause for ''{0}''
too.broad.catch.option=&Only warn on RuntimeException, Exception, Error or Throwable
unnecessary.call.to.string.valueof.display.name=Unnecessary call to 'String.valueOf()'
unnecessary.tostring.call.display.name=Unnecessary call to '.toString()'
unnecessary.call.to.string.valueof.problem.descriptor=<code>#ref</code> can be simplified to ''{0}'' #loc
unnecessary.tostring.call.problem.descriptor=Unnecessary <code>#ref()</code> call #loc
unnecessary.call.to.string.valueof.quickfix=Replace with ''{0}''
throwable.result.of.method.call.ignored.display.name=Throwable result of method call ignored
throwable.result.of.method.call.ignored.problem.descriptor=Result of <code>#ref()</code> not thrown #loc
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,13 +15,13 @@
*/
package com.siyeh.ig.jdk;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
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.BaseInspection;
@@ -44,15 +44,13 @@ public class VarargParameterInspection extends BaseInspection {
@Override
@NotNull
public String getDisplayName() {
return InspectionGadgetsBundle.message(
"variable.argument.method.display.name");
return InspectionGadgetsBundle.message("variable.argument.method.display.name");
}
@Override
@NotNull
public String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message(
"variable.argument.method.problem.descriptor");
return InspectionGadgetsBundle.message("variable.argument.method.problem.descriptor");
}
@Override
@@ -65,27 +63,29 @@ public class VarargParameterInspection extends BaseInspection {
@NotNull
public String getName() {
return InspectionGadgetsBundle.message(
"variable.argument.method.quickfix");
return InspectionGadgetsBundle.message("variable.argument.method.quickfix");
}
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
protected void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
final PsiMethod method = (PsiMethod)element.getParent();
final PsiParameterList parameterList = method.getParameterList();
final PsiParameter[] parameters = parameterList.getParameters();
final PsiParameter lastParameter =
parameters[parameters.length - 1];
final PsiParameter lastParameter = parameters[parameters.length - 1];
if (!lastParameter.isVarArgs()) {
return;
}
final PsiEllipsisType type =
(PsiEllipsisType)lastParameter.getType();
final PsiEllipsisType type = (PsiEllipsisType)lastParameter.getType();
final Query<PsiReference> query = ReferencesSearch.search(method);
final PsiType componentType = type.getComponentType();
final String typeText = componentType.getCanonicalText();
final String typeText;
if (componentType instanceof PsiClassType) {
final PsiClassType classType = (PsiClassType)componentType;
typeText = classType.rawType().getCanonicalText();
} else {
typeText = componentType.getCanonicalText();
}
final Collection<PsiReference> references = query.findAll();
for (PsiReference reference : references) {
modifyCalls(reference, typeText, parameters.length - 1);
@@ -93,59 +93,48 @@ public class VarargParameterInspection extends BaseInspection {
final PsiType arrayType = type.toArrayType();
final PsiManager psiManager = lastParameter.getManager();
final PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory();
final PsiTypeElement newTypeElement =
factory.createTypeElement(arrayType);
final PsiTypeElement typeElement =
lastParameter.getTypeElement();
final PsiTypeElement newTypeElement = factory.createTypeElement(arrayType);
final PsiTypeElement typeElement = lastParameter.getTypeElement();
if (typeElement == null) {
return;
}
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, "java.lang.SafeVarargs");
if (annotation != null) {
annotation.delete();
}
typeElement.replace(newTypeElement);
}
public static void modifyCalls(PsiReference reference,
String arrayTypeText,
int indexOfFirstVarargArgument)
throws IncorrectOperationException {
final PsiReferenceExpression referenceExpression =
(PsiReferenceExpression)reference.getElement();
final PsiMethodCallExpression methodCallExpression =
(PsiMethodCallExpression)referenceExpression.getParent();
final PsiExpressionList argumentList =
methodCallExpression.getArgumentList();
public static void modifyCalls(PsiReference reference, String arrayTypeText, int indexOfFirstVarargArgument) {
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)reference.getElement();
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)referenceExpression.getParent();
final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
@NonNls final StringBuilder builder = new StringBuilder("new ");
builder.append(arrayTypeText);
builder.append("[]{");
if (arguments.length > indexOfFirstVarargArgument) {
final PsiExpression firstArgument =
arguments[indexOfFirstVarargArgument];
final PsiExpression firstArgument = arguments[indexOfFirstVarargArgument];
final String firstArgumentText = firstArgument.getText();
builder.append(firstArgumentText);
for (int i = indexOfFirstVarargArgument + 1;
i < arguments.length; i++) {
builder.append(',');
builder.append(arguments[i].getText());
for (int i = indexOfFirstVarargArgument + 1; i < arguments.length; i++) {
builder.append(',').append(arguments[i].getText());
}
}
builder.append('}');
final Project project = referenceExpression.getProject();
final PsiElementFactory factory =
JavaPsiFacade.getElementFactory(project);
final PsiExpression arrayExpression =
factory.createExpressionFromText(builder.toString(),
referenceExpression);
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
final PsiExpression arrayExpression = factory.createExpressionFromText(builder.toString(), referenceExpression);
if (arguments.length > indexOfFirstVarargArgument) {
final PsiExpression firstArgument =
arguments[indexOfFirstVarargArgument];
argumentList.deleteChildRange(firstArgument,
arguments[arguments.length - 1]);
final PsiExpression firstArgument = arguments[indexOfFirstVarargArgument];
argumentList.deleteChildRange(firstArgument, arguments[arguments.length - 1]);
argumentList.add(arrayExpression);
}
else {
argumentList.add(arrayExpression);
}
final CodeStyleManager codeStyleManager =
CodeStyleManager.getInstance(project);
final JavaCodeStyleManager javaCodeStyleManager =
JavaCodeStyleManager.getInstance(project);
final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project);
javaCodeStyleManager.shortenClassReferences(argumentList);
codeStyleManager.reformat(argumentList);
}
@@ -165,8 +154,7 @@ public class VarargParameterInspection extends BaseInspection {
return;
}
final PsiParameter[] parameters = parameterList.getParameters();
final PsiParameter lastParameter =
parameters[parameters.length - 1];
final PsiParameter lastParameter = parameters[parameters.length - 1];
if (lastParameter.isVarArgs()) {
registerMethodError(method);
}
@@ -0,0 +1,200 @@
/*
* Copyright 2008-2013 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ig.style;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.ParenthesesUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class UnnecessaryToStringCallInspection extends BaseInspection {
@Override
@Nls
@NotNull
public String getDisplayName() {
return InspectionGadgetsBundle.message("unnecessary.tostring.call.display.name");
}
@Override
@NotNull
protected String buildErrorString(Object... infos) {
final String text = (String)infos[0];
return InspectionGadgetsBundle.message("unnecessary.tostring.call.problem.descriptor", text);
}
@Override
@Nullable
protected InspectionGadgetsFix buildFix(Object... infos) {
final String text = (String)infos[0];
return new UnnecessaryCallToStringValueOfFix(text);
}
public static String calculateReplacementText(PsiExpression expression) {
if (expression == null) {
return "this";
}
return expression.getText();
}
private static class UnnecessaryCallToStringValueOfFix extends InspectionGadgetsFix {
private final String replacementText;
UnnecessaryCallToStringValueOfFix(String replacementText) {
this.replacementText = replacementText;
}
@NotNull
public String getName() {
return InspectionGadgetsBundle.message("unnecessary.call.to.string.valueof.quickfix", replacementText);
}
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)descriptor.getPsiElement().getParent().getParent();
final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
final PsiExpression qualifier = methodExpression.getQualifierExpression();
if (qualifier == null) {
replaceExpression(methodCallExpression, "this");
} else {
methodCallExpression.replace(qualifier);
}
}
}
@Override
public BaseInspectionVisitor buildVisitor() {
return new UnnecessaryCallToStringValueOfVisitor();
}
private static class UnnecessaryCallToStringValueOfVisitor extends BaseInspectionVisitor {
@Override
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
final String referenceName = methodExpression.getReferenceName();
if (!"toString".equals(referenceName)) {
return;
}
if (isToStringCallNecessary(expression)) {
return;
}
final PsiExpressionList argumentList = expression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
if (arguments.length != 0) {
return;
}
final PsiExpression qualifier = methodExpression.getQualifierExpression();
if (qualifier != null && qualifier.getType() instanceof PsiArrayType) {
// do not warn on nonsensical code
return;
}
registerMethodCallError(expression, calculateReplacementText(qualifier));
}
private boolean isToStringCallNecessary(PsiMethodCallExpression expression) {
final PsiElement parent = ParenthesesUtils.getParentSkipParentheses(expression);
if (parent instanceof PsiPolyadicExpression) {
final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)parent;
final PsiType type = polyadicExpression.getType();
if (!TypeUtils.typeEquals(CommonClassNames.JAVA_LANG_STRING, type)) {
return true;
}
final PsiExpression[] operands = polyadicExpression.getOperands();
int index = -1;
for (int i = 0, length = operands.length; i < length; i++) {
final PsiExpression operand = operands[i];
if (expression.equals(operand)) {
index = i;
}
}
if (index > 0) {
if (!TypeUtils.typeEquals(CommonClassNames.JAVA_LANG_STRING, operands[index - 1].getType())) {
return true;
}
} else if (operands.length > 1) {
if (!TypeUtils.typeEquals(CommonClassNames.JAVA_LANG_STRING, operands[index + 1].getType())) {
return true;
}
} else {
return true;
}
} else if (parent instanceof PsiExpressionList) {
final PsiExpressionList expressionList = (PsiExpressionList)parent;
final PsiElement grandParent = expressionList.getParent();
if (!(grandParent instanceof PsiMethodCallExpression)) {
return true;
}
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)grandParent;
final PsiReferenceExpression methodExpression1 = methodCallExpression.getMethodExpression();
final String name = methodExpression1.getReferenceName();
final PsiExpression[] expressions = expressionList.getExpressions();
if ("insert".equals(name)) {
if (expressions.length < 2 || !expression.equals(ParenthesesUtils.stripParentheses(expressions[1]))) {
return true;
}
if (!isCallToMethodIn(methodCallExpression, "java.lang.StringBuilder", "java.lang.StringBuffer")) {
return true;
}
} else if ("append".equals(name)) {
if (expressions.length < 1 || !expression.equals(ParenthesesUtils.stripParentheses(expressions[0]))) {
return true;
}
if (!isCallToMethodIn(methodCallExpression, "java.lang.StringBuilder", "java.lang.StringBuffer")) {
return true;
}
} else if ("print".equals(name) || "println".equals(name)) {
if (!isCallToMethodIn(methodCallExpression, "java.io.PrintStream", "java.io.PrintWriter")) {
return true;
}
}
} else {
return true;
}
return false;
}
private boolean isCallToMethodIn(PsiMethodCallExpression methodCallExpression, String... classNames) {
final PsiMethod method = methodCallExpression.resolveMethod();
if (method == null) {
return false;
}
final PsiClass containingClass = method.getContainingClass();
if (containingClass == null) {
return false;
}
final String qualifiedName = containingClass.getQualifiedName();
for (String className : classNames) {
if (className.equals(qualifiedName)) {
return true;
}
}
return false;
}
}
}
@@ -1,8 +1,8 @@
<html>
<body>
Reports on any calls to <b>String.valueOf()</b>
used in string concatenations. The conversion to string is handled automatically by the compiler
without a call to <b>String.valueOf()</b>, making it unnecessary.
Reports on any calls to <b>String.valueOf()</b> used in string concatenations and as arguments to the
<b>print</b> and <b>println</b> methods of <b>java.io.PrintWriter</b> and <b>java.io.PrintStream</b>. The conversion
to string will be handled by the underlying library methods without an explicit call to <b>String.valueOf()</b>.
<!-- tooltip end -->
<p>
<small>Powered by InspectionGadgets</small>
@@ -0,0 +1,13 @@
<html>
<body>
Reports on any calls to <b>.toString()</b> used in string concatenations and as arguments to the
<b>print</b> and <b>println</b> methods of <b>java.io.PrintWriter</b> and <b>java.io.PrintStream</b>. The conversion
to string will be handled by the underlying library methods without an explicit call to <b>.toString()</b>.
<p>
Note that without the <b>.toString()</b> the expression will have different semantics (the string "null" will be used instead of
throwing a <b>NullPointerException</b>).
<!-- tooltip end -->
<p>
<small>Powered by InspectionGadgets</small>
</body>
</html>
@@ -0,0 +1,11 @@
package com.siyeh.igfixes.jdk.vararg_parameter;
@SuppressWarnings("UnusedDeclaration")
public class GenericType {
final void addClasses(Class<? extends Number>[] classes) {
}
void test() {
addClasses(new Class[]{Number.class, Byte.class});
}
}
@@ -0,0 +1,12 @@
package com.siyeh.igfixes.jdk.vararg_parameter;
@SuppressWarnings("UnusedDeclaration")
public class GenericType {
@java.lang.SafeVarargs
final void addCl<caret>asses(Class<? extends Number>... classes) {
}
void test() {
addClasses(Number.class, Byte.class);
}
}
@@ -0,0 +1,30 @@
package com.siyeh.igtest.style.unnecessary_tostring;
public class UnnecessaryToString {
String foo(Object o) {
return "star" + o.toString();
}
String bar() {
char[] cs = {'!'};
return "wars" + cs.toString();
}
void fizzz(Object o) {
boolean c = true;
System.out.println(o.toString() + c);
}
void polyadic(Object s) {
s = "abc" + s.toString() + "efg";
}
void printStream(Object o) {
System.out.print(o.toString());
}
void builder(StringBuilder builder, Object o) {
builder.append(o.toString());
}
}
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>UnnecessaryToString.java</file>
<line>6</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary call to '.toString()'</problem_class>
<description>Unnecessary &lt;code&gt;toString()&lt;/code&gt; call #loc</description>
</problem>
<problem>
<file>UnnecessaryToString.java</file>
<line>20</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary call to '.toString()'</problem_class>
<description>Unnecessary &lt;code&gt;toString()&lt;/code&gt; call #loc</description>
</problem>
<problem>
<file>UnnecessaryToString.java</file>
<line>24</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary call to '.toString()'</problem_class>
<description>Unnecessary &lt;code&gt;toString()&lt;/code&gt; call #loc</description>
</problem>
<problem>
<file>UnnecessaryToString.java</file>
<line>28</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary call to '.toString()'</problem_class>
<description>Unnecessary &lt;code&gt;toString()&lt;/code&gt; call #loc</description>
</problem>
</problems>
@@ -0,0 +1,18 @@
package com.siyeh.ig.fixes.jdk;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.IGQuickFixesTestCase;
import com.siyeh.ig.jdk.VarargParameterInspection;
public class VarargParameterFixTest extends IGQuickFixesTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
myFixture.enableInspections(new VarargParameterInspection());
myRelativePath = "jdk/vararg_parameter";
myDefaultHint = InspectionGadgetsBundle.message("variable.argument.method.quickfix");
}
public void testGenericType() { doTest(); }
}
@@ -0,0 +1,10 @@
package com.siyeh.ig.style;
import com.siyeh.ig.IGInspectionTestCase;
public class UnnecessaryToStringCallInspectionTest extends IGInspectionTestCase {
public void test() throws Exception {
doTest("com/siyeh/igtest/style/unnecessary_tostring", new UnnecessaryToStringCallInspection());
}
}
@@ -142,7 +142,8 @@ public abstract class ConnectionOnProcess implements IConnection {
protected synchronized void execute(GeneralCommandLine commandLine) throws AuthenticationException {
try {
commandLine.setEnvironment(EnvironmentUtil.getEnvironmentProperties());
commandLine.getEnvironment().clear();
commandLine.getEnvironment().putAll(EnvironmentUtil.getEnvironmentProperties());
myProcess = commandLine.createProcess();
myErrThread = new ReadProcessThread(
@@ -451,7 +451,8 @@ public abstract class GitHandler {
LOG.debug(String.format("handler=%s, port=%s", myHandlerNo, port));
addAuthListener(httpAuthenticator);
}
myCommandLine.setEnvironment(myEnv);
myCommandLine.getEnvironment().clear();
myCommandLine.getEnvironment().putAll(myEnv);
// start process
myProcess = startProcess();
startHandlingStreams();
@@ -16,7 +16,6 @@
<orderEntry type="module" module-name="lang-api" />
<orderEntry type="module" module-name="openapi" />
<orderEntry type="module" module-name="debugger-openapi" />
<orderEntry type="module" module-name="codeInsight-tests" scope="TEST" />
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
<orderEntry type="module" module-name="xml" scope="TEST" />
@@ -39,6 +39,10 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.artifacts.ArtifactManager;
import com.intellij.packaging.artifacts.ArtifactType;
import com.intellij.packaging.elements.ArtifactRootElement;
import com.intellij.packaging.elements.PackagingElementFactory;
import com.intellij.packaging.impl.artifacts.ArtifactUtil;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.HyperlinkLabel;
@@ -94,28 +98,29 @@ public class AppEngineSupportProvider extends FacetBasedFrameworkSupportProvider
private void addSupport(final Module module, final ModifiableRootModel rootModel, String sdkPath, @Nullable PersistenceApi persistenceApi) {
super.addSupport(module, rootModel, null, null);
final VirtualFile descriptorDir = AppEngineWebIntegration.getInstance().suggestParentDirectoryForAppEngineWebXml(module, rootModel);
if (descriptorDir != null) {
createFileFromTemplate(AppEngineTemplateGroupDescriptorFactory.APP_ENGINE_WEB_XML_TEMPLATE, descriptorDir,
AppEngineUtil.APP_ENGINE_WEB_XML_NAME);
}
final AppEngineFacet appEngineFacet = AppEngineFacet.getAppEngineFacetByModule(module);
LOG.assertTrue(appEngineFacet != null);
final AppEngineFacetConfiguration facetConfiguration = appEngineFacet.getConfiguration();
facetConfiguration.setSdkHomePath(sdkPath);
final AppEngineSdk sdk = appEngineFacet.getSdk();
final Artifact artifact = findContainingArtifact(appEngineFacet);
final Artifact artifact = findOrCreateArtifact(appEngineFacet);
final VirtualFile descriptorDir = AppEngineWebIntegration.getInstance().suggestParentDirectoryForAppEngineWebXml(module, rootModel);
if (descriptorDir != null) {
VirtualFile descriptor = createFileFromTemplate(AppEngineTemplateGroupDescriptorFactory.APP_ENGINE_WEB_XML_TEMPLATE, descriptorDir,
AppEngineUtil.APP_ENGINE_WEB_XML_NAME);
if (descriptor != null) {
AppEngineWebIntegration.getInstance().addDescriptor(artifact, module.getProject(), descriptor);
}
}
final Project project = module.getProject();
AppEngineWebIntegration.getInstance().setupRunConfiguration(rootModel, sdk, artifact, project);
final Library apiJar = addProjectLibrary(module, "AppEngine API", sdk.getLibUserDirectoryPath(), VirtualFile.EMPTY_ARRAY);
rootModel.addLibraryEntry(apiJar);
if (artifact != null) {
AppEngineWebIntegration.getInstance().addLibraryToArtifact(apiJar, artifact, project);
}
AppEngineWebIntegration.getInstance().addLibraryToArtifact(apiJar, artifact, project);
if (persistenceApi != null) {
facetConfiguration.setRunEnhancerOnMake(true);
@@ -146,21 +151,25 @@ public class AppEngineSupportProvider extends FacetBasedFrameworkSupportProvider
}
final Library library = addProjectLibrary(module, "AppEngine ORM", sdk.getOrmLibDirectoryPath(), sdk.getOrmLibSources());
rootModel.addLibraryEntry(library);
if (artifact != null) {
AppEngineWebIntegration.getInstance().addLibraryToArtifact(library, artifact, project);
}
AppEngineWebIntegration.getInstance().addLibraryToArtifact(library, artifact, project);
}
}
@Nullable
private static Artifact findContainingArtifact(AppEngineFacet appEngineFacet) {
final Collection<Artifact> artifacts = ArtifactUtil.getArtifactsContainingModuleOutput(appEngineFacet.getModule());
@NotNull
private static Artifact findOrCreateArtifact(AppEngineFacet appEngineFacet) {
Module module = appEngineFacet.getModule();
ArtifactType artifactType = AppEngineWebIntegration.getInstance().getAppEngineTargetArtifactType();
final Collection<Artifact> artifacts = ArtifactUtil.getArtifactsContainingModuleOutput(module);
for (Artifact artifact : artifacts) {
if (AppEngineWebIntegration.getInstance().getAppEngineTargetArtifactType().equals(artifact.getArtifactType())) {
if (artifactType.equals(artifact.getArtifactType())) {
return artifact;
}
}
return null;
ArtifactManager artifactManager = ArtifactManager.getInstance(module.getProject());
PackagingElementFactory elementFactory = PackagingElementFactory.getInstance();
ArtifactRootElement<?> root = elementFactory.createArtifactRootElement();
elementFactory.getOrCreateDirectory(root, "WEB-INF/classes").addOrFindChild(elementFactory.createModuleOutput(module));
return artifactManager.addArtifact(module.getName(), artifactType, root);
}
private static Library addProjectLibrary(final Module module, final String name, final String path, final VirtualFile[] sources) {
@@ -52,4 +52,7 @@ public abstract class AppEngineWebIntegration {
public abstract void addLibraryToArtifact(@NotNull Library library, @NotNull Artifact artifact, @NotNull Project project);
public abstract List<? extends AppEngineSdk> getSdkForConfiguredDevServers();
public void addDescriptor(@NotNull Artifact artifact, @NotNull Project project, @NotNull VirtualFile descriptor) {
}
}
@@ -94,4 +94,9 @@ public class AppEngineCommunityWebIntegration extends AppEngineWebIntegration {
public List<? extends AppEngineSdk> getSdkForConfiguredDevServers() {
return Collections.emptyList();
}
@Override
public void addDescriptor(@NotNull Artifact artifact, @NotNull Project project, @NotNull VirtualFile descriptor) {
ArtifactManager.getInstance(project).addElementsToDirectory(artifact, "WEB-INF", PackagingElementFactory.getInstance().createFileCopy(descriptor.getPath(), null));
}
}
@@ -20,14 +20,18 @@ import com.intellij.codeInsight.generation.PsiGenerationInfo;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMember;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster;
import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
@@ -92,6 +96,19 @@ public class GroovyGenerationInfo<T extends PsiMember> extends PsiGenerationInfo
}
GrReferenceAdjuster.shortenReferences(member);
adjustDocCommentIfExists(member);
}
private static void adjustDocCommentIfExists(PsiMember member) {
final PsiElement child = member.getFirstChild();
if (child instanceof PsiDocComment) {
final Project project = member.getProject();
final GrDocComment groovyDoc = GroovyPsiElementFactory.getInstance(project).createDocCommentFromText(child.getText());
child.delete();
CodeStyleManager.getInstance(project).reformat(member);
member.getParent().addBefore(groovyDoc, member);
}
}
@Override
@@ -73,7 +73,6 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ClosureMissingMethodContributor;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.lang.resolve.processors.*;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
import org.jetbrains.plugins.groovy.util.ResolveProfiler;
import java.util.*;
@@ -95,7 +94,6 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
private boolean findClassOrPackageAtFirst() {
final String name = getReferenceName();
if (StringUtil.isEmpty(name) || hasAt()) return false;
assert name != null;
return Character.isUpperCase(name.charAt(0)) && !isMethodCallRef() ||
getParent() instanceof GrReferenceExpressionImpl && ((GrReferenceExpressionImpl)getParent()).findClassOrPackageAtFirst();
@@ -216,6 +214,8 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
}
}
if (classCandidates != null && classCandidates.length > 0) return classCandidates;
final boolean isLValue = PsiUtil.isLValue(this);
String[] accessorNames = isLValue ? GroovyPropertyUtils.suggestSettersName(name) : GroovyPropertyUtils.suggestGettersName(name);
List<GroovyResolveResult> accessorResults = new ArrayList<GroovyResolveResult>();
@@ -258,22 +258,6 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
return false;
}
private static boolean containsLocalVar(GroovyResolveResult[] fieldCandidates) {
boolean preferVar = false;
if (fieldCandidates.length > 0) {
for (GroovyResolveResult candidate : fieldCandidates) {
PsiElement element = candidate.getElement();
LOG.assertTrue(element != null, candidate);
if (GroovyRefactoringUtil.isLocalVariable(element) && !(element instanceof GrBindingVariable)) {
preferVar = true;
break;
}
}
}
return preferVar;
}
public GroovyResolveResult[] getCallVariants(GrExpression upToArgument) {
return resolveMethodOrProperty(true, upToArgument, true);
}
@@ -72,7 +72,10 @@ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProp
GrExpression selected = getInvokedExpression();
PsiType thisType = selected.getType();
if (thisType == null) return null;
if (thisType == null) {
thisType = TypesUtil.getJavaLangObject(this);
}
GrArgumentList argList = getArgumentList();
@@ -153,7 +156,9 @@ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProp
GrExpression invoked = getInvokedExpression();
PsiType thisType = invoked.getType();
if (thisType == null) return GroovyResolveResult.EMPTY_ARRAY;
if (thisType == null) {
thisType = TypesUtil.getJavaLangObject(this);
}
GrArgumentList argList = getArgumentList();

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