Merge remote-tracking branch 'origin/master'
@@ -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 <code>2</code> to <code>Integer</code> 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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 984 B After Width: | Height: | Size: 667 B |
|
Before Width: | Height: | Size: 461 B After Width: | Height: | Size: 422 B |
|
Before Width: | Height: | Size: 604 B After Width: | Height: | Size: 588 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 624 B After Width: | Height: | Size: 607 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 654 B After Width: | Height: | Size: 620 B |
|
Before Width: | Height: | Size: 637 B After Width: | Height: | Size: 626 B |
|
Before Width: | Height: | Size: 928 B After Width: | Height: | Size: 224 B |
|
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 <code>toString()</code> 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 <code>toString()</code> 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 <code>toString()</code> 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 <code>toString()</code> 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();
|
||||
|
||||
|
||||