Merge branch 'master' into uta-python

This commit is contained in:
Alexey Utkin
2015-12-29 20:25:05 +03:00
178 changed files with 2166 additions and 996 deletions
+1 -1
View File
@@ -809,7 +809,7 @@
<inspection_tool class="WaitNotInLoop" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="WaitNotInSynchronizedContext" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="WaitWhileHoldingTwoLocks" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true">
<inspection_tool class="WeakerAccess" enabled="false" level="WARNING" enabled_by_default="true">
<option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="false" />
<option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="false" />
<option name="SUGGEST_PRIVATE_FOR_INNERS" value="false" />
+1
View File
@@ -214,6 +214,7 @@ libraryLicense(name: "imgscalr", libraryName: "imgscalr", version: "4.2", licens
libraryLicense(name: "batik", libraryName: "batik", version: "1.7.1", license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt", url: "https://svn.apache.org/repos/asf/xmlgraphics/batik")
libraryLicense(name: "xmlgraphics-commons", libraryName: "xmlgraphics-commons", version: "1.5", license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt", url: "https://svn.apache.org/repos/asf/xmlgraphics/commons")
libraryLicense(name: "xml-apis-ext", libraryName: "xml-apis-ext", version: "1.3", license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt", url: "http://xerces.apache.org/xml-commons/components/external")
libraryLicense(name: "ImageIO", libraryName: "com.twelvemonkeys.imageio:imageio-tiff:3.2.1", version: "3.2.1", license: "BSD", url: "https://github.com/haraldk/TwelveMonkeys", licenseUrl: "https://github.com/haraldk/TwelveMonkeys#license")
libraryLicense(name: "ini4j", libraryName: "ini4j-0.5.2-patched", version: "0.5.2 (with a patch by JetBrains)", license: "Apache 2.0", url: "http://ini4j.sourceforge.net/", attachedTo: "git4idea")
libraryLicense(name: "ISO RELAX", libraryName: "isorelax.jar", license: "MIT License", url: "http://sourceforge.net/projects/iso-relax/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html")
libraryLicense(name: "Jakarta ORO", libraryName: "OroMatcher", version: "2.0.8", license: "Apache", url: "http://jakarta.apache.org/oro/", licenseUrl: "http://svn.apache.org/repos/asf/jakarta/oro/trunk/LICENSE")
@@ -26,7 +26,6 @@ import org.intellij.images.editor.ImageEditor;
import org.intellij.images.editor.ImageZoomModel;
import org.intellij.images.fileTypes.ImageFileTypeManager;
import org.intellij.images.thumbnail.actionSystem.ThumbnailViewActions;
import org.intellij.images.ui.ImageComponent;
import org.intellij.images.vfs.IfsUtil;
import org.jetbrains.annotations.NotNull;
@@ -37,13 +36,13 @@ import javax.swing.*;
*
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
final class ImageEditorImpl implements ImageEditor {
public final class ImageEditorImpl implements ImageEditor {
private final Project project;
private final VirtualFile file;
private final ImageEditorUI editorUI;
private boolean disposed;
ImageEditorImpl(@NotNull Project project, @NotNull VirtualFile file) {
public ImageEditorImpl(@NotNull Project project, @NotNull VirtualFile file) {
this.project = project;
this.file = file;
@@ -104,7 +104,7 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
@Override
public void visitAnonymousClass(PsiAnonymousClass aClass) {
for (PsiMethod psiMethod : aClass.getMethods()) {
targets.add(new MethodSmartStepTarget(psiMethod, getCurrentParamName(), psiMethod.getBody(), true, null));
targets.add(0, new MethodSmartStepTarget(psiMethod, getCurrentParamName(), psiMethod.getBody(), true, null));
}
}
@@ -113,7 +113,7 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
myInsideLambda = true;
super.visitLambdaExpression(expression);
myInsideLambda = inLambda;
targets.add(new LambdaSmartStepTarget(expression, getCurrentParamName(), expression.getBody(), myNextLambdaExpressionOrdinal++, null));
targets.add(0, new LambdaSmartStepTarget(expression, getCurrentParamName(), expression.getBody(), myNextLambdaExpressionOrdinal++, null));
}
@Override
@@ -122,7 +122,7 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
if (element instanceof PsiMethod) {
PsiElement navMethod = element.getNavigationElement();
if (navMethod instanceof PsiMethod) {
targets.add(new MethodSmartStepTarget(((PsiMethod)navMethod), null, expression, true, null));
targets.add(0, new MethodSmartStepTarget(((PsiMethod)navMethod), null, expression, true, null));
}
}
}
@@ -73,8 +73,9 @@ public abstract class JvmSmartStepIntoHandler {
}
});
ListPopupImpl popup = new ListPopupImpl(popupStep);
DebuggerUIUtil.registerExtraHandleShortcuts(popup, XDebuggerActions.STEP_INTO);
DebuggerUIUtil.registerExtraHandleShortcuts(popup, XDebuggerActions.SMART_STEP_INTO);
DebuggerUIUtil.registerExtraHandleShortcuts(popup, XDebuggerActions.STEP_INTO, XDebuggerActions.SMART_STEP_INTO);
popup.setAdText(DebuggerUIUtil.getSelectionShortcutsAdText(XDebuggerActions.STEP_INTO, XDebuggerActions.SMART_STEP_INTO));
popup.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
popupStep.getScopeHighlighter().dropHighlight();
@@ -39,6 +39,7 @@ import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.EvaluationMode;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -74,6 +75,10 @@ public class JavaDebuggerEvaluator extends XDebuggerEvaluator {
@Override
public void threadAction() {
if (DebuggerUIUtil.isObsolete(callback)) {
return;
}
JavaDebugProcess process = myDebugProcess.getXdebugProcess();
if (process == null) {
callback.errorOccurred("No debug process");
@@ -141,6 +141,9 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
@Override
public void contextAction() throws Exception {
if (node.isObsolete()) {
return;
}
if (!myContextSet) {
myValueDescriptor.setContext(myEvaluationContext);
}
@@ -281,7 +281,7 @@ public class RequestHint {
}
}
// smart step feature
if (myMethodFilter != null) {
if (myMethodFilter != null && !mySteppedOut) {
return StepRequest.STEP_OUT;
}
}
@@ -89,7 +89,7 @@ public class DefaultCodeFragmentFactory extends CodeFragmentFactory {
final DebuggerContextImpl debuggerContext = DebuggerManagerEx.getInstanceEx(project).getContext();
DebuggerSession debuggerSession = debuggerContext.getDebuggerSession();
if (debuggerSession != null) {
if (debuggerSession != null && debuggerContext.getSuspendContext() != null) {
final Semaphore semaphore = new Semaphore();
semaphore.down();
final AtomicReference<PsiType> nameRef = new AtomicReference<PsiType>();
@@ -30,6 +30,7 @@ public abstract class DebuggerContextCommandImpl extends SuspendContextCommandIm
private final DebuggerContextImpl myDebuggerContext;
private final ThreadReferenceProxyImpl myCustomThread; // thread to perform command in
private SuspendContextImpl myCustomSuspendContext;
protected DebuggerContextCommandImpl(@NotNull DebuggerContextImpl debuggerContext) {
this(debuggerContext, null);
@@ -44,10 +45,15 @@ public abstract class DebuggerContextCommandImpl extends SuspendContextCommandIm
@Nullable
@Override
public SuspendContextImpl getSuspendContext() {
if (myCustomThread != null) {
return SuspendManagerUtil.findContextByThread(myDebuggerContext.getDebugProcess().getSuspendManager(), getThread());
if (myCustomSuspendContext == null) {
myCustomSuspendContext = super.getSuspendContext();
ThreadReferenceProxyImpl thread = getThread();
if (myCustomThread != null &&
(myCustomSuspendContext == null || myCustomSuspendContext.isResumed() || !myCustomSuspendContext.suspends(thread))) {
myCustomSuspendContext = SuspendManagerUtil.findContextByThread(myDebuggerContext.getDebugProcess().getSuspendManager(), thread);
}
}
return super.getSuspendContext();
return myCustomSuspendContext;
}
private ThreadReferenceProxyImpl getThread() {
@@ -34,6 +34,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.util.ClassUtil;
import com.intellij.psi.util.PsiTreeUtil;
import java.util.ArrayList;
import java.util.LinkedHashSet;
@@ -163,6 +164,7 @@ public abstract class AbstractPatternBasedConfigurationProducer<T extends Module
return true;
}
else {
final PsiElement element = CommonDataKeys.PSI_ELEMENT.getData(dataContext);
final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
if (files != null) {
Project project = CommonDataKeys.PROJECT.getData(dataContext);
@@ -171,7 +173,16 @@ public abstract class AbstractPatternBasedConfigurationProducer<T extends Module
for (VirtualFile file : files) {
final PsiFile psiFile = psiManager.findFile(file);
if (psiFile instanceof PsiClassOwner) {
collectTestMembers(((PsiClassOwner)psiFile).getClasses(), checkAbstract, checkIsTest, processor);
PsiClass[] psiClasses = ((PsiClassOwner)psiFile).getClasses();
if (element != null && psiClasses.length > 0) {
for (PsiClass aClass : psiClasses) {
if (PsiTreeUtil.isAncestor(aClass, element, false)) {
psiClasses = new PsiClass[] {aClass};
break;
}
}
}
collectTestMembers(psiClasses, checkAbstract, checkIsTest, processor);
for (PsiElement psiMember : processor.getCollection()) {
classes.add(((PsiClass)psiMember).getQualifiedName());
}
@@ -98,6 +98,7 @@ public abstract class LanguageLevelCombo extends ComboBox {
}
else if (!(getItemAt(0) instanceof String)) {
addDefaultItem();
setSelectedIndex(0);
}
repaint();
}
@@ -230,7 +230,7 @@ class AccessCanBeTightenedInspection extends BaseJavaBatchLocalInspectionTool {
}
return myVisibilityInspection.SUGGEST_PRIVATE_FOR_INNERS ||
memberClass == aClass && memberClass.getContainingClass() == null ? PsiUtil.ACCESS_LEVEL_PRIVATE : suggestPackageLocal(member);
!isInnerClass(memberClass) ? PsiUtil.ACCESS_LEVEL_PRIVATE : suggestPackageLocal(member);
}
//if (file == memberFile) {
// return PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL;
@@ -253,6 +253,10 @@ class AccessCanBeTightenedInspection extends BaseJavaBatchLocalInspectionTool {
}
}
private static boolean isInnerClass(@NotNull PsiClass memberClass) {
return memberClass.getContainingClass() != null || memberClass instanceof PsiAnonymousClass;
}
private static boolean isInReferenceList(@Nullable PsiElement list, @NotNull final PsiMember member) {
if (list == null) return false;
final PsiManager psiManager = member.getManager();
@@ -1230,9 +1230,7 @@ public class ExpectedTypesProvider {
final PsiClassType type =
substitutor == null ? facade.getElementFactory().createType(aClass) : facade.getElementFactory().createType(aClass, substitutor);
if (method.hasModifierProperty(PsiModifier.STATIC) ||
method.hasModifierProperty(PsiModifier.FINAL) ||
method.hasModifierProperty(PsiModifier.PRIVATE)) {
if (method.hasModifierProperty(PsiModifier.STATIC) || method.hasModifierProperty(PsiModifier.PRIVATE)) {
types.add(createInfoImpl(type, ExpectedTypeInfo.TYPE_STRICTLY, type, TailType.DOT));
} else if (method.findSuperMethods().length == 0) {
types.add(createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, TailType.DOT));
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.daemon;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.ide.scratch.ScratchFileType;
import com.intellij.openapi.roots.JavaProjectRootsUtil;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
@@ -36,8 +37,11 @@ public class JavaProblemHighlightFilter extends ProblemHighlightFilter {
if (shouldHighlight) {
if (psiFile.getFileType() == JavaFileType.INSTANCE) {
final VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile != null && ProjectRootManager.getInstance(psiFile.getProject()).getFileIndex().isInLibrarySource(virtualFile)) {
return false;
if (virtualFile != null) {
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(psiFile.getProject()).getFileIndex();
if (fileIndex.isInLibrarySource(virtualFile)) {
return fileIndex.isInSourceContent(virtualFile);
}
}
}
}
@@ -0,0 +1,45 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.editorActions.wordSelection;
import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandler;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiForStatement;
import com.intellij.psi.PsiForeachStatement;
import com.intellij.psi.PsiJavaToken;
import java.util.Collections;
import java.util.List;
public class ForStatementHeaderSelectioner implements ExtendWordSelectionHandler {
@Override
public boolean canSelect(PsiElement e) {
return e instanceof PsiForStatement || e instanceof PsiForeachStatement;
}
@Override
public List<TextRange> select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) {
PsiJavaToken lParen = e instanceof PsiForStatement ? ((PsiForStatement)e).getLParenth()
: e instanceof PsiForeachStatement ? ((PsiForeachStatement)e).getLParenth() : null;
PsiJavaToken rParen = e instanceof PsiForStatement ? ((PsiForStatement)e).getRParenth()
: e instanceof PsiForeachStatement ? ((PsiForeachStatement)e).getRParenth() : null;
if (lParen == null || rParen == null) return null;
TextRange result = new TextRange(lParen.getTextRange().getEndOffset(), rParen.getTextRange().getStartOffset());
return result.containsOffset(cursorOffset) ? Collections.singletonList(result) : null;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -40,8 +40,7 @@ public class MethodOrClassSelectioner extends BasicSelectioner {
@Override
public List<TextRange> select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) {
List<TextRange> result = ContainerUtil.newArrayList(e.getTextRange());
result.addAll(expandToWholeLinesWithBlanks(editorText, e.getTextRange()));
List<TextRange> result = ContainerUtil.newArrayList();
PsiElement firstChild = e.getFirstChild();
PsiElement[] children = e.getChildren();
@@ -77,6 +76,9 @@ public class MethodOrClassSelectioner extends BasicSelectioner {
result.addAll(expandToWholeLinesWithBlanks(editorText, range));
}
result.add(e.getTextRange());
result.addAll(expandToWholeLinesWithBlanks(editorText, e.getTextRange()));
if (e instanceof PsiClass) {
result.addAll(selectWithTypeParameters((PsiClass)e));
result.addAll(selectBetweenBracesLines(children, editorText));
@@ -21,7 +21,6 @@ import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -30,7 +29,9 @@ import org.jetbrains.java.generate.template.TemplateResource;
import org.jetbrains.java.generate.template.TemplatesManager;
import java.io.IOException;
import java.util.*;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Set;
@State(
name = "EqualsHashCodeTemplates",
@@ -42,14 +43,23 @@ import java.util.*;
public class EqualsHashCodeTemplatesManager extends TemplatesManager {
private static final String DEFAULT_EQUALS = "/com/intellij/codeInsight/generation/defaultEquals.vm";
private static final String DEFAULT_HASH_CODE = "/com/intellij/codeInsight/generation/defaultHashCode.vm";
private static final String APACHE3_EQUALS = "/com/intellij/codeInsight/generation/apacheEqualsBuilder3.vm";
private static final String APACHE3_HASH_CODE = "/com/intellij/codeInsight/generation/apacheHashCodeBuilder3.vm";
private static final String APACHE3_BUILDER = "org.apache.commons.lang3.builder.EqualsBuilder";
private static final String APACHE_EQUALS = "/com/intellij/codeInsight/generation/apacheEqualsBuilder.vm";
private static final String APACHE_HASH_CODE = "/com/intellij/codeInsight/generation/apacheHashCodeBuilder.vm";
private static final String APACHE_BUILDER = "org.apache.commons.lang.builder.EqualsBuilder";
private static final String GUAVA_EQUALS = "/com/intellij/codeInsight/generation/guavaEquals.vm";
private static final String GUAVA_HASH_CODE = "/com/intellij/codeInsight/generation/guavaHashCode.vm";
private static final String GUAVA_BUILDER = "com.google.common.base.Objects";
private static final String OBJECTS_EQUALS = "/com/intellij/codeInsight/generation/objectsEquals.vm";
private static final String OBJECTS_HASH_CODE = "/com/intellij/codeInsight/generation/objectsHashCode.vm";
private static final String OBJECTS_BUILDER = "java.util.Objects";
private static final String EQUALS_SUFFIX = "equals";
private static final String HASH_CODE_SUFFIX = "hashCode";
@@ -72,17 +82,17 @@ public class EqualsHashCodeTemplatesManager extends TemplatesManager {
new TemplateResource(toEqualsName(INTELLI_J_DEFAULT), readFile(DEFAULT_EQUALS), true),
new TemplateResource(toHashCodeName(INTELLI_J_DEFAULT), readFile(DEFAULT_HASH_CODE), true),
new TemplateResource(toEqualsName(EQUALS_HASH_CODE_BUILDER_APACHE_COMMONS_LANG), readFile(APACHE_EQUALS), true),
new TemplateResource(toHashCodeName(EQUALS_HASH_CODE_BUILDER_APACHE_COMMONS_LANG), readFile(APACHE_HASH_CODE), true),
new TemplateResource(toEqualsName(EQUALS_HASH_CODE_BUILDER_APACHE_COMMONS_LANG), readFile(APACHE_EQUALS), true, APACHE_BUILDER),
new TemplateResource(toHashCodeName(EQUALS_HASH_CODE_BUILDER_APACHE_COMMONS_LANG), readFile(APACHE_HASH_CODE), true, APACHE_BUILDER),
new TemplateResource(toEqualsName(EQUALS_HASH_CODE_BUILDER_APACHE_COMMONS_LANG_3), readFile(APACHE3_EQUALS), true),
new TemplateResource(toHashCodeName(EQUALS_HASH_CODE_BUILDER_APACHE_COMMONS_LANG_3), readFile(APACHE3_HASH_CODE), true),
new TemplateResource(toEqualsName(EQUALS_HASH_CODE_BUILDER_APACHE_COMMONS_LANG_3), readFile(APACHE3_EQUALS), true, APACHE3_BUILDER),
new TemplateResource(toHashCodeName(EQUALS_HASH_CODE_BUILDER_APACHE_COMMONS_LANG_3), readFile(APACHE3_HASH_CODE), true, APACHE3_BUILDER),
new TemplateResource(toEqualsName(OBJECTS_EQUAL_AND_HASH_CODE_GUAVA), readFile(GUAVA_EQUALS), true),
new TemplateResource(toHashCodeName(OBJECTS_EQUAL_AND_HASH_CODE_GUAVA), readFile(GUAVA_HASH_CODE), true),
new TemplateResource(toEqualsName(OBJECTS_EQUAL_AND_HASH_CODE_GUAVA), readFile(GUAVA_EQUALS), true, GUAVA_BUILDER),
new TemplateResource(toHashCodeName(OBJECTS_EQUAL_AND_HASH_CODE_GUAVA), readFile(GUAVA_HASH_CODE), true, GUAVA_BUILDER),
new TemplateResource(toEqualsName(JAVA_UTIL_OBJECTS_EQUALS_AND_HASH_CODE), readFile(OBJECTS_EQUALS), true),
new TemplateResource(toHashCodeName(JAVA_UTIL_OBJECTS_EQUALS_AND_HASH_CODE), readFile(OBJECTS_HASH_CODE), true)
new TemplateResource(toEqualsName(JAVA_UTIL_OBJECTS_EQUALS_AND_HASH_CODE), readFile(OBJECTS_EQUALS), true, OBJECTS_BUILDER),
new TemplateResource(toHashCodeName(JAVA_UTIL_OBJECTS_EQUALS_AND_HASH_CODE), readFile(OBJECTS_HASH_CODE), true, OBJECTS_BUILDER)
};
}
catch (IOException e) {
@@ -110,14 +120,6 @@ public class EqualsHashCodeTemplatesManager extends TemplatesManager {
return getDefaultTemplate(HASH_CODE_SUFFIX, EQUALS_SUFFIX, template);
}
public String[] getTemplateNames() {
final Set<String> names = new LinkedHashSet<String>();
for (TemplateResource resource : getAllTemplates()) {
names.add(getTemplateBaseName(resource));
}
return ArrayUtil.toStringArray(names);
}
@NotNull
public static String getTemplateBaseName(TemplateResource resource) {
return StringUtil.trimEnd(StringUtil.trimEnd(resource.getFileName(), EQUALS_SUFFIX), HASH_CODE_SUFFIX).trim();
@@ -29,18 +29,21 @@ import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.ComponentWithBrowseButton;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.classMembers.AbstractMemberInfoModel;
import com.intellij.refactoring.classMembers.MemberInfoBase;
import com.intellij.refactoring.classMembers.MemberInfoTooltipManager;
import com.intellij.refactoring.ui.AbstractMemberSelectionPanel;
import com.intellij.refactoring.ui.MemberSelectionPanel;
import com.intellij.refactoring.util.classMembers.MemberInfo;
import com.intellij.ui.JBColor;
import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.ui.NonFocusableCheckBox;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.java.generate.psi.PsiAdapter;
import org.jetbrains.java.generate.template.TemplateResource;
import javax.swing.*;
import java.awt.*;
@@ -265,7 +268,7 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
@Override
protected void addSteps() {
if (myEqualsPanel != null) {
addStep(new TemplateChooserStep(myClass.hasModifierProperty(PsiModifier.FINAL), myClass.getProject()));
addStep(new TemplateChooserStep(myClass.hasModifierProperty(PsiModifier.FINAL), myClass));
}
super.addSteps();
}
@@ -352,19 +355,19 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
private static class TemplateChooserStep extends StepAdapter {
private final JComponent myPanel;
private TemplateChooserStep(boolean isFinal, Project project) {
private TemplateChooserStep(boolean isFinal, PsiClass psiClass) {
myPanel = new JPanel(new VerticalFlowLayout());
final JPanel templateChooserPanel = new JPanel(new BorderLayout());
final JLabel templateChooserLabel = new JLabel(CodeInsightBundle.message("generate.equals.hashcode.template"));
templateChooserPanel.add(templateChooserLabel, BorderLayout.WEST);
final ComboBox comboBox = new ComboBox();
final ComponentWithBrowseButton<ComboBox> comboBoxWithBrowseButton =
new ComponentWithBrowseButton<ComboBox>(comboBox, new MyEditTemplatesListener(project, myPanel, comboBox));
new ComponentWithBrowseButton<ComboBox>(comboBox, new MyEditTemplatesListener(psiClass, myPanel, comboBox));
templateChooserLabel.setLabelFor(comboBox);
final EqualsHashCodeTemplatesManager manager = EqualsHashCodeTemplatesManager.getInstance();
comboBox.setModel(new DefaultComboBoxModel(manager.getTemplateNames()));
comboBox.setSelectedItem(manager.getDefaultTemplateBaseName());
setupCombobox(manager, comboBox, psiClass);
comboBox.addActionListener(new ActionListener() {
public void actionPerformed(@NotNull final ActionEvent M) {
manager.setDefaultTemplate((String)comboBox.getSelectedItem());
@@ -400,13 +403,43 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
return myPanel;
}
private static void setupCombobox(EqualsHashCodeTemplatesManager templatesManager,
ComboBox comboBox,
PsiClass psiClass) {
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(psiClass.getProject());
final GlobalSearchScope resolveScope = psiClass.getResolveScope();
final Set<String> names = new LinkedHashSet<String>();
final Set<String> invalid = new HashSet<String>();
for (TemplateResource resource : templatesManager.getAllTemplates()) {
final String templateBaseName = EqualsHashCodeTemplatesManager.getTemplateBaseName(resource);
if (names.add(templateBaseName)) {
final String className = resource.getClassName();
if (className != null && psiFacade.findClass(className, resolveScope) == null) {
invalid.add(templateBaseName);
}
}
}
comboBox.setRenderer(new ListCellRendererWrapper<String>() {
@Override
public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) {
setText(value);
if (invalid.contains(value)) {
setForeground(JBColor.RED);
}
}
});
comboBox.setModel(new DefaultComboBoxModel(names.toArray(new String[names.size()])));
comboBox.setSelectedItem(templatesManager.getDefaultTemplateBaseName());
}
private static class MyEditTemplatesListener implements ActionListener {
private final Project myProject;
private final PsiClass myPsiClass;
private final JComponent myParent;
private final ComboBox myComboBox;
public MyEditTemplatesListener(Project project, JComponent panel, ComboBox comboBox) {
myProject = project;
public MyEditTemplatesListener(PsiClass psiClass, JComponent panel, ComboBox comboBox) {
myPsiClass = psiClass;
myParent = panel;
myComboBox = comboBox;
}
@@ -414,11 +447,10 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
@Override
public void actionPerformed(ActionEvent e) {
final EqualsHashCodeTemplatesManager templatesManager = EqualsHashCodeTemplatesManager.getInstance();
final EqualsHashCodeTemplatesPanel ui = new EqualsHashCodeTemplatesPanel(myProject, EqualsHashCodeTemplatesManager.getInstance());
final EqualsHashCodeTemplatesPanel ui = new EqualsHashCodeTemplatesPanel(myPsiClass.getProject(), EqualsHashCodeTemplatesManager.getInstance());
ui.selectNodeInTree(templatesManager.getDefaultTemplateBaseName());
ShowSettingsUtil.getInstance().editConfigurable(myParent, ui);
myComboBox.setModel(new DefaultComboBoxModel(templatesManager.getTemplateNames()));
myComboBox.setSelectedItem(templatesManager.getDefaultTemplateBaseName());
setupCombobox(templatesManager, myComboBox, myPsiClass);
}
}
}
@@ -26,6 +26,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.RefactoringActionHandler;
import com.intellij.refactoring.RefactoringBundle;
@@ -140,20 +141,21 @@ public class ExtractInterfaceHandler implements RefactoringActionHandler, Elemen
String interfaceName,
MemberInfo[] selectedMembers,
DocCommentPolicy javaDocPolicy) throws IncorrectOperationException {
aClass.getProject().getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC)
final Project project = aClass.getProject();
project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC)
.refactoringStarted(ExtractSuperClassUtil.REFACTORING_EXTRACT_SUPER_ID, ExtractSuperClassUtil.createBeforeData(aClass, selectedMembers));
final PsiClass anInterface = JavaDirectoryService.getInstance().createInterface(targetDir, interfaceName);
try {
PsiJavaCodeReferenceElement ref = ExtractSuperClassUtil.createExtendingReference(anInterface, aClass, selectedMembers);
final PsiReferenceList referenceList = aClass.isInterface() ? aClass.getExtendsList() : aClass.getImplementsList();
assert referenceList != null;
referenceList.add(ref);
CodeStyleManager.getInstance(project).reformat(referenceList.add(ref));
PullUpProcessor pullUpHelper = new PullUpProcessor(aClass, anInterface, selectedMembers, javaDocPolicy);
pullUpHelper.moveMembersToBase();
return anInterface;
}
finally {
aClass.getProject().getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC)
project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC)
.refactoringDone(ExtractSuperClassUtil.REFACTORING_EXTRACT_SUPER_ID, ExtractSuperClassUtil.createAfterData(anInterface));
}
}
@@ -95,10 +95,11 @@ public class ExtractSuperClassUtil {
// make original class extend extracted superclass
PsiJavaCodeReferenceElement ref = createExtendingReference(superclass, subclass, selectedMemberInfos);
final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
if (subClassExtends != null) {
subclass.getExtendsList().add(ref);
codeStyleManager.reformat(subclass.getExtendsList().add(ref));
} else if (subclass instanceof PsiAnonymousClass) {
((PsiAnonymousClass)subclass).getBaseClassReference().replace(ref);
codeStyleManager.reformat(((PsiAnonymousClass)subclass).getBaseClassReference().replace(ref));
}
PullUpProcessor pullUpHelper = new PullUpProcessor(subclass, superclass, selectedMemberInfos,
@@ -302,7 +302,11 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
final InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(project);
PsiElement elementAtStart = file.findElementAt(startOffset);
if (elementAtStart == null || elementAtStart instanceof PsiWhiteSpace || elementAtStart instanceof PsiComment) {
elementAtStart = PsiTreeUtil.skipSiblingsForward(elementAtStart, PsiWhiteSpace.class, PsiComment.class);
final PsiElement element = PsiTreeUtil.skipSiblingsForward(elementAtStart, PsiWhiteSpace.class, PsiComment.class);
if (element != null) {
startOffset = element.getTextOffset();
elementAtStart = file.findElementAt(startOffset);
}
if (elementAtStart == null) {
if (injectedLanguageManager.isInjectedFragment(file)) {
return getSelectionFromInjectedHost(project, file, injectedLanguageManager, startOffset, endOffset);
@@ -323,6 +327,11 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
PsiElement elementAt = PsiTreeUtil.findCommonParent(elementAtStart, elementAtEnd);
final PsiExpression containingExpression = PsiTreeUtil.getParentOfType(elementAt, PsiExpression.class, false);
if (containingExpression != null && containingExpression == elementAtEnd && startOffset == containingExpression.getTextOffset()) {
return containingExpression;
}
if (containingExpression == null || containingExpression instanceof PsiLambdaExpression) {
if (injectedLanguageManager.isInjectedFragment(file)) {
return getSelectionFromInjectedHost(project, file, injectedLanguageManager, startOffset, endOffset);
@@ -17,7 +17,6 @@ package com.intellij.refactoring.memberPushDown;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.ChangeContextUtil;
import com.intellij.codeInsight.generation.OverrideImplementExploreUtil;
import com.intellij.codeInsight.generation.OverrideImplementUtil;
import com.intellij.codeInsight.intention.impl.CreateClassDialog;
import com.intellij.codeInsight.intention.impl.CreateSubclassAction;
@@ -319,13 +318,6 @@ public class PushDownProcessor extends BaseRefactoringProcessor {
}
private void decodeRefs(final PsiMember member, final PsiClass targetClass) {
try {
ChangeContextUtil.decodeContextInfo(member, null, null);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
final PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory();
member.accept(new JavaRecursiveElementWalkingVisitor() {
@Override public void visitReferenceExpression(PsiReferenceExpression expression) {
@@ -47,7 +47,7 @@ public class SafeDeleteExtendsClassUsageInfo extends SafeDeleteReferenceUsageInf
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(refClass.getProject()).getElementFactory();
final PsiReferenceList extendsList = refClass.getExtendsList();
final PsiReferenceList extendingImplementsList = myExtendingClass.getImplementsList();
final PsiReferenceList extendingImplementsList = myExtendingClass instanceof PsiTypeParameter ? myExtendingClass.getExtendsList() : myExtendingClass.getImplementsList();
if (extendsList != null) {
final PsiClassType[] referenceTypes = extendsList.getReferencedTypes();
final PsiReferenceList listToAddExtends = refClass.isInterface() == myExtendingClass.isInterface() || myExtendingClass instanceof PsiTypeParameter ? myExtendingClass.getExtendsList() : extendingImplementsList;
@@ -154,12 +154,26 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager {
final Set<PsiClass> occurrenceClasses = new HashSet<PsiClass>();
for (final PsiExpression occurrence : myOccurrences) {
final PsiType occurrenceType = occurrence.getType();
collectOccurrenceClasses(occurrenceClasses, occurrenceType);
}
return new ExpectedTypeUtil.ExpectedClassesFromSetProvider(occurrenceClasses);
}
private static void collectOccurrenceClasses(Set<PsiClass> occurrenceClasses, PsiType occurrenceType) {
if (occurrenceType instanceof PsiIntersectionType) {
for (PsiType type : ((PsiIntersectionType)occurrenceType).getConjuncts()) {
collectOccurrenceClasses(occurrenceClasses, type);
}
}
else if (occurrenceType instanceof PsiCapturedWildcardType) {
collectOccurrenceClasses(occurrenceClasses, ((PsiCapturedWildcardType)occurrenceType).getUpperBound());
}
else {
final PsiClass aClass = PsiUtil.resolveClassInType(occurrenceType);
if (aClass != null) {
occurrenceClasses.add(aClass);
}
}
return new ExpectedTypeUtil.ExpectedClassesFromSetProvider(occurrenceClasses);
}
private PsiType[] getTypesForMain() {
@@ -46,10 +46,7 @@ import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
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.refactoring.PackageWrapper;
import com.intellij.refactoring.introduceField.ElementToWorkOn;
import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
@@ -389,14 +386,18 @@ public class RefactoringUtil {
PsiElementFactory factory = JavaPsiFacade.getInstance(expr.getProject()).getElementFactory();
PsiType type = getTypeByExpression(expr, factory);
final boolean isFunctionalType = type instanceof PsiLambdaExpressionType || type instanceof PsiMethodReferenceType || type instanceof PsiLambdaParameterType;
if (type != null && !isFunctionalType) {
final boolean isDenotable = PsiTypesUtil.isDenotableType(expr.getType());
if (type != null && !isFunctionalType && isDenotable) {
return type;
}
ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getInstance(expr.getProject()).getExpectedTypes(expr, false);
if (expectedTypes.length == 1 || isFunctionalType && expectedTypes.length > 0) {
if (expectedTypes.length == 1 || (isFunctionalType || !isDenotable)&& expectedTypes.length > 0 ) {
type = expectedTypes[0].getType();
if (!type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) return type;
}
if (!isDenotable) {
return type;
}
return null;
}
@@ -23,10 +23,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
public class MethodSignatureUtil {
@@ -323,20 +320,16 @@ public class MethodSignatureUtil {
result = result.put(superTypeParameters[i], factory.createType(methodTypeParameter));
}
final PsiSubstitutor methodSubstitutor = methodSignature.getSubstitutor();
//check bounds
for (int i = 0; i < methodTypeParameters.length; i++) {
PsiTypeParameter methodTypeParameter = methodTypeParameters[i];
PsiTypeParameter superTypeParameter = superTypeParameters[i];
final Set<PsiType> methodSupers = new HashSet<PsiType>();
for (PsiClassType methodSuper : methodTypeParameter.getSuperTypes()) {
methodSupers.add(methodSubstitutor.substitute(methodSuper));
}
Collections.addAll(methodSupers, methodTypeParameter.getSuperTypes());
final Set<PsiType> superSupers = new HashSet<PsiType>();
for (PsiClassType superSuper : superTypeParameter.getSuperTypes()) {
superSupers.add(methodSubstitutor.substitute(result.substitute(superSuper)));
superSupers.add(result.substitute(superSuper));
}
methodSupers.remove(PsiType.getJavaLangObject(methodTypeParameter.getManager(), methodTypeParameter.getResolveScope()));
superSupers.remove(PsiType.getJavaLangObject(superTypeParameter.getManager(), superTypeParameter.getResolveScope()));
@@ -207,8 +207,8 @@ public class PsiSuperMethodImplUtil {
}
if (nameHint != null && !nameHint.equals(method.getName())) continue;
if (!includePrivates && method.hasModifierProperty(PsiModifier.PRIVATE)) continue;
final MethodSignatureBackedByPsiMethod signature = MethodSignatureBackedByPsiMethod.create(method, substitutor, isInRawContext);
HierarchicalMethodSignatureImpl newH = new HierarchicalMethodSignatureImpl(signature);
final MethodSignatureBackedByPsiMethod signature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY, isInRawContext);
HierarchicalMethodSignatureImpl newH = new HierarchicalMethodSignatureImpl(MethodSignatureBackedByPsiMethod.create(method, substitutor, isInRawContext));
List<PsiMethod> list = sameParameterErasureMethods.get(signature);
if (list == null) {
@@ -238,7 +238,7 @@ public class PsiSuperMethodImplUtil {
List<Pair<MethodSignature, HierarchicalMethodSignature>> flattened = new ArrayList<Pair<MethodSignature, HierarchicalMethodSignature>>();
for (Map.Entry<MethodSignature, HierarchicalMethodSignature> entry : superResult.entrySet()) {
HierarchicalMethodSignature hms = entry.getValue();
MethodSignature signature = entry.getKey();
MethodSignature signature = MethodSignatureBackedByPsiMethod.create(hms.getMethod(), hms.getSubstitutor(), hms.isRaw());
PsiClass containingClass = hms.getMethod().getContainingClass();
List<HierarchicalMethodSignature> supers = new ArrayList<HierarchicalMethodSignature>(hms.getSuperSignatures());
for (HierarchicalMethodSignature aSuper : supers) {
@@ -0,0 +1,45 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.impl.source.resolve.graphInference;
import com.intellij.psi.PsiCall;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiSubstitutor;
import java.util.Map;
class CompoundInitialState {
private PsiSubstitutor myInitialSubstitutor;
private Map<PsiElement, InitialInferenceState> myInitialStates;
CompoundInitialState(PsiSubstitutor initialSubstitutor,
Map<PsiElement, InitialInferenceState> initialStates) {
myInitialSubstitutor = initialSubstitutor;
myInitialStates = initialStates;
}
PsiSubstitutor getInitialSubstitutor() {
return myInitialSubstitutor;
}
Map<PsiElement, InitialInferenceState> getInitialStates() {
return myInitialStates;
}
InitialInferenceState getInitialState(PsiCall call) {
return myInitialStates.get(call);
}
}
@@ -167,7 +167,7 @@ public class InferenceIncorporationPhase {
for (PsiType lowerBound : lowerBounds) {
if (mySession.getInferenceVariable(lowerBound) == null) {
addConstraint(new StrictSubtypingConstraint(lowerBound, superBound));
addConstraint(new StrictSubtypingConstraint(superBound, lowerBound));
}
}
}
@@ -156,6 +156,11 @@ public class InferenceSession {
}
if (parameters.length > 0) {
for (int i = 0; i < args.length; i++) {
//don't infer anything if number of parameters differ and method is not vararg
if (!varargs && i >= parameters.length) {
continue;
}
if (args[i] != null && isPertinentToApplicability(args[i], method)) {
PsiType parameterType = getParameterType(parameters, i, mySiteSubstitutor, varargs);
addConstraint(new ExpressionCompatibilityConstraint(args[i], substituteWithInferenceVariables(parameterType)));
@@ -406,9 +411,8 @@ public class InferenceSession {
}
}
}
final InferenceSession nestedCallSession = myInferenceSessionContainer.findNestedCallSession(arg, this);
final PsiType parameterType =
nestedCallSession.substituteWithInferenceVariables(getParameterType(parameters, i, siteSubstitutor, varargs));
final PsiSubstitutor nestedSubstitutor = myInferenceSessionContainer.findNestedSubstitutor(arg, myInferenceSubstitution);
final PsiType parameterType = nestedSubstitutor.substitute(getParameterType(parameters, i, siteSubstitutor, varargs));
if (!isPertinentToApplicability(arg, parentMethod)) {
additionalConstraints.add(new ExpressionCompatibilityConstraint(arg, parameterType));
}
@@ -584,13 +588,14 @@ public class InferenceSession {
return mySiteSubstitutor;
}
public InitialInferenceState createInitialState() {
return new InitialInferenceState(myInferenceVariables,
public InitialInferenceState createInitialState(InferenceSessionContainer container, PsiSubstitutor topInferenceSubstitutor) {
return new InitialInferenceState(myInferenceVariables,
topInferenceSubstitutor,
myContext,
myInferenceSubstitution,
mySiteSubstitutor,
myIncorporationPhase.getCaptures(),
myInferenceSessionContainer);
container);
}
public void initBounds(PsiTypeParameter... typeParameters) {
@@ -669,7 +674,7 @@ public class InferenceSession {
}
substitutedCapture = elementFactory.createType(psiClass, newParameters);
myIncorporationPhase.addCapture(copy, substitutedCapture);
myIncorporationPhase.addCapture(copy, (PsiClassType)returnType);
addConstraint(new TypeCompatibilityConstraint(targetType, substitutedCapture));
}
} else {
@@ -848,6 +853,17 @@ public class InferenceSession {
public boolean collectDependencies(@Nullable PsiType type,
@Nullable final Set<InferenceVariable> dependencies) {
return collectDependencies(type, dependencies, new Function<PsiClassType, InferenceVariable>() {
@Override
public InferenceVariable fun(PsiClassType classType) {
return getInferenceVariable(classType);
}
});
}
public static boolean collectDependencies(@Nullable PsiType type,
@Nullable final Set<InferenceVariable> dependencies,
final Function<PsiClassType, InferenceVariable> fun) {
if (type == null) return true;
final Boolean isProper = type.accept(new PsiTypeVisitor<Boolean>() {
@Nullable
@@ -879,7 +895,7 @@ public class InferenceSession {
@Nullable
@Override
public Boolean visitClassType(PsiClassType classType) {
final InferenceVariable inferenceVariable = getInferenceVariable(classType);
final InferenceVariable inferenceVariable = fun.fun(classType);
if (inferenceVariable != null) {
if (dependencies != null) {
dependencies.add(inferenceVariable);
@@ -1727,6 +1743,10 @@ public class InferenceSession {
return myInferenceSubstitution.substitute(type);
}
public PsiSubstitutor getInferenceSubstitution() {
return myInferenceSubstitution;
}
public InferenceSessionContainer getInferenceSessionContainer() {
return myInferenceSessionContainer;
}
@@ -1790,4 +1810,8 @@ public class InferenceSession {
public List<String> getIncompatibleErrorMessages() {
return myErrorMessages;
}
public boolean isErased() {
return myErased;
}
}
@@ -17,21 +17,15 @@ package com.intellij.psi.impl.source.resolve.graphInference;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.graphInference.constraints.ExpressionCompatibilityConstraint;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.*;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.*;
public class InferenceSessionContainer {
private static final Logger LOG = Logger.getInstance("#" + InferenceSessionContainer.class.getName());
@@ -46,15 +40,15 @@ public class InferenceSessionContainer {
}
@Contract("_, !null -> !null")
public InferenceSession findNestedCallSession(PsiElement arg, @Nullable InferenceSession defaultSession) {
public PsiSubstitutor findNestedSubstitutor(PsiElement arg, @Nullable PsiSubstitutor defaultSession) {
InferenceSession session = myNestedSessions.get(PsiTreeUtil.getParentOfType(arg, PsiCall.class));
return session == null ? defaultSession : session;
return session == null ? defaultSession : session.getInferenceSubstitution();
}
public void registerNestedSession(InferenceSession session,
PsiType returnType,
PsiExpression returnExpression) {
final InferenceSession callSession = findNestedCallSession(((PsiCallExpression)returnExpression).getArgumentList(), null);
void registerNestedSession(InferenceSession session,
PsiType returnType,
PsiExpression returnExpression) {
final PsiSubstitutor callSession = findNestedSubstitutor(((PsiCallExpression)returnExpression).getArgumentList(), null);
if (callSession == null) {
final InferenceSession inferenceSession =
ExpressionCompatibilityConstraint.reduceExpressionCompatibilityConstraint(session, returnExpression, returnType);
@@ -73,19 +67,29 @@ public class InferenceSessionContainer {
final PsiExpressionList argumentList = ((PsiCall)parent).getArgumentList();
final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(argumentList);
if (properties != null && !properties.isApplicabilityCheck()) {
final Pair<PsiSubstitutor, Map<PsiElement, InitialInferenceState>>
session = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(parent, false,
new Computable<Pair<PsiSubstitutor, Map<PsiElement, InitialInferenceState>>>() {
@Override
public Pair<PsiSubstitutor, Map<PsiElement, InitialInferenceState>> compute() {
return createValue(parent);
}
});
final InferenceSession session = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(parent, false,
new Computable<InferenceSession>() {
@Override
public InferenceSession compute() {
if (MethodCandidateInfo.isOverloadCheck()) {
return startTopLevelInference(parent);
}
return CachedValuesManager.getCachedValue(parent,
new CachedValueProvider<InferenceSession>() {
@Nullable
@Override
public Result<InferenceSession> compute() {
return new Result<InferenceSession>(startTopLevelInference(parent), PsiModificationTracker.MODIFICATION_COUNT);
}
});
}
});
if (session != null) {
final InitialInferenceState initialInferenceState = session.second.get(PsiTreeUtil.getParentOfType(argumentList, PsiCall.class));
final CompoundInitialState compoundInitialState = createState(session);
final InitialInferenceState initialInferenceState = compoundInitialState.getInitialState(PsiTreeUtil.getParentOfType(argumentList, PsiCall.class));
if (initialInferenceState != null) {
return new InferenceSession(initialInferenceState).collectAdditionalAndInfer(parameters, arguments, properties, session.first);
return new InferenceSession(initialInferenceState)
.collectAdditionalAndInfer(parameters, arguments, properties, compoundInitialState.getInitialSubstitutor());
}
}
}
@@ -95,23 +99,41 @@ public class InferenceSessionContainer {
inferenceSession.initExpressionConstraints(parameters, arguments, parent, null);
return inferenceSession.infer(parameters, arguments, parent);
}
private static CompoundInitialState createState(InferenceSession topLevelSession) {
final PsiSubstitutor topInferenceSubstitutor = replaceVariables(topLevelSession.getInferenceVariables());
final Map<PsiElement, InitialInferenceState> nestedStates = new LinkedHashMap<PsiElement, InitialInferenceState>();
private static Pair<PsiSubstitutor, Map<PsiElement, InitialInferenceState>> createValue(@NotNull final PsiElement parent) {
if (MethodCandidateInfo.isOverloadCheck()) {
return startTopLevelInference(parent);
final InferenceSessionContainer copy = new InferenceSessionContainer() {
@Override
public PsiSubstitutor findNestedSubstitutor(PsiElement arg, @Nullable PsiSubstitutor defaultSession) {
final InitialInferenceState state = nestedStates.get(PsiTreeUtil.getParentOfType(arg, PsiCall.class));
if (state != null) {
return state.getInferenceSubstitutor();
}
return super.findNestedSubstitutor(arg, defaultSession);
}
};
final Map<PsiElement, InferenceSession> nestedSessions = topLevelSession.getInferenceSessionContainer().myNestedSessions;
for (Map.Entry<PsiElement, InferenceSession> entry : nestedSessions.entrySet()) {
nestedStates.put(entry.getKey(), entry.getValue().createInitialState(copy, topInferenceSubstitutor));
}
return CachedValuesManager.getCachedValue(parent,
new CachedValueProvider<Pair<PsiSubstitutor, Map<PsiElement, InitialInferenceState>>>() {
@Nullable
@Override
public Result<Pair<PsiSubstitutor, Map<PsiElement, InitialInferenceState>>> compute() {
return new Result<Pair<PsiSubstitutor, Map<PsiElement, InitialInferenceState>>>(
startTopLevelInference(parent), PsiModificationTracker.MODIFICATION_COUNT);
}
});
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
for (InferenceVariable variable : topLevelSession.getInferenceVariables()) {
final PsiType instantiation = variable.getInstantiation();
if (instantiation != PsiType.NULL) {
final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(topInferenceSubstitutor.substitute(variable));
if (psiClass instanceof InferenceVariable) {
substitutor = substitutor.put((PsiTypeParameter)psiClass, instantiation);
}
}
}
return new CompoundInitialState(substitutor, nestedStates);
}
private static Pair<PsiSubstitutor, Map<PsiElement, InitialInferenceState>> startTopLevelInference(@NotNull final PsiElement parent) {
private static InferenceSession startTopLevelInference(@NotNull final PsiElement parent) {
final PsiCall topLevelCall = treeWalkUp(parent);
if (topLevelCall != null) {
final JavaResolveResult result = topLevelCall.resolveMethodGenerics();
@@ -125,28 +147,38 @@ public class InferenceSessionContainer {
new InferenceSession(method.getTypeParameters(), ((MethodCandidateInfo)result).getSiteSubstitutor(), topLevelCall.getManager(), topLevelCall);
topLevelSession.initExpressionConstraints(topLevelParameters, topLevelArguments, topLevelCall, method, ((MethodCandidateInfo)result).isVarargs());
topLevelSession.infer(topLevelParameters, topLevelArguments, topLevelCall, ((MethodCandidateInfo)result).createProperties());
final Map<PsiElement, InferenceSession> nestedSessions = topLevelSession.getInferenceSessionContainer().myNestedSessions;
Map<PsiElement, InitialInferenceState> nestedStates = new LinkedHashMap<PsiElement, InitialInferenceState>();
for (Map.Entry<PsiElement, InferenceSession> entry : nestedSessions.entrySet()) {
nestedStates.put(entry.getKey(), entry.getValue().createInitialState());
}
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
for (InferenceVariable variable : topLevelSession.getInferenceVariables()) {
final PsiType instantiation = variable.getInstantiation();
if (instantiation != PsiType.NULL) {
substitutor = substitutor.put(variable, instantiation);
}
}
return Pair.create(substitutor, nestedStates);
return topLevelSession;
}
}
return null;
}
@NotNull
private static PsiSubstitutor replaceVariables(Collection<InferenceVariable> inferenceVariables) {
final List<InferenceVariable> targetVars = new ArrayList<InferenceVariable>();
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
final InferenceVariable[] oldVars = inferenceVariables.toArray(new InferenceVariable[inferenceVariables.size()]);
for (InferenceVariable variable : oldVars) {
final InferenceVariable newVariable = new InferenceVariable(variable.getCallContext(), variable.getParameter());
substitutor = substitutor.put(variable, JavaPsiFacade.getElementFactory(variable.getProject()).createType(newVariable));
targetVars.add(newVariable);
if (variable.isThrownBound()) {
newVariable.setThrownBound();
}
}
for (int i = 0; i < targetVars.size(); i++) {
InferenceVariable var = targetVars.get(i);
for (InferenceBound boundType : InferenceBound.values()) {
for (PsiType bound : oldVars[i].getBounds(boundType)) {
var.addBound(substitutor.substitute(bound), boundType);
}
}
}
return substitutor;
}
@Nullable
private static PsiCall treeWalkUp(PsiElement context) {
if (context instanceof PsiExpression && !PsiPolyExpressionUtil.isPolyExpression((PsiExpression)context)) {
@@ -17,12 +17,14 @@ package com.intellij.psi.impl.source.resolve.graphInference;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import com.intellij.psi.util.PsiUtil;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class InitialInferenceState {
class InitialInferenceState {
private final Set<InferenceVariable> myInferenceVariables;
private final PsiElement myContext;
@@ -31,48 +33,48 @@ public class InitialInferenceState {
private final List<Pair<PsiTypeParameter[], PsiClassType>> myCaptures;
private final InferenceSessionContainer myInferenceSessionContainer;
public InitialInferenceState(Set<InferenceVariable> inferenceVariables,
PsiElement context,
PsiSubstitutor inferenceSubstitutor,
PsiSubstitutor siteSubstitutor,
List<Pair<PsiTypeParameter[], PsiClassType>> captures,
InferenceSessionContainer inferenceSessionContainer) {
myInferenceVariables = inferenceVariables;
myContext = context;
myInferenceSubstitutor = inferenceSubstitutor;
mySiteSubstitutor = siteSubstitutor;
myCaptures = captures;
myInferenceSessionContainer = inferenceSessionContainer;
}
@NotNull
static PsiSubstitutor copyVariables(List<InferenceVariable> targetVars,
Set<InferenceVariable> inferenceVariables,
PsiElement context) {
InitialInferenceState(Set<InferenceVariable> inferenceVariables,
PsiSubstitutor topInferenceSubstitutor,
PsiElement context,
PsiSubstitutor inferenceSubstitutor,
PsiSubstitutor siteSubstitutor,
List<Pair<PsiTypeParameter[], PsiClassType>> captures,
InferenceSessionContainer inferenceSessionContainer) {
myInferenceVariables = new HashSet<InferenceVariable>();
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
final InferenceVariable[] oldVars = inferenceVariables.toArray(new InferenceVariable[inferenceVariables.size()]);
for (InferenceVariable variable : oldVars) {
final InferenceVariable newVariable = new InferenceVariable(context, variable.getParameter());
substitutor = substitutor.put(variable, JavaPsiFacade.getElementFactory(variable.getProject()).createType(newVariable));
targetVars.add(newVariable);
}
for (int i = 0; i < targetVars.size(); i++) {
InferenceVariable var = targetVars.get(i);
for (InferenceBound boundType : InferenceBound.values()) {
for (PsiType bound : oldVars[i].getBounds(boundType)) {
var.addBound(substitutor.substitute(bound), boundType);
PsiSubstitutor subst = PsiSubstitutor.EMPTY;
for (InferenceVariable variable : inferenceVariables) {
final PsiType substitute = topInferenceSubstitutor.substitute(variable);
final PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(substitute);
if (aClass instanceof InferenceVariable) {
myInferenceVariables.add((InferenceVariable)aClass);
if (inferenceSubstitutor.getSubstitutionMap().containsValue(PsiSubstitutor.EMPTY.substitute(variable))) {
substitutor = substitutor.put(variable.getParameter(), substitute);
subst = subst.put(variable, substitute);
}
}
}
return substitutor;
myInferenceSubstitutor = substitutor;
myContext = context;
mySiteSubstitutor = siteSubstitutor;
myCaptures = new ArrayList<Pair<PsiTypeParameter[], PsiClassType>>();
for (Pair<PsiTypeParameter[], PsiClassType> capture : captures) {
PsiTypeParameter[] newParameters = new PsiTypeParameter[capture.first.length];
PsiTypeParameter[] parameters = capture.first;
for (int i = 0; i < parameters.length; i++) {
final PsiType substitute = topInferenceSubstitutor.substitute(parameters[i]);
newParameters[i] = (PsiTypeParameter)PsiUtil.resolveClassInClassTypeOnly(substitute);
}
myCaptures.add(Pair.create(newParameters, (PsiClassType)subst.substitute(capture.second)));
}
myInferenceSessionContainer = inferenceSessionContainer;
}
public InferenceSessionContainer getInferenceSessionContainer() {
InferenceSessionContainer getInferenceSessionContainer() {
return myInferenceSessionContainer;
}
public Set<InferenceVariable> getInferenceVariables() {
Set<InferenceVariable> getInferenceVariables() {
return myInferenceVariables;
}
@@ -80,11 +82,11 @@ public class InitialInferenceState {
return myContext;
}
public PsiSubstitutor getInferenceSubstitutor() {
PsiSubstitutor getInferenceSubstitutor() {
return myInferenceSubstitutor;
}
public PsiSubstitutor getSiteSubstitutor() {
PsiSubstitutor getSiteSubstitutor() {
return mySiteSubstitutor;
}
@@ -56,8 +56,14 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
return false;
}
if (exprType instanceof PsiClassType && ((PsiClassType)exprType).resolve() == null) {
return true;
if (exprType instanceof PsiClassType) {
if (((PsiClassType)exprType).resolve() == null) {
return true;
}
if (((PsiClassType)exprType).isRaw()) {
session.setErased();
}
}
if (exprType != null && exprType != PsiType.NULL) {
@@ -94,6 +100,9 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
if (callSession != session) {
session.getInferenceSessionContainer().registerNestedSession(callSession);
session.propagateVariables(callSession.getInferenceVariables());
if (callSession.isErased()) {
session.setErased();
}
}
return true;
}
@@ -4,9 +4,11 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.Function;
import java.util.List;
@@ -76,9 +78,16 @@ public class LambdaExpressionCompatibilityConstraint implements ConstraintFormul
session.registerIncompatibleErrorMessage("Incompatible types: expected not void but the lambda body is a block that is not value-compatible");
return false;
}
InferenceSession callsession = session.getInferenceSessionContainer().findNestedCallSession(myExpression, session);
returnType = callsession.substituteWithInferenceVariables(substitutor.substitute(returnType));
if (!callsession.isProperType(returnType)) {
final PsiSubstitutor nestedSubstitutor = session.getInferenceSessionContainer().findNestedSubstitutor(myExpression, session.getInferenceSubstitution());
returnType = nestedSubstitutor.substitute(substitutor.substitute(returnType));
boolean isProperType = InferenceSession.collectDependencies(returnType, null, new Function<PsiClassType, InferenceVariable>() {
@Override
public InferenceVariable fun(PsiClassType type) {
final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(type);
return psiClass instanceof InferenceVariable && nestedSubstitutor.getSubstitutionMap().containsValue(type) ? (InferenceVariable)psiClass : null;
}
});
if (!isProperType) {
for (PsiExpression returnExpression : returnExpressions) {
constraints.add(new ExpressionCompatibilityConstraint(returnExpression, returnType));
}
@@ -32,6 +32,7 @@ public class StrictSubtypingConstraint implements ConstraintFormula {
private PsiType myS;
private PsiType myT;
//t < s
public StrictSubtypingConstraint(PsiType t, PsiType s) {
myT = t;
myS = s;
@@ -675,12 +675,6 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
}
}
final boolean raw1 = PsiUtil.isRawSubstitutor(method1, classSubstitutor1);
final boolean raw2 = PsiUtil.isRawSubstitutor(method2, classSubstitutor2);
if (raw1 ^ raw2) {
return raw1 ? Specifics.SECOND : Specifics.FIRST;
}
final boolean varargs1 = info1.isVarargs();
final boolean varargs2 = info2.isVarargs();
if (varargs1 ^ varargs2) {
@@ -0,0 +1,15 @@
import java.util.List;
class Main {
static List<? extends Child> foo() {
return get ();
}
static <T extends Base> List<? extends T> get() {
return null;
}
static class Base {}
static class Child extends Base {}
}
@@ -0,0 +1,14 @@
interface Item<K, V>{}
interface Holder<A, B> {
boolean apply(Item<? extends A, ? extends B> i);
}
class C {
void f(Holder<?,?> h) {
h.apply(create());
}
private <L, M> Item<L,M> create() {
return null;
}
}
@@ -0,0 +1,22 @@
import java.util.List;
class Temp<K> {
public static List<String> foo() {
return parallelizePairs(asList(new Tuple())).partitionBy();
}
public static <T> List<T> asList(T a) {
return null;
}
public static <K> Temp<K> parallelizePairs(List<Tuple<K>> list) {
return null;
}
public List<K> partitionBy() { return null; }
}
class Tuple<A> {
public Tuple() {}
}
@@ -0,0 +1,15 @@
import java.util.concurrent.Callable;
class Test {
public void test() {
Foo<String> f = new Foo<>(() -> "this doesn't compile");
}
public class Foo<T> {
public Foo(Callable<T> supplier) {
}
public Foo(T value) {
}
}
}
@@ -0,0 +1,17 @@
import java.util.function.Supplier;
class LazyVal<T> {
public LazyVal(Supplier<T> supplier) {}
public LazyVal(T value) {}
}
class Sample {
String getString() {
return "";
}
public void usage() {
new LazyVal<>(() -> new Sample().getString());
}
}
@@ -0,0 +1,15 @@
import java.util.Collection;
import java.util.Set;
import java.util.function.Function;
class Test {
{
Set<Class<? extends Throwable>> exceptions = null;
transform(exceptions, x -> x.getSimpleName());
}
public static <F, T> Collection<T> transform(Collection<F> fromCollection, Function<? super F, T> function) {
return null;
}
}
@@ -0,0 +1,14 @@
import java.util.List;
import java.util.Set;
abstract class Test {
public void foo(List list) {
set<error descr="Ambiguous method call: both 'Test.set(Set<List>, List)' and 'Test.set(Set, List)' match">(get(), list)</error>;
}
abstract <Y> Set<Y> get();
abstract <Y, X extends Y> void set(Set<Y> set, X x);
abstract <Y> void set(Set<Y> set, List<? extends Y> l);
}
@@ -0,0 +1,9 @@
// "Add 'String' as 2nd parameter to method 'get'" "true"
import java.util.List;
class Test<T> {
public LazyVal(final List<T> ts) {
get(ts, "");
}
public static <T1> void get(List<T1> l, String s) {}
}
@@ -0,0 +1,9 @@
// "Add 'String' as 2nd parameter to method 'get'" "true"
import java.util.List;
class Test<T> {
public LazyVal(final List<T> ts) {
get(t<caret>s, "");
}
public static <T1> void get(List<T1> l) {}
}
@@ -0,0 +1,3 @@
public class Test<A, B extends Number> {
public B m(A a){return null;}
}
@@ -0,0 +1,2 @@
public class TestSubclass<A, B extends Number> extends Test<A, B> {
}
@@ -0,0 +1,3 @@
public class Test<A, B extends Number> {
public B m(A a){return null;}
}
@@ -0,0 +1,2 @@
interface Int<T> {
}
@@ -0,0 +1,4 @@
abstract class Test implements Runnable {
<T extends Runnable> void m() {
}
}
@@ -0,0 +1,4 @@
interface Int<T> {
}
abstract class Super implements Runnable {
}
@@ -0,0 +1,4 @@
abstract class Test extends Super {
<T extends Super> void m() {
}
}
@@ -0,0 +1,19 @@
interface IA {
void a();
}
interface IB {
void b();
}
interface IC<T extends IA>{
T c();
}
class K {
void foo(IC<? extends IB> x){
IA m = x.c();
m.a();
}
}
@@ -0,0 +1,18 @@
interface IA {
void a();
}
interface IB {
void b();
}
interface IC<T extends IA>{
T c();
}
class K {
void foo(IC<? extends IB> x){
<selection>x.c()</selection>.a();
}
}
@@ -0,0 +1,8 @@
class Test {
{
final String ab = "".substring(1)
.substring(1);
ab // comment
.notify()
}
}
@@ -0,0 +1,7 @@
class Test {
{
<selection> "".substring(1)
.substring(1) // comment</selection>
.notify()
}
}
@@ -0,0 +1,10 @@
class A {
public final void foo() {}
}
class B extends A {}
class C {
void f(B b) {
B v = b;
v.foo();
}
}
@@ -0,0 +1,9 @@
class A {
public final void foo() {}
}
class B extends A {}
class C {
void f(B b) {
<selection>b</selection>.foo();
}
}
@@ -0,0 +1,12 @@
import static InlineIssue.ClassToMove.F1;
abstract class InlineIssue {
public enum ClassToMove { F1 }
public InlineIssue cre<caret>ate(ClassToMove e) {
F1.notify();
return null;
}
}
class Desc extends InlineIssue {
}
@@ -0,0 +1,13 @@
import static Desc.ClassToMove.F1;
abstract class InlineIssue {
}
class Desc extends InlineIssue {
public InlineIssue create(ClassToMove e) {
F1.notify();
return null;
}
public enum ClassToMove { F1 }
}
@@ -347,6 +347,18 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
doTest();
}
public void testCaptureConstraint() throws Exception {
doTest();
}
public void testPullUncheckedWarningNotionThroughNestedCalls() throws Exception {
doTest();
}
public void testIDEA149774() throws Exception {
doTest();
}
private void doTest() throws Exception {
doTest(false);
}
@@ -248,6 +248,18 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testIDEA149224() throws Exception {
doTest();
}
public void testIDEA149670() throws Exception {
doTest();
}
public void testIDEA149709() throws Exception {
doTest();
}
private void doTest() {
doTest(false);
}
@@ -269,4 +281,4 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
}
return suite;
}*/
}
}
@@ -191,6 +191,10 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase {
doTest(false);
}
public void testNoNeedToPreferGenericToRawSubstitution() throws Exception {
doTest();
}
private void doTest() {
doTest(true);
}
@@ -59,6 +59,10 @@ public class ExtractSuperClassTest extends RefactoringTestCase {
doTest("Test", "TestSubclass", new RefactoringTestUtil.MemberDescriptor("m", PsiMethod.class));
}
public void testMultipleTypeParameters() throws Exception {
doTest("Test", "TestSubclass", new RefactoringTestUtil.MemberDescriptor("m", PsiMethod.class));
}
public void testEmptyForeach() throws Exception {
doTest("Test", "TestSubclass", new RefactoringTestUtil.MemberDescriptor("m", PsiMethod.class));
@@ -16,7 +16,6 @@
package com.intellij.refactoring;
import com.intellij.JavaTestUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.inlineSuperClass.InlineSuperClassRefactoringProcessor;
@@ -70,6 +69,7 @@ public class InlineSuperClassTest extends MultiFileTestCase {
public void testMultipleSubclassesInheritsOneBaseBase() { doTestMultipleSubclasses(); }
public void testInlineSuperclassExtendsList() { doTest(); }
public void testInterfaceHierarchyWithSubstitution() { doTest(); }
public void testTypeParameterBound() { doTest();}
private void doTest() {
doTest(false, false);
@@ -313,6 +313,10 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase {
doTest(new MockIntroduceVariableHandler("ab", true, true, false, "boolean"));
}
public void testSubexpressionWithSpacesInSelectionAndTailingComment() {
doTest(new MockIntroduceVariableHandler("ab", true, true, false, CommonClassNames.JAVA_LANG_STRING));
}
public void testDuplicatesAnonymousClassCreationWithSimilarParameters () {
doTest(new MockIntroduceVariableHandler("foo1", true, true, false, "Foo"));
}
@@ -517,6 +521,29 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase {
});
}
public void testTypesHierarchyBasedOnCalledMethod() {
doTest(new MockIntroduceVariableHandler("v", true, false, false, "B") {
@Override
public IntroduceVariableSettings getSettings(Project project, Editor editor,
PsiExpression expr, PsiExpression[] occurrences,
TypeSelectorManagerImpl typeSelectorManager,
boolean declareFinalIfAll,
boolean anyAssignmentLHS,
InputValidator validator,
PsiElement anchor, final OccurrencesChooser.ReplaceChoice replaceChoice) {
final PsiType[] types = typeSelectorManager.getTypesForAll();
assertTrue(types[0].getPresentableText(), types[0].getPresentableText().equals("B"));
assertTrue(types[1].getPresentableText(), types[1].getPresentableText().equals("A"));
return super.getSettings(project, editor, expr, occurrences, typeSelectorManager, declareFinalIfAll, anyAssignmentLHS,
validator, anchor, replaceChoice);
}
});
}
public void testChooseIntersectionConjunctBasedOnFollowingCalls() throws Exception {
doTest(new MockIntroduceVariableHandler("m", false, false, false, "IA"));
}
private void doTest(IntroduceVariableBase testMe) {
String baseName = "/refactoring/introduceVariable/" + getTestName(false);
configureByFile(baseName + ".java");
@@ -63,6 +63,8 @@ public class PushDownTest extends LightRefactoringTestCase {
public void testInterfaceConstants() { doTest();}
public void testReferenceForMovedInnerClass() { doTest();}
public void testInsertOverrideWhenKeepAbstract() throws Exception {
doTestImplements(true);
}
@@ -92,6 +94,13 @@ public class PushDownTest extends LightRefactoringTestCase {
membersToMove.add(memberInfo);
}
final PsiClass classByName = currentClass.findInnerClassByName("ClassToMove", false);
if (classByName != null) {
final MemberInfo memberInfo = new MemberInfo(classByName);
memberInfo.setChecked(true);
membersToMove.add(memberInfo);
}
final MemberInfo memberInfo = new MemberInfo(psiMember);
memberInfo.setChecked(true);
membersToMove.add(memberInfo);
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -349,7 +349,7 @@ public class Main {
scrollPane.setPreferredSize(new Dimension(Math.min(maxWidth, component.width), Math.min(maxHeight, component.height)));
}
int type = error ? JOptionPane.ERROR_MESSAGE : JOptionPane.INFORMATION_MESSAGE;
int type = error ? JOptionPane.ERROR_MESSAGE : JOptionPane.WARNING_MESSAGE;
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), scrollPane, title, type);
}
catch (Throwable t) {
+1
View File
@@ -12,5 +12,6 @@
<orderEntry type="module" module-name="platform-api" />
<orderEntry type="module" module-name="platform-impl" />
<orderEntry type="module" module-name="vcs-api-core" />
<orderEntry type="module" module-name="vcs-api" />
</component>
</module>
@@ -37,9 +37,11 @@ import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -103,23 +105,13 @@ public class DiffRequestFactoryImpl extends DiffRequestFactory {
@Override
@NotNull
public String getContentTitle(@NotNull VirtualFile file) {
if (file.isDirectory()) return file.getPath();
VirtualFile parent = file.getParent();
return getContentTitle(file.getName(), file.getPath(), parent != null ? parent.getPath() : null);
return getContentTitle(VcsUtil.getFilePath(file));
}
@Override
@NotNull
public String getTitle(@NotNull VirtualFile file1, @NotNull VirtualFile file2) {
if ((file1.isDirectory() || file2.isDirectory()) && file1.getPath().equals(file2.getPath())) return file1.getPath();
if (file1.isDirectory() ^ file2.isDirectory()) return getContentTitle(file1) + " vs " + getContentTitle(file2);
VirtualFile parent1 = file1.getParent();
VirtualFile parent2 = file2.getParent();
return getRequestTitle(file1.getName(), file1.getPath(), parent1 != null ? parent1.getPath() : null,
file2.getName(), file2.getPath(), parent2 != null ? parent2.getPath() : null,
" vs ");
return getTitle(VcsUtil.getFilePath(file1), VcsUtil.getFilePath(file2), " vs ");
}
@Override
@@ -130,20 +122,29 @@ public class DiffRequestFactoryImpl extends DiffRequestFactory {
@NotNull
public static String getContentTitle(@NotNull FilePath path) {
if (path.isDirectory()) return path.getPath();
if (path.isDirectory()) return path.getPresentableUrl();
FilePath parent = path.getParentPath();
return getContentTitle(path.getName(), path.getPath(), parent != null ? parent.getPath() : null);
return getContentTitle(path.getName(), path.getPresentableUrl(), parent != null ? parent.getPresentableUrl() : null);
}
@NotNull
public static String getTitle(@NotNull FilePath path1, @NotNull FilePath path2, @NotNull String separator) {
if ((path1.isDirectory() || path2.isDirectory()) && path1.getPath().equals(path2.getPath())) return path1.getPath();
if (path1.isDirectory() ^ path2.isDirectory()) return getContentTitle(path1) + " vs " + getContentTitle(path2);
if ((path1.isDirectory() || path2.isDirectory()) && path1.getPresentableUrl().equals(path2.getPresentableUrl())) {
return path1.getPresentableUrl();
}
String name1 = path1.getName();
String name2 = path2.getName();
if (path1.isDirectory() ^ path2.isDirectory()) {
if (path1.isDirectory()) name1 += File.separatorChar;
if (path2.isDirectory()) name2 += File.separatorChar;
}
FilePath parent1 = path1.getParentPath();
FilePath parent2 = path2.getParentPath();
return getRequestTitle(path1.getName(), path1.getPath(), parent1 != null ? parent1.getPath() : null,
path2.getName(), path2.getPath(), parent2 != null ? parent2.getPath() : null,
return getRequestTitle(name1, path1.getPresentableUrl(), parent1 != null ? parent1.getPresentableUrl() : null,
name2, path2.getPresentableUrl(), parent2 != null ? parent2.getPresentableUrl() : null,
separator);
}
@@ -121,7 +121,7 @@ public class CompareFilesAction extends BaseShowDiffAction {
Type type = getType(file);
if (type == Type.DIRECTORY || type == Type.ARCHIVE) {
descriptor = new FileChooserDescriptor(false, true, true, false, false, false);
descriptor = new FileChooserDescriptor(false, true, true, true, true, false);
key = LAST_USED_FOLDER_KEY;
}
else {
@@ -187,6 +187,7 @@ public class DiffUtil {
editor.getSettings().setShowIntentionBulb(false);
((EditorMarkupModel)editor.getMarkupModel()).setErrorStripeVisible(true);
editor.getGutterComponentEx().setShowDefaultGutterPopup(false);
editor.getGutterComponentEx().setShowRightFreePaintersArea(false);
if (enableFolding) {
setFoldingModelSupport(editor);
@@ -37,6 +37,7 @@ class ChangeCompareModeAction extends DumbAwareAction {
ChangeCompareModeAction(DirDiffTableModel model, DirDiffSettings.CompareMode mode) {
super(mode.getPresentableName(model.getSettings()));
getTemplatePresentation().setIcon(OFF);
myModel = model;
myMode = mode;
}
@@ -18,10 +18,10 @@ package com.intellij.execution.console;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -30,13 +30,13 @@ import java.util.List;
*/
class ConsoleHistoryModel extends SimpleModificationTracker {
/** @noinspection FieldCanBeLocal*/
private final ConsoleHistoryModel myMasterModel; // hard ref
private int myIndex;
private final Object myLock;
private final LinkedList<String> myEntries;
private int myIndex;
ConsoleHistoryModel(ConsoleHistoryModel masterModel) {
myMasterModel = masterModel;
myEntries = myMasterModel == null ? new LinkedList<String>() : myMasterModel.myEntries;
ConsoleHistoryModel(@Nullable ConsoleHistoryModel masterModel) {
myEntries = masterModel == null ? new LinkedList<String>() : masterModel.myEntries;
myLock = masterModel == null ? this : masterModel.myLock; // hard ref to master model
resetIndex();
}
@@ -44,23 +44,27 @@ class ConsoleHistoryModel extends SimpleModificationTracker {
return new ConsoleHistoryModel(this);
}
public synchronized void resetEntries(@NotNull List<String> entries) {
myEntries.clear();
myEntries.addAll(entries.subList(0, Math.min(entries.size(), getMaxHistorySize())));
incModificationCount();
public void resetEntries(@NotNull List<String> entries) {
synchronized (myLock) {
myEntries.clear();
myEntries.addAll(entries.subList(0, Math.min(entries.size(), getMaxHistorySize())));
incModificationCount();
}
}
public synchronized void addToHistory(@Nullable String statement) {
public void addToHistory(@Nullable String statement) {
if (StringUtil.isEmptyOrSpaces(statement)) return;
int maxHistorySize = getMaxHistorySize();
myEntries.remove(statement);
int size = myEntries.size();
if (size >= maxHistorySize && size > 0) {
myEntries.removeFirst();
synchronized (myLock) {
int maxHistorySize = getMaxHistorySize();
myEntries.remove(statement);
int size = myEntries.size();
if (size >= maxHistorySize && size > 0) {
myEntries.removeFirst();
}
myEntries.addLast(statement);
incModificationCount();
}
myEntries.addLast(statement);
incModificationCount();
}
@Override
@@ -69,48 +73,66 @@ class ConsoleHistoryModel extends SimpleModificationTracker {
super.incModificationCount();
}
protected synchronized void resetIndex() {
myIndex = myEntries.size();
protected void resetIndex() {
synchronized (myLock) {
myIndex = myEntries.size();
}
}
public int getMaxHistorySize() {
return UISettings.getInstance().CONSOLE_COMMAND_HISTORY_LIMIT;
}
public synchronized void removeFromHistory(String statement) {
myEntries.remove(statement);
incModificationCount();
public void removeFromHistory(String statement) {
synchronized (myLock) {
myEntries.remove(statement);
incModificationCount();
}
}
public synchronized List<String> getEntries() {
return new ArrayList<String>(myEntries);
public List<String> getEntries() {
synchronized (myLock) {
return ContainerUtil.newArrayList(myEntries);
}
}
public synchronized int getHistorySize() {
return myEntries.size();
public int getHistorySize() {
synchronized (myLock) {
return myEntries.size();
}
}
@Nullable
public synchronized String getHistoryNext() {
if (myIndex >= 0) --myIndex;
return getCurrentEntry();
public String getHistoryNext() {
synchronized (myLock) {
if (myIndex >= 0) --myIndex;
return getCurrentEntry();
}
}
@Nullable
public synchronized String getHistoryPrev() {
if (myIndex <= myEntries.size() - 1) ++myIndex;
return getCurrentEntry();
public String getHistoryPrev() {
synchronized (myLock) {
if (myIndex <= myEntries.size() - 1) ++myIndex;
return getCurrentEntry();
}
}
public synchronized boolean hasHistory(final boolean next) {
return next ? myIndex > 0 : myIndex < myEntries.size() - 1;
public boolean hasHistory(final boolean next) {
synchronized (myLock) {
return next ? myIndex > 0 : myIndex < myEntries.size() - 1;
}
}
synchronized String getCurrentEntry() {
return myIndex >= 0 && myIndex < myEntries.size() ? myEntries.get(myIndex) : null;
String getCurrentEntry() {
synchronized (myLock) {
return myIndex >= 0 && myIndex < myEntries.size() ? myEntries.get(myIndex) : null;
}
}
synchronized int getCurrentIndex() {
return myIndex;
int getCurrentIndex() {
synchronized (myLock) {
return myIndex;
}
}
}
@@ -1179,7 +1179,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
myTitle.setText(title);
myMainPanel.add(createTitle(" " + title), BorderLayout.NORTH);
}
myMainPanel.add(cmp, BorderLayout.WEST);
myMainPanel.add(cmp, BorderLayout.CENTER);
if (cmp instanceof Accessible) {
myMainPanel.setAccessible((Accessible)cmp);
}
@@ -52,6 +52,21 @@ class SearchEverywherePsiRenderer extends PsiElementListCellRenderer<PsiElement>
public SearchEverywherePsiRenderer(JList list) {
myList = list;
setFocusBorderEnabled(false);
setLayout(new BorderLayout() {
@Override
public void layoutContainer(Container target) {
super.layoutContainer(target);
final Component right = getLayoutComponent(EAST);
final Component left = getLayoutComponent(WEST);
//IDEA-140824
if (right != null && left != null && left.getBounds().x + left.getBounds().width > right.getBounds().x) {
final Rectangle bounds = right.getBounds();
final int newX = left.getBounds().x + left.getBounds().width;
right.setBounds(newX, bounds.y, bounds.width - (newX - bounds.x), bounds.height);
}
}
});
}
@Override
@@ -357,7 +357,7 @@ public class Bookmark implements Navigatable, Comparable<Bookmark> {
private static class MyCheckedIcon implements Icon, RetrievableIcon {
@Nullable
@Override
public Icon retrieve() {
public Icon retrieveIcon() {
return PlatformIcons.CHECK_ICON;
}
@@ -35,7 +35,6 @@ import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.ide.PooledThreadExecutor;
import javax.swing.*;
@@ -250,8 +249,8 @@ public class DeferredIconImpl<T> implements DeferredIcon, RetrievableIcon {
@Nullable
@Override
public Icon retrieve() {
return evaluate();
public Icon retrieveIcon() {
return isDone() ? myDelegateIcon : evaluate();
}
@NotNull
@@ -378,12 +377,6 @@ public class DeferredIconImpl<T> implements DeferredIcon, RetrievableIcon {
equalIcons(myDelegateIcon, ((DeferredIconImpl)icon).myDelegateIcon);
}
@TestOnly
@NotNull
Icon getDelegateIcon() {
return myDelegateIcon;
}
@Override
public String toString() {
return "Deferred. Base=" + myDelegateIcon;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -44,15 +44,17 @@ public class ProgressManagerQueue extends AbstractTaskQueue<Runnable> {
protected void runMe() {
if (!myIsStarted) return;
if (ApplicationManager.getApplication().isDispatchThread()) {
if (myQueuePollTask.myProject.isDisposed() || isEmpty()) return;
myProgressManager.run(myQueuePollTask);
if (!myQueuePollTask.myProject.isDisposed()) {
myProgressManager.run(myQueuePollTask);
}
}
else {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (myQueuePollTask.myProject.isDisposed() || isEmpty()) return;
myProgressManager.run(myQueuePollTask);
if (!myQueuePollTask.myProject.isDisposed()) {
myProgressManager.run(myQueuePollTask);
}
}
});
}
@@ -745,7 +745,9 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable {
case MouseEvent.MOUSE_PRESSED:
if (isInside(e.getPoint())) {
myWasPressedOnMe = true;
myGlassPane.setCursor(getResizeCursor(), myListener);
if (myGlassPane != null) {
myGlassPane.setCursor(getResizeCursor(), myListener);
}
e.consume();
} else {
myWasPressedOnMe = false;
@@ -755,7 +757,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable {
if (myWasPressedOnMe) {
e.consume();
}
if (isInside(e.getPoint())) {
if (isInside(e.getPoint()) && myGlassPane != null) {
myGlassPane.setCursor(getResizeCursor(), myListener);
}
myWasPressedOnMe = false;
+1
View File
@@ -45,5 +45,6 @@
<orderEntry type="library" exported="" name="KotlinJavaRuntime" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Slf4j" level="project" />
<orderEntry type="module" module-name="configuration-store-impl" scope="RUNTIME" />
<orderEntry type="library" name="com.twelvemonkeys.imageio:imageio-tiff:3.2.1" level="project" />
</component>
</module>
@@ -172,8 +172,11 @@ public class AboutPopup {
myLines.add(new AboutBoxLine(""));
myLines.add(new AboutBoxLine(""));
myLines.add(new AboutBoxLine("Powered by ").keepWithNext());
myLines.add(new AboutBoxLine("open-source software", false, thirdParty).keepWithNext());
myLines.add(new AboutBoxLine("open-source software", false, thirdParty));
}
myLines.add(new AboutBoxLine(""));
myLines.add(new AboutBoxLine(IdeBundle.message("about.box.copy.prompt", SystemInfo.isMac ? "Cmd+C" : "Ctrl+C")));
addMouseListener(new MouseAdapter() {
@Override
@@ -36,7 +36,6 @@ import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.startup.StartupActivity;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
@@ -208,11 +207,6 @@ public class StartupManagerImpl extends StartupManagerEx {
}
}
});
// otherwise will be stored - we must not create config files in tests
if (!app.isUnitTestMode()) {
Registry.get("ide.firstStartup").setValue(false);
}
}
public void scheduleInitialVfsRefresh() {
@@ -262,10 +256,10 @@ public class StartupManagerImpl extends StartupManagerEx {
path = PathUtil.getParentPath(path);
}
boolean actual = FileUtil.isFileSystemCaseSensitive(path);
LOG.info(path + " case-sensitivity: " + actual);
if (actual != SystemInfo.isFileSystemCaseSensitive) {
int prefix = SystemInfo.isFileSystemCaseSensitive ? 1 : 0; // IDE=true -> FS=false -> prefix='in'
boolean expected = SystemInfo.isFileSystemCaseSensitive, actual = FileUtil.isFileSystemCaseSensitive(path);
LOG.info(path + " case-sensitivity: expected=" + expected + " actual=" + actual);
if (actual != expected) {
int prefix = expected ? 1 : 0; // IDE=true -> FS=false -> prefix='in'
String title = ApplicationBundle.message("fs.case.sensitivity.mismatch.title");
String text = ApplicationBundle.message("fs.case.sensitivity.mismatch.message", prefix);
Notifications.Bus.notify(
@@ -493,7 +493,7 @@ public class CustomizableActionsPanel {
setText(((QuickList)userObject).getName());
icon = AllIcons.Actions.QuickList;
}
else {
else if (userObject != null) {
throw new IllegalArgumentException("unknown userObject: " + userObject);
}
@@ -143,6 +143,7 @@ public final class SocketLock {
myServer = BuiltInServer.start(workerCount, 6942, 50, false, handler);
}
catch (IllegalStateException e) {
Logger.getInstance(SocketLock.class).warn(e);
myServer = BuiltInServer.start(new OioEventLoopGroup(1, new BuiltInServer.BuiltInServerThreadFactory()), true, 6942, 50, false, handler);
}
@@ -18,12 +18,12 @@ package com.intellij.openapi.application;
import com.intellij.ide.plugins.IdeaPluginDescriptorImpl;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.idea.Main;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.AppUIUtil;
import com.intellij.util.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,47 +38,63 @@ import java.util.PropertyResourceBundle;
* @author max
*/
public class ConfigImportHelper {
/**
* Holds name of the system property that is supposed to hold <code>'true'</code> value when IDE settings have been
* imported on the current startup
*/
@NonNls public static final String CONFIG_IMPORTED_IN_CURRENT_SESSION_KEY = "intellij.config.imported.in.current.session";
@NonNls private static final String BUILD_NUMBER_FILE = SystemInfo.isMac ? "/Resources/build.txt" : "build.txt";
@NonNls private static final String PLUGINS_PATH = "plugins";
@NonNls private static final String BIN_FOLDER = "bin";
@NonNls private static final String CONFIG_RELATED_PATH = SystemInfo.isMac ? "" : "config/";
@NonNls private static final String OPTIONS_XML = "options/options.xml";
private static final String FIRST_SESSION_KEY = "intellij.first.ide.session";
private static final String CONFIG_IMPORTED_IN_CURRENT_SESSION_KEY = "intellij.config.imported.in.current.session";
private ConfigImportHelper() {
}
private static final String BUILD_NUMBER_FILE = SystemInfo.isMac ? "/Resources/build.txt" : "build.txt";
private static final String PLUGINS_PATH = "plugins";
private static final String BIN_FOLDER = "bin";
private static final String CONFIG_RELATED_PATH = SystemInfo.isMac ? "" : "config/";
private static final String OPTIONS_XML = "options/options.xml";
private ConfigImportHelper() { }
public static void importConfigsTo(@NotNull String newConfigPath) {
System.setProperty(FIRST_SESSION_KEY, Boolean.TRUE.toString());
ConfigImportSettings settings = getConfigImportSettings();
File newConfigDir = new File(newConfigPath);
File oldConfigDir = findOldConfigDir(newConfigDir, settings.getCustomPathsSelector());
do {
try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); }
catch (Throwable ignore) { }
while (true) {
ImportOldConfigsPanel dialog = new ImportOldConfigsPanel(oldConfigDir, settings);
dialog.setModalityType(Dialog.ModalityType.TOOLKIT_MODAL);
AppUIUtil.updateWindowIcon(dialog);
dialog.setVisible(true);
if (dialog.isImportEnabled()) {
File installationHome = dialog.getSelectedFile();
oldConfigDir = getOldConfigDir(installationHome, settings);
if (!validateOldConfigDir(installationHome, oldConfigDir, settings)) {
continue;
}
assert oldConfigDir != null;
doImport(newConfigDir, oldConfigDir, settings, installationHome);
settings.importFinished(newConfigPath);
System.setProperty(CONFIG_IMPORTED_IN_CURRENT_SESSION_KEY, Boolean.TRUE.toString());
if (!dialog.isImportEnabled()) {
break;
}
File installationHome = dialog.getSelectedFile();
oldConfigDir = getOldConfigDir(installationHome, settings);
if (!validateOldConfigDir(installationHome, oldConfigDir, settings)) {
continue;
}
assert oldConfigDir != null;
doImport(newConfigDir, oldConfigDir, settings, installationHome);
settings.importFinished(newConfigPath);
System.setProperty(CONFIG_IMPORTED_IN_CURRENT_SESSION_KEY, Boolean.TRUE.toString());
break;
}
while (true);
}
/**
* Returns {@code true} when the IDE is launched for the first time (i.e. there was no config directory).
*/
public static boolean isFirstSession() {
return Boolean.getBoolean(FIRST_SESSION_KEY);
}
/**
* Returns {@code true} when the IDE is launched for the first time, and configs were imported from another installation.
*/
public static boolean isConfigImported() {
return Boolean.getBoolean(CONFIG_IMPORTED_IN_CURRENT_SESSION_KEY);
}
@NotNull
@@ -91,10 +107,8 @@ public class ConfigImportHelper {
return ReflectionUtil.newInstance(customProviderClass);
}
}
catch (ClassNotFoundException ignored) {
}
catch (RuntimeException ignored) {
}
catch (ClassNotFoundException ignored) { }
catch (RuntimeException ignored) { }
return new ConfigImportSettings();
}
@@ -141,28 +155,26 @@ public class ConfigImportHelper {
copy(oldConfigDir, newConfigDir, settings, installationHome);
}
catch (IOException e) {
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
ApplicationBundle.message("error.unable.to.import.settings", e.getMessage()),
ApplicationBundle.message("title.settings.import.failed"), JOptionPane.WARNING_MESSAGE);
String message = ApplicationBundle.message("error.unable.to.import.settings", e.getMessage());
Main.showMessage(ApplicationBundle.message("title.settings.import.failed"), message, false);
}
}
private static boolean validateOldConfigDir(@Nullable File installationHome, @Nullable File oldConfigDir, @NotNull ConfigImportSettings settings) {
if (oldConfigDir == null) {
if (installationHome != null) {
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
ApplicationBundle.message("error.invalid.installation.home", installationHome.getAbsolutePath(), settings.getProductName(ThreeState.YES)));
String message = ApplicationBundle.message("error.invalid.installation.home", installationHome.getAbsolutePath(), settings.getProductName(ThreeState.YES));
Main.showMessage(ApplicationBundle.message("title.settings.import.failed"), message, false);
}
return false;
}
if (!oldConfigDir.exists()) {
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
ApplicationBundle.message("error.no.settings.path",
oldConfigDir.getAbsolutePath()),
ApplicationBundle.message("title.settings.import.failed"), JOptionPane.WARNING_MESSAGE);
String message = ApplicationBundle.message("error.no.settings.path", oldConfigDir.getAbsolutePath());
Main.showMessage(ApplicationBundle.message("title.settings.import.failed"), message, false);
return false;
}
return true;
}
@@ -224,7 +236,7 @@ public class ConfigImportHelper {
}
@Nullable
public static File getOldConfigDir(@Nullable File oldInstallHome, ConfigImportSettings settings) {
private static File getOldConfigDir(@Nullable File oldInstallHome, ConfigImportSettings settings) {
if (oldInstallHome == null) {
return null;
}
@@ -240,7 +252,6 @@ public class ConfigImportHelper {
int oldBuildNumber = getBuildNumber(oldInstallHome);
if (oldBuildNumber != -1 && oldBuildNumber <= 600) { // Pandora
//noinspection HardCodedStringLiteral
return new File(oldInstallHome, "config");
}
@@ -252,11 +263,8 @@ public class ConfigImportHelper {
});
}
private static File getSettingsPath(final File installHome,
final ConfigImportSettings settings,
final String propertyName,
final Function<String, String> fromPathSelector) {
final File[] launchFileCandidates = getLaunchFilesCandidates(installHome, settings);
private static File getSettingsPath(File installHome, ConfigImportSettings settings, String propertyName, Function<String, String> fromPathSelector) {
final List<File> launchFileCandidates = getLaunchFilesCandidates(installHome, settings);
// custom config folder
for (File candidate : launchFileCandidates) {
@@ -275,10 +283,9 @@ public class ConfigImportHelper {
if (candidate.exists()) {
final String pathsSelector = getPropertyFromLaxFile(candidate, PathManager.PROPERTY_PATHS_SELECTOR);
if (pathsSelector != null) {
final String configDir = fromPathSelector.fun(pathsSelector);
final File probableConfig = new File(configDir);
if (probableConfig.exists()) {
return probableConfig;
File candidateDir = new File(fromPathSelector.fun(pathsSelector));
if (candidateDir.exists()) {
return candidateDir;
}
}
}
@@ -287,21 +294,18 @@ public class ConfigImportHelper {
return null;
}
@SuppressWarnings({"HardCodedStringLiteral"})
private static File[] getLaunchFilesCandidates(@NotNull final File instHome, @NotNull final ConfigImportSettings settings) {
private static List<File> getLaunchFilesCandidates(@NotNull File instHome, @NotNull ConfigImportSettings settings) {
final File bin = new File(instHome, BIN_FOLDER);
final List<File> files = new ArrayList<File>();
if (SystemInfo.isMac) {
// Info.plist
files.add(new File(new File(instHome, "Contents"), "Info.plist"));
files.add(new File(new File(new File(bin, "idea.app"), "Contents"), "Info.plist"));
files.add(new File(new File(new File(instHome, "idea.app"), "Contents"), "Info.plist"));
}
// idea.properties
files.add(new File(bin, PathManager.PROPERTIES_FILE_NAME));
// other binary scripts
final String executableName = StringUtil.toLowerCase(settings.getExecutableName());
// * defaults:
@@ -313,21 +317,17 @@ public class ConfigImportHelper {
// for compatibility with some platform-base IDEs with wrong executable names
addLaunchExecutableScriptsCandidates(files, "idea", bin);
}
return files.toArray(new File[files.size()]);
return files;
}
private static void addLaunchExecutableScriptsCandidates(final List<File> files,
final String executableName,
final File binFolder) {
private static void addLaunchExecutableScriptsCandidates(List<File> files, String executableName, File binFolder) {
files.add(new File(binFolder, executableName + ".lax"));
files.add(new File(binFolder, executableName + ".bat"));
files.add(new File(binFolder, executableName + ".sh"));
}
@SuppressWarnings({"HardCodedStringLiteral"})
@Nullable
public static String getPropertyFromLaxFile(@NotNull final File file,
@NotNull final String propertyName) {
private static String getPropertyFromLaxFile(@NotNull File file, @NotNull String propertyName) {
if (file.getName().endsWith(".properties")) {
try {
PropertyResourceBundle bundle;
@@ -360,8 +360,7 @@ public class ConfigImportHelper {
}
@Nullable
private static String findProperty(final String propertyName,
final String fileContent) {
private static String findProperty(String propertyName, String fileContent) {
String param = propertyName + "=";
int idx = fileContent.indexOf(param);
if (idx == -1) {
@@ -405,29 +404,14 @@ public class ConfigImportHelper {
@Nullable
private static String getContent(File file) {
try {
StringBuilder content = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
try {
do {
String line = reader.readLine();
if (line == null) break;
content.append(line);
content.append('\n');
}
while (true);
}
finally {
reader.close();
}
return content.toString();
return FileUtil.loadFile(file);
}
catch (Exception e) {
catch (IOException e) {
return null;
}
}
public static String fixDirName(String dir, boolean replaceUserHome) {
private static String fixDirName(String dir, boolean replaceUserHome) {
if (StringUtil.startsWithChar(dir, '\"') && StringUtil.endsWithChar(dir, '\"')) {
dir = dir.substring(1, dir.length() - 1);
}
@@ -437,7 +421,7 @@ public class ConfigImportHelper {
return dir;
}
public static boolean isInstallationHomeOrConfig(@NotNull final String installationHome, @NotNull final ConfigImportSettings settings) {
public static boolean isInstallationHomeOrConfig(@NotNull String installationHome, @NotNull ConfigImportSettings settings) {
if (new File(installationHome, OPTIONS_XML).exists()) return true;
if (new File(installationHome, CONFIG_RELATED_PATH + OPTIONS_XML).exists()) return true;
@@ -450,7 +434,6 @@ public class ConfigImportHelper {
String[] mainJarNames = settings.getMainJarNames();
for (String name : mainJarNames) {
String mainJarName = StringUtil.toLowerCase(name) + ".jar";
//noinspection HardCodedStringLiteral
if (new File(libFolder, mainJarName).exists()) {
quickTest = true;
break;
@@ -458,7 +441,7 @@ public class ConfigImportHelper {
}
if (!quickTest) return false;
File[] files = getLaunchFilesCandidates(new File(installationHome), settings);
List<File> files = getLaunchFilesCandidates(new File(installationHome), settings);
for (File file : files) {
if (file.exists()) return true;
}
@@ -493,4 +476,4 @@ public class ConfigImportHelper {
return -1;
}
}
}
@@ -104,7 +104,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
private final boolean myTestModeFlag;
private final boolean myHeadlessMode;
private final boolean myCommandLineMode;
private final boolean myIsRunningFromSources;
private static volatile Boolean ourIsRunningFromSources;
private final boolean myIsInternal;
private final String myName;
@@ -198,8 +198,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
myHeadlessMode = isHeadless;
myCommandLineMode = isCommandLine;
myIsRunningFromSources = new File(PathManager.getHomePath(), ".idea").isDirectory();
myDoNotSave = isUnitTestMode || isHeadless;
if (myTestModeFlag) {
@@ -358,8 +356,11 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
return myCommandLineMode;
}
public boolean isRunningFromSources() {
return myIsRunningFromSources;
public static boolean isRunningFromSources() {
if (ourIsRunningFromSources == null) {
ourIsRunningFromSources = new File(PathManager.getHomePath(), ".idea").isDirectory();
}
return ourIsRunningFromSources;
}
@NotNull
@@ -72,4 +72,6 @@ public abstract class EditorGutterComponentEx extends JComponent implements Edit
public abstract void setGutterPopupGroup(@Nullable ActionGroup group);
public abstract void setPaintBackground(boolean value);
public abstract void setShowRightFreePaintersArea(boolean value);
}
@@ -215,8 +215,9 @@ public class ComplementaryFontsRegistry {
}
@Nullable
private static FontInfo doGetFontAbleToDisplay(int codePoint, int size, @JdkConstants.FontStyle int style, @NotNull String defaultFontFamily) {
private static FontInfo doGetFontAbleToDisplay(int codePoint, int size, @JdkConstants.FontStyle int originalStyle, @NotNull String defaultFontFamily) {
synchronized (lock) {
@JdkConstants.FontStyle int style = originalStyle;
if (Patches.JDK_MAC_FONT_STYLE_DETECTION_WORKAROUND && style > 0 && style < 4) {
Pair<String, Integer>[] replacement = ourStyledFontMap.get(defaultFontFamily);
if (replacement != null) {
@@ -242,7 +243,7 @@ public class ComplementaryFontsRegistry {
FontInfo defaultFont = ourUsedFonts.get(ourSharedKeyInstance);
if (defaultFont == null) {
defaultFont = new FontInfo(defaultFontFamily, size, style);
defaultFont = new FontInfo(defaultFontFamily, size, style, originalStyle);
ourUsedFonts.put(ourSharedKeyInstance, defaultFont);
ourSharedKeyInstance = new FontKey("", 0, 0);
}
@@ -103,7 +103,7 @@ import java.util.List;
* <ul>
* <li>Left free painters</li>
* <li>Icons</li>
* <li>GAP_BETWEEN_AREAS</li>
* <li>Debugger additional area</li>
* <li>Free painters</li>
* </ul>
* </li>
@@ -146,6 +146,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
private TIntObjectHashMap<Color> myTextFgColors = new TIntObjectHashMap<Color>();
private boolean myPaintBackground = true;
private boolean myLeftFreePaintersAreaShown;
private boolean myRightFreePaintersAreaShown = true;
private int myLastNonDumbModeIconAreaWidth = 0;
@SuppressWarnings("unchecked")
@@ -884,8 +885,8 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
((LineMarkerRendererEx)renderer).getPosition() == LineMarkerRendererEx.Position.LEFT;
int height = endY - startY;
int w = leftPosition ? FREE_PAINTERS_LEFT_AREA_WIDTH : FREE_PAINTERS_RIGHT_AREA_WIDTH;
int x = leftPosition ? getLineMarkerAreaOffset() : getLineMarkerFreePaintersAreaOffset() - 1;
int w = leftPosition ? getLeftFreePaintersAreaWidth() : getRightFreePaintersAreaWidth();
int x = leftPosition ? getLeftFreePaintersAreaOffset() : getLineMarkerFreePaintersAreaOffset() - 1;
return new Rectangle(x, startY, w, height);
}
@@ -1184,9 +1185,8 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
}
public int getLineMarkerAreaWidth() {
return isLineMarkersShown() ? ((myLeftFreePaintersAreaShown ? FREE_PAINTERS_LEFT_AREA_WIDTH : 0) +
myIconsAreaWidth + GAP_BETWEEN_AREAS + FREE_PAINTERS_RIGHT_AREA_WIDTH) :
0;
return isLineMarkersShown() ? getLeftFreePaintersAreaWidth() + myIconsAreaWidth +
getDebuggerAdditionalAreaWidth() + getRightFreePaintersAreaWidth() : 0;
}
public void setLineNumberAreaWidthFunction(@NotNull TIntFunction calculator) {
@@ -1267,12 +1267,24 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
@Override
public int getIconAreaOffset() {
return getLineMarkerAreaOffset() + (myLeftFreePaintersAreaShown ? FREE_PAINTERS_LEFT_AREA_WIDTH : 0);
return getLineMarkerAreaOffset() + getLeftFreePaintersAreaWidth();
}
public int getLeftFreePaintersAreaOffset() {
return getLineMarkerAreaOffset();
}
@Override
public int getLineMarkerFreePaintersAreaOffset() {
return getIconAreaOffset() + myIconsAreaWidth + GAP_BETWEEN_AREAS;
return getIconAreaOffset() + myIconsAreaWidth + getDebuggerAdditionalAreaWidth();
}
public int getLeftFreePaintersAreaWidth() {
return myLeftFreePaintersAreaShown ? FREE_PAINTERS_LEFT_AREA_WIDTH : 0;
}
public int getRightFreePaintersAreaWidth() {
return myRightFreePaintersAreaShown ? FREE_PAINTERS_RIGHT_AREA_WIDTH : 0;
}
@Override
@@ -1280,6 +1292,10 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
return myIconsAreaWidth;
}
public int getDebuggerAdditionalAreaWidth() {
return isRealEditor() ? GAP_BETWEEN_AREAS : 0;
}
private boolean isMirrored() {
return myEditor.getVerticalScrollbarOrientation() != EditorEx.VERTICAL_SCROLLBAR_RIGHT;
}
@@ -1658,6 +1674,11 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
myPaintBackground = value;
}
@Override
public void setShowRightFreePaintersArea(boolean value) {
myRightFreePaintersAreaShown = value;
}
private void invokePopup(MouseEvent e) {
final ActionManager actionManager = ActionManager.getInstance();
if (myEditor.getMouseEventArea(e) == EditorMouseEventArea.ANNOTATIONS_AREA) {
@@ -15,14 +15,19 @@
*/
package com.intellij.openapi.editor.impl;
import com.intellij.Patches;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.ex.util.EditorUIUtil;
import com.intellij.openapi.editor.impl.view.FontLayoutService;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import gnu.trove.TIntHashSet;
import org.intellij.lang.annotations.JdkConstants;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.awt.font.FontRenderContext;
@@ -31,15 +36,15 @@ import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Locale;
import java.util.*;
import java.util.List;
/**
* @author max
*/
public class FontInfo {
private static final Logger LOG = Logger.getInstance(FontInfo.class);
private static final boolean USE_ALTERNATIVE_CAN_DISPLAY_PROCEDURE = SystemInfo.isAppleJvm && Registry.is("ide.mac.fix.font.fallback");
private static final FontRenderContext DUMMY_CONTEXT = new FontRenderContext(null, false, false);
private static final boolean ENABLE_OPTIONAL_LIGATURES = Registry.is("editor.enable.optional.ligatures");
@@ -55,50 +60,87 @@ public class FontInfo {
private boolean myCheckedForProblemGlyphs;
public FontInfo(final String familyName, final int size, @JdkConstants.FontStyle int style) {
this(familyName, size, style, style);
}
FontInfo(final String familyName, final int size, @JdkConstants.FontStyle int style, @JdkConstants.FontStyle int realStyle) {
mySize = size;
myStyle = style;
Font font = new Font(familyName, style, size);
myFont = ENABLE_OPTIONAL_LIGATURES ? getFontWithLigaturesEnabled(font) : font;
myFont = ENABLE_OPTIONAL_LIGATURES ? getFontWithLigaturesEnabled(font, realStyle) : font;
}
@NotNull
private static Font getFontWithLigaturesEnabled(Font font) {
if (SystemInfo.isMac) {
private static Font getFontWithLigaturesEnabled(Font font, @JdkConstants.FontStyle int fontStyle) {
if (Patches.JDK_BUG_ID_7162125) {
// Ligatures don't work on Mac for fonts loaded natively, so we need to locate and load font manually
File fontFile = findFileForFont(font, true);
if (fontFile == null && font.getStyle() != Font.PLAIN) fontFile = findFileForFont(font.deriveFont(Font.PLAIN), true);
if (fontFile == null) fontFile = findFileForFont(font, false);
if (fontFile == null) return font;
String familyName = font.getFamily();
File fontFile = findFileForFont(familyName, fontStyle);
if (fontFile == null) {
LOG.info(font + "(style=" + fontStyle + ") not located");
return font;
}
LOG.info(font + "(style=" + fontStyle + ") located at " + fontFile);
try {
font = Font.createFont(Font.TRUETYPE_FONT, fontFile).deriveFont(font.getStyle(), font.getSize());
font = Font.createFont(Font.TRUETYPE_FONT, fontFile).deriveFont(fontStyle, font.getSize());
}
catch (Exception e) {
LOG.warn("Couldn't load font", e);
return font;
}
}
return font.deriveFont(Collections.singletonMap(TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON));
}
private static File findFileForFont(Font font, final boolean matchStyle) {
final String normalizedFamilyName = font.getFamily().toLowerCase(Locale.getDefault()).replace(" ", "");
final int fontStyle = font.getStyle();
File[] files = new File(System.getProperty("user.home"), "Library/Fonts").listFiles(new FilenameFilter() {
private static final Comparator<File> BY_NAME = new Comparator<File>() {
@Override
public int compare(File file1, File file2) {
return file1.getName().compareTo(file2.getName());
}
};
@Nullable
private static File findFileForFont(@NotNull String familyName, int style) {
File fontFile = doFindFileForFont(familyName, style);
if (fontFile == null && style != Font.PLAIN) fontFile = doFindFileForFont(familyName, Font.PLAIN);
if (fontFile == null) fontFile = doFindFileForFont(familyName, -1);
return fontFile;
}
@Nullable
private static File doFindFileForFont(@NotNull String familyName, final int style) {
final String normalizedFamilyName = familyName.toLowerCase(Locale.getDefault()).replace(" ", "");
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File file, String name) {
String normalizedName = name.toLowerCase(Locale.getDefault());
return normalizedName.startsWith(normalizedFamilyName) &&
(normalizedName.endsWith(".otf") || normalizedName.endsWith(".ttf")) &&
(!matchStyle || fontStyle == ComplementaryFontsRegistry.getFontStyle(name));
(style == -1 || style == ComplementaryFontsRegistry.getFontStyle(name));
}
});
if (files == null || files.length == 0) return null;
// to make sure results are predictable we return first file in alphabetical order
return Collections.min(Arrays.asList(files), new Comparator<File>() {
@Override
public int compare(File file1, File file2) {
return file1.getName().compareTo(file2.getName());
}
});
};
List<File> files = new ArrayList<File>();
File[] userFiles = new File(System.getProperty("user.home"), "Library/Fonts").listFiles(filter);
if (userFiles != null) files.addAll(Arrays.asList(userFiles));
File[] localFiles = new File("/Library/Fonts").listFiles(filter);
if (localFiles != null) files.addAll(Arrays.asList(localFiles));
if (files.isEmpty()) return null;
if (style == Font.PLAIN) {
// prefer font containing 'regular' in its name
List<File> regulars = ContainerUtil.filter(files, new Condition<File>() {
@Override
public boolean value(File file) {
return file.getName().toLowerCase(Locale.getDefault()).contains("regular");
}
});
if (!regulars.isEmpty()) return Collections.min(regulars, BY_NAME);
}
return Collections.min(files, BY_NAME);
}
private void parseProblemGlyphs() {
@@ -453,6 +453,7 @@ public class ActionsTreeUtil {
node.add(childNode);
}
else {
LOG.assertTrue(child != null);
node.add(new DefaultMutableTreeNode(child));
}
}
@@ -77,12 +77,14 @@ public class UpdateCheckerComponent implements ApplicationComponent {
if (eap && current != ChannelStatus.EAP && UpdateStrategyCustomization.getInstance().forceEapUpdateChannelForEapBuilds()) {
mySettings.setSelectedChannelStatus(ChannelStatus.EAP);
LOG.info("channel forced to 'eap'");
String title = IdeBundle.message("update.notifications.title");
String message = IdeBundle.message("update.channel.enforced", ChannelStatus.EAP);
notify(app, UpdateChecker.NOTIFICATIONS.createNotification(title, message, NotificationType.INFORMATION, null));
if (!ConfigImportHelper.isFirstSession()) {
String title = IdeBundle.message("update.notifications.title");
String message = IdeBundle.message("update.channel.enforced", ChannelStatus.EAP);
notify(app, UpdateChecker.NOTIFICATIONS.createNotification(title, message, NotificationType.INFORMATION, null));
}
}
if (!eap && current == ChannelStatus.EAP && Boolean.getBoolean(ConfigImportHelper.CONFIG_IMPORTED_IN_CURRENT_SESSION_KEY)) {
if (!eap && current == ChannelStatus.EAP && ConfigImportHelper.isConfigImported()) {
mySettings.setSelectedChannelStatus(ChannelStatus.RELEASE);
LOG.info("channel set to 'release'");
}

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