Merge branch 'master' of git@git.labs.intellij.net:idea/community

This commit is contained in:
Kirill Kalishev
2011-05-12 12:43:33 +04:00
72 changed files with 761 additions and 470 deletions
@@ -44,7 +44,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -205,20 +204,11 @@ public class JavaMarkObjectActionHandler extends MarkObjectActionHandler {
}
private static List<ObjectReference> getReferringObjects(ObjectReference value) {
// invoke the following method using Reflection in order to remain compilable on jdk 1.5
// java.util.List<com.sun.jdi.ObjectReference> referringObjects(long l);
try {
final Method apiMethod = ObjectReference.class.getMethod("referringObjects", long.class);
//noinspection unchecked
return (List<ObjectReference>)apiMethod.invoke(value, AUTO_MARKUP_REFERRING_OBJECTS_LIMIT);
return value.referringObjects(AUTO_MARKUP_REFERRING_OBJECTS_LIMIT);
}
catch (IllegalAccessException e) {
LOG.error(e); // should not happen
}
catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
catch (NoSuchMethodException ignored) {
catch (UnsupportedOperationException e) {
LOG.info(e);
}
return Collections.emptyList();
}
@@ -65,6 +65,6 @@ public class ObjectMarkupPropertiesDialog extends ValueMarkerPresentationDialogB
}
public boolean isMarkAdditionalFields() {
return myCbMarkAdditionalFields.isSelected();
return mySuggestAdditionalMarkup && myCbMarkAdditionalFields.isSelected();
}
}
@@ -23,13 +23,12 @@ import com.intellij.psi.PsiExpressionCodeFragment;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
public class TextWithImportsImpl implements TextWithImports{
public final class TextWithImportsImpl implements TextWithImports{
private final CodeFragmentKind myKind;
private String myText;
private final String myImports;
public TextWithImportsImpl (PsiExpression expression) {
myKind = CodeFragmentKind.EXPRESSION;
final String text = expression.getText();
@@ -92,9 +91,13 @@ public class TextWithImportsImpl implements TextWithImports{
}
public String toString() {
return getText();
}
public String toExternalForm() {
return "".equals(myImports) ? myText : myText + DebuggerEditorImpl.SEPARATOR + myImports;
}
public int hashCode() {
return myText.hashCode();
}
@@ -66,7 +66,7 @@ public class DebuggerUtilsImpl extends DebuggerUtilsEx{
public Element writeTextWithImports(TextWithImports text) {
Element element = new Element("TextWithImports");
element.setAttribute("text", text.toString());
element.setAttribute("text", text.toExternalForm());
element.setAttribute("type", text.getKind() == CodeFragmentKind.EXPRESSION ? "expression" : "code fragment");
return element;
}
@@ -85,7 +85,7 @@ public class DebuggerUtilsImpl extends DebuggerUtilsEx{
public void writeTextWithImports(Element root, String name, TextWithImports value) {
LOG.assertTrue(value.getKind() == CodeFragmentKind.EXPRESSION);
JDOMExternalizerUtil.writeField(root, name, value.toString());
JDOMExternalizerUtil.writeField(root, name, value.toExternalForm());
}
public TextWithImports readTextWithImports(Element root, String name) {
@@ -210,7 +210,7 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable{
exprColumn.setCellRenderer(new DefaultTableCellRenderer() {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
final TextWithImports textWithImports = (TextWithImports)value;
String text = (textWithImports != null)? textWithImports.toString() : "";
final String text = (textWithImports != null)? textWithImports.getText() : "";
return super.getTableCellRendererComponent(table, text, isSelected, hasFocus, row, column);
}
});
@@ -260,7 +260,7 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa
public void writeExternal(Element parentNode) throws WriteExternalException {
super.writeExternal(parentNode);
JDOMExternalizerUtil.writeField(parentNode, LOG_MESSAGE_OPTION_NAME, getLogMessage().toString());
JDOMExternalizerUtil.writeField(parentNode, LOG_MESSAGE_OPTION_NAME, getLogMessage().toExternalForm());
}
public TextWithImports getLogMessage() {
@@ -143,7 +143,7 @@ public abstract class FilteredRequestor implements LocatableEventRequestor, JDOM
public void writeExternal(Element parentNode) throws WriteExternalException {
DefaultJDOMExternalizer.writeExternal(this, parentNode);
JDOMExternalizerUtil.writeField(parentNode, CONDITION_OPTION_NAME, getCondition().toString());
JDOMExternalizerUtil.writeField(parentNode, CONDITION_OPTION_NAME, getCondition().toExternalForm());
DebuggerUtilsEx.writeFilters(parentNode, FILTER_OPTION_NAME, myClassFilters);
DebuggerUtilsEx.writeFilters(parentNode, EXCLUSION_FILTER_OPTION_NAME, myClassExclusionFilters);
DebuggerUtilsEx.writeFilters(parentNode, INSTANCE_ID_OPTION_NAME, InstanceFilter.createClassFilters(myInstanceFilters));
@@ -19,8 +19,15 @@ import org.jetbrains.annotations.NotNull;
public interface TextWithImports {
String getText();
void setText(String newText);
@NotNull String getImports();
@NotNull
String getImports();
CodeFragmentKind getKind();
boolean isEmpty();
String toExternalForm();
}
@@ -22,6 +22,7 @@ import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor;
import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler;
import com.intellij.codeInsight.guess.GuessManager;
import com.intellij.codeInsight.lookup.*;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -44,6 +45,8 @@ import com.intellij.psi.filters.element.ExcludeDeclaredFilter;
import com.intellij.psi.filters.element.ExcludeSillyAssignment;
import com.intellij.psi.html.HtmlTag;
import com.intellij.psi.impl.source.PsiImmediateClassType;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.impl.source.tree.TreeUtil;
import com.intellij.psi.javadoc.PsiDocToken;
import com.intellij.psi.scope.BaseScopeProcessor;
import com.intellij.psi.scope.ElementClassFilter;
@@ -764,7 +767,7 @@ public class JavaCompletionUtil {
assert document != null;
document.replaceString(startOffset, endOffset, name);
final RangeMarker toDelete = insertTemporary(startOffset + name.length(), document, "#");
final RangeMarker toDelete = insertTemporary(startOffset + name.length(), document, " ");
PsiDocumentManager.getInstance(project).commitAllDocuments();
@@ -781,9 +784,15 @@ public class JavaCompletionUtil {
? ((PsiImportStaticReferenceElement)ref).bindToTargetClass(psiClass)
: ref.bindToElement(psiClass);
RangeMarker marker = document.createRangeMarker(newElement.getTextRange());
ASTNode newNode = newElement.getNode();
CodeEditUtil.disablePostponedFormatting(newNode);
ASTNode next = TreeUtil.nextLeaf(newNode);
if (next != null) {
CodeEditUtil.disablePostponedFormatting(next);
}
newElement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(newElement);
newStartOffset = marker.getStartOffset();
newStartOffset = newElement.getTextRange().getStartOffset();
if (!staticImport &&
newElement instanceof PsiJavaCodeReferenceElement &&
@@ -71,7 +71,7 @@ public class WordCompletionTest extends CompletionTestCase {
}
};
PsiReferenceRegistrarImpl registrar =
(PsiReferenceRegistrarImpl)ReferenceProvidersRegistry.getInstance().getRegistrar(StdLanguages.JAVA);
ReferenceProvidersRegistry.getInstance().getRegistrar(StdLanguages.JAVA);
try {
registrar.registerReferenceProvider(PsiLiteralExpression.class, softProvider);
registrar.registerReferenceProvider(PsiLiteralExpression.class, hardProvider);
@@ -23,6 +23,7 @@ import com.intellij.lang.Commenter;
import com.intellij.lang.LanguageCommenters;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -61,7 +62,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
final String relativePath = quickFixTestCase.getBasePath() + "/" + BEFORE_PREFIX + testName;
final String testFullPath = quickFixTestCase.getTestDataPath().replace(File.separatorChar, '/') + relativePath;
final File testFile = new File(testFullPath);
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
CommandProcessor.getInstance().executeCommand(quickFixTestCase.getProject(), new Runnable() {
@Override
public void run() {
try {
@@ -263,17 +264,22 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
@Override
public void configureFromFileText(String name, String contents) throws IOException {
LightCodeInsightTestCase.configureFromFileText(name, contents);
LightQuickFixTestCase.configureFromFileText(name, contents);
}
@Override
public PsiFile getFile() {
return LightCodeInsightTestCase.getFile();
return LightQuickFixTestCase.getFile();
}
@Override
public Project getProject() {
return LightQuickFixTestCase.getProject();
}
@Override
public void bringRealEditorBack() {
LightCodeInsightTestCase.bringRealEditorBack();
LightQuickFixTestCase.bringRealEditorBack();
}
});
}
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.daemon.quickFix;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiFile;
@@ -57,4 +58,6 @@ public interface QuickFixTestCase {
void configureFromFileText(String name, String contents) throws Throwable;
PsiFile getFile();
Project getProject();
}
@@ -34,7 +34,7 @@ public class Extensions {
public static final ExtensionPointName<AreaListener> AREA_LISTENER_EXTENSION_POINT = new ExtensionPointName<AreaListener>("com.intellij.arealistener");
private static final Map<AreaInstance,ExtensionsAreaImpl> ourAreaInstance2area = new HashMap<AreaInstance, ExtensionsAreaImpl>();
private static final ExtensionsAreaImpl ourRootArea = createRootArea();
private static ExtensionsAreaImpl ourRootArea = createRootArea();
private static final MultiMap<String, AreaInstance> ourAreaClass2instances = new MultiMap<String, AreaInstance>();
private static final Map<AreaInstance,String> ourAreaInstance2class = new HashMap<AreaInstance, String>();
private static final Map<String,AreaClassConfiguration> ourAreaClass2Configuration = new HashMap<String, AreaClassConfiguration>();
@@ -42,7 +42,6 @@ public class Extensions {
private static ExtensionsAreaImpl createRootArea() {
ExtensionsAreaImpl rootArea = new ExtensionsAreaImpl(null, null, null, ourLogger);
rootArea.registerExtensionPoint(AREA_LISTENER_EXTENSION_POINT.getName(), AreaListener.class.getName());
ourAreaInstance2area.put(null, rootArea);
return rootArea;
}
@@ -72,7 +71,7 @@ public class Extensions {
oldRootArea.notifyAreaReplaced();
Disposer.register(parentDisposable, new Disposable() {
public void dispose() {
ourAreaInstance2area.put(null, oldRootArea);
ourRootArea = oldRootArea;
newArea.notifyAreaReplaced();
}
});
@@ -123,7 +122,7 @@ public class Extensions {
if (!ourAreaClass2Configuration.containsKey(areaClass)) {
throw new IllegalArgumentException("Area class is not registered: " + areaClass);
}
if (ourAreaInstance2area.containsKey(areaInstance)) {
if ((areaInstance == null && ourRootArea != null) || ourAreaInstance2area.containsKey(areaInstance)) {
throw new IllegalArgumentException("Area already instantiated for: " + areaInstance);
}
ExtensionsArea parentArea = getArea(parentAreaInstance);
@@ -0,0 +1,38 @@
/*
* Copyright 2000-2011 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.patterns;
import com.intellij.patterns.compiler.PatternCompilerFactory;
import com.intellij.psi.PsiElement;
import com.intellij.util.xmlb.annotations.Attribute;
import com.intellij.util.xmlb.annotations.Tag;
import com.intellij.util.xmlb.annotations.Text;
import org.jetbrains.annotations.Nullable;
@Tag("pattern")
public class ElementPatternBean {
@Attribute("type")
public String type;
@Text
public String text;
@Nullable
public ElementPattern<PsiElement> compilePattern() {
return PatternCompilerFactory.getFactory().<PsiElement>getPatternCompiler(type).compileElementPattern(text);
}
}
@@ -15,7 +15,10 @@ import com.intellij.openapi.extensions.ExtensionPointName;
* Some elements return them from {@link PsiElement#getReferences()} directly though, but one should not rely on that
* behavior since it may be changed in the future.
*
* The alternative way to register {@link PsiReferenceProvider} is by using {@link PsiReferenceProviderBean}.
*
* @author peter
* @see PsiReferenceProviderBean
*/
public abstract class PsiReferenceContributor implements Disposable {
public static final ExtensionPointName<PsiReferenceContributor> EP_NAME = ExtensionPointName.create("com.intellij.psi.referenceContributor");
@@ -20,6 +20,8 @@ import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
/**
* Register it via {@link PsiReferenceContributor} or {@link PsiReferenceProviderBean#EP_NAME}
*
* @author ik
*/
public abstract class PsiReferenceProvider {
@@ -19,27 +19,41 @@ package com.intellij.psi;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.AbstractExtensionPointBean;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.ElementPatternBean;
import com.intellij.patterns.StandardPatterns;
import com.intellij.patterns.compiler.PatternCompilerFactory;
import com.intellij.util.xmlb.annotations.*;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Attribute;
import com.intellij.util.xmlb.annotations.Property;
import com.intellij.util.xmlb.annotations.Tag;
import org.jetbrains.annotations.Nullable;
/**
* Registers a {@link PsiReferenceProvider} in plugin.xml
*/
public class PsiReferenceProviderBean extends AbstractExtensionPointBean {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.PsiReferenceProviderBean");
public static final ExtensionPointName<PsiReferenceProviderBean> EP_NAME =
new ExtensionPointName<PsiReferenceProviderBean>("com.intellij.psi.referenceProvider");
@Attribute("providerClass")
public String className;
@Tag("description")
public String description;
@Property(surroundWithTag = false)
@AbstractCollection(surroundWithTag = false)
public Info[] patterns;
public ElementPatternBean[] patterns;
public String getDescription() {
return description;
}
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.PsiReferenceProviderBean");
public PsiReferenceProvider instantiate() {
try {
return (PsiReferenceProvider)instantiate(className, ApplicationManager.getApplication().getPicoContainer());
@@ -50,30 +64,25 @@ public class PsiReferenceProviderBean extends AbstractExtensionPointBean {
return null;
}
private static final NullableFunction<ElementPatternBean,ElementPattern<? extends PsiElement>> PATTERN_NULLABLE_FUNCTION = new NullableFunction<ElementPatternBean, ElementPattern<? extends PsiElement>>() {
@Override
public ElementPattern<? extends PsiElement> fun(ElementPatternBean elementPatternBean) {
return elementPatternBean.compilePattern();
}
};
@Nullable
public ElementPattern<PsiElement> createElementPattern() {
final PatternCompilerFactory factory = PatternCompilerFactory.getFactory();
if (patterns.length > 1) {
final ElementPattern[] result = new ElementPattern[this.patterns.length];
for (int i = 0, len = this.patterns.length; i < len; i++) {
result[i] = factory.getPatternCompiler(patterns[i].type).compileElementPattern(patterns[i].text);
}
return StandardPatterns.or(result);
return StandardPatterns.or(ContainerUtil.mapNotNull(patterns,
PATTERN_NULLABLE_FUNCTION).toArray(new ElementPattern[0]));
}
else if (patterns.length == 1) {
return factory.<PsiElement>getPatternCompiler(patterns[0].type).compileElementPattern(patterns[0].text);
return patterns[0].compilePattern();
}
else {
LOG.error("At least one pattern should be specified");
return null;
}
}
@Tag("pattern")
public static class Info {
@Attribute("type")
public String type;
@Text
public String text;
}
}
@@ -20,6 +20,8 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import gnu.trove.THashSet;
import gnu.trove.TObjectHashingStrategy;
import java.util.*;
@@ -76,7 +78,7 @@ class LiftShorterItemsClassifier extends Classifier<LookupElement> {
}
private Iterable<List<LookupElement>> liftShorterElements(List<LookupElement> source, Set<LookupElement> lifted) {
final Set<LookupElement> srcSet = new HashSet<LookupElement>(source);
final Set<LookupElement> srcSet = new THashSet<LookupElement>(source, TObjectHashingStrategy.IDENTITY);
final Iterable<List<LookupElement>> classified = myNext.classify(source);
final Set<LookupElement> processed = new HashSet<LookupElement>();
@@ -84,6 +86,7 @@ class LiftShorterItemsClassifier extends Classifier<LookupElement> {
for (List<LookupElement> list : classified) {
final ArrayList<LookupElement> group = new ArrayList<LookupElement>();
for (LookupElement element : list) {
assert srcSet.contains(element) : myNext;
if (processed.add(element)) {
final List<String> prefixes = new SmartList<String>();
for (String string : getAllLookupStrings(element)) {
@@ -18,6 +18,8 @@ package com.intellij.codeInsight.lookup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.StripedLockConcurrentHashMap;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
import java.util.*;
@@ -26,7 +28,7 @@ import java.util.*;
* @author peter
*/
public abstract class ComparingClassifier<T> extends Classifier<T> {
private final Map<T, Comparable> myWeights = new HashMap<T, Comparable>();
private final Map<T, Comparable> myWeights = new StripedLockConcurrentHashMap<T, Comparable>(TObjectHashingStrategy.IDENTITY);
private final Classifier<T> myNext;
private final String myName;
@@ -49,7 +51,7 @@ public abstract class ComparingClassifier<T> extends Classifier<T> {
for (T t : source) {
final Comparable weight = myWeights.get(t);
if (weight == null) {
throw new AssertionError(myName + "; " + myWeights.containsKey(t));
throw new AssertionError(myName + "; " + myWeights.containsKey(t) + "; element=" + t);
}
List<T> list = map.get(weight);
if (list == null) {
@@ -84,7 +84,7 @@ public class ConversionContextImpl implements ConversionContext {
myWorkspaceFile = new File(StringUtil.trimEnd(projectPath, ProjectFileType.DOT_DEFAULT_EXTENSION) + WorkspaceFileType.DOT_DEFAULT_EXTENSION);
}
myModuleFiles = findModuleFiles(JDomConvertingUtil.loadDocument(modulesFile).getRootElement());
myModuleFiles = modulesFile.exists() ? findModuleFiles(JDomConvertingUtil.loadDocument(modulesFile).getRootElement()) : new File[0];
}
public Set<File> getAllProjectFiles() {
@@ -38,8 +38,7 @@ public abstract class AbstractBlockAlignmentProcessor implements BlockAlignmentP
return Result.TARGET_BLOCK_PROCESSED_NOT_ALIGNED;
}
WhiteSpace whiteSpace = context.targetBlock.getWhiteSpace();
if (whiteSpace.containsLineFeeds()) {
applyIndentToTheFirstBlockOnLine(indent, context);
if (whiteSpace.containsLineFeeds() && applyIndentToTheFirstBlockOnLine(indent, context)) {
return Result.TARGET_BLOCK_ALIGNED;
}
@@ -118,8 +117,10 @@ public abstract class AbstractBlockAlignmentProcessor implements BlockAlignmentP
*
* @param alignmentAnchorIndent alignment anchor indent
* @param context current processing context
* @return <code>true</code> if desired alignment indent is applied to the current block;
* <code>false</code> otherwise
*/
protected abstract void applyIndentToTheFirstBlockOnLine(@NotNull IndentData alignmentAnchorIndent, @NotNull Context context);
protected abstract boolean applyIndentToTheFirstBlockOnLine(@NotNull IndentData alignmentAnchorIndent, @NotNull Context context);
/**
* Calculates the difference between alignment anchor indent and current target block indent.
@@ -134,36 +134,6 @@ public abstract class AbstractBlockWrapper {
if (wrap != null) wrap.reset();
}
/**
* Calculates indent for the given block and target start offset according to the given indent options.
*
* @param options indent options to use
* @param block target wrapped block
* @param tokenBlockStartOffset target wrapped block offset
* @return indent to use for the given parameters
*/
private static IndentData getIndent(CodeStyleSettings.IndentOptions options,
AbstractBlockWrapper block,
final int tokenBlockStartOffset) {
final IndentImpl indent = block.getIndent();
if (indent.getType() == Indent.Type.CONTINUATION) {
return new IndentData(options.CONTINUATION_INDENT_SIZE);
}
if (indent.getType() == Indent.Type.CONTINUATION_WITHOUT_FIRST) {
if (block.getStartOffset() != block.getParent().getStartOffset() && block.getStartOffset() == tokenBlockStartOffset) {
return new IndentData(options.CONTINUATION_INDENT_SIZE);
}
else {
return new IndentData(0);
}
}
if (indent.getType() == Indent.Type.LABEL) return new IndentData(options.LABEL_INDENT_SIZE);
if (indent.getType() == Indent.Type.NONE) return new IndentData(0);
if (indent.getType() == Indent.Type.SPACES) return new IndentData(0, indent.getSpaces());
return new IndentData(options.INDENT_SIZE);
}
public IndentData getChildOffset(AbstractBlockWrapper child, CodeStyleSettings.IndentOptions options, int targetBlockStartOffset) {
final boolean childStartsNewLine = child.getWhiteSpace().containsLineFeeds();
IndentImpl.Type childIndentType = child.getIndent().getType();
@@ -173,7 +143,7 @@ public abstract class AbstractBlockWrapper {
if (childStartsNewLine
|| (!getWhiteSpace().containsLineFeeds() && RELATIVE_INDENT_TYPES.contains(childIndentType) && indentAlreadyUsedBefore(child)))
{
childIndent = getIndent(options, child, targetBlockStartOffset);
childIndent = CoreFormatterUtil.getIndent(options, child, targetBlockStartOffset);
}
else if (child.getIndent().isEnforceIndentToChildren() && !child.getWhiteSpace().containsLineFeeds()) {
// Enforce indent if child doesn't start new line, e.g. prefer the code below:
@@ -231,7 +201,7 @@ public abstract class AbstractBlockWrapper {
}
return anchorBlock.getNumberOfSymbolsBeforeBlock();
}
childIndent = getIndent(options, child, getStartOffset());
childIndent = CoreFormatterUtil.getIndent(options, child, getStartOffset());
}
else {
childIndent = new IndentData(0);
@@ -15,6 +15,7 @@
*/
package com.intellij.formatting;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
@@ -64,16 +65,19 @@ public interface BlockAlignmentProcessor {
@NotNull public final LeafBlockWrapper targetBlock;
@NotNull public final Map<AbstractBlockWrapper, Set<AbstractBlockWrapper>> alignmentMappings;
@NotNull public final Map<LeafBlockWrapper, Set<LeafBlockWrapper>> backwardShiftedAlignedBlocks;
@NotNull public final CodeStyleSettings.IndentOptions indentOptions;
public Context(@NotNull AlignmentImpl alignment,
@NotNull LeafBlockWrapper targetBlock,
@NotNull Map<AbstractBlockWrapper, Set<AbstractBlockWrapper>> alignmentMappings,
@NotNull Map<LeafBlockWrapper, Set<LeafBlockWrapper>> backwardShiftedAlignedBlocks)
@NotNull Map<LeafBlockWrapper, Set<LeafBlockWrapper>> backwardShiftedAlignedBlocks,
@NotNull CodeStyleSettings.IndentOptions indentOptions)
{
this.alignment = alignment;
this.targetBlock = targetBlock;
this.alignmentMappings = alignmentMappings;
this.backwardShiftedAlignedBlocks = backwardShiftedAlignedBlocks;
this.indentOptions = indentOptions;
}
}
}
@@ -15,6 +15,7 @@
*/
package com.intellij.formatting;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -207,4 +208,33 @@ public class CoreFormatterUtil {
return true;
}
/**
* Calculates indent for the given block and target start offset according to the given indent options.
*
* @param options indent options to use
* @param block target wrapped block
* @param tokenBlockStartOffset target wrapped block offset
* @return indent to use for the given parameters
*/
public static IndentData getIndent(CodeStyleSettings.IndentOptions options, AbstractBlockWrapper block,
final int tokenBlockStartOffset)
{
final IndentImpl indent = block.getIndent();
if (indent.getType() == Indent.Type.CONTINUATION) {
return new IndentData(options.CONTINUATION_INDENT_SIZE);
}
if (indent.getType() == Indent.Type.CONTINUATION_WITHOUT_FIRST) {
if (block.getStartOffset() != block.getParent().getStartOffset() && block.getStartOffset() == tokenBlockStartOffset) {
return new IndentData(options.CONTINUATION_INDENT_SIZE);
}
else {
return new IndentData(0);
}
}
if (indent.getType() == Indent.Type.LABEL) return new IndentData(options.LABEL_INDENT_SIZE);
if (indent.getType() == Indent.Type.NONE) return new IndentData(0);
if (indent.getType() == Indent.Type.SPACES) return new IndentData(0, indent.getSpaces());
return new IndentData(options.INDENT_SIZE);
}
}
@@ -599,7 +599,7 @@ class FormatProcessor {
}
BlockAlignmentProcessor.Context context = new BlockAlignmentProcessor.Context(
alignment, myCurrentBlock, myAlignmentMappings, myBackwardShiftedAlignedBlocks
alignment, myCurrentBlock, myAlignmentMappings, myBackwardShiftedAlignedBlocks, myIndentOption
);
BlockAlignmentProcessor.Result result = alignmentProcessor.applyAlignment(context);
switch (result) {
@@ -56,9 +56,10 @@ public class LeftEdgeAlignmentProcessor extends AbstractBlockAlignmentProcessor
}
@Override
protected void applyIndentToTheFirstBlockOnLine(@NotNull IndentData alignmentAnchorIndent, @NotNull Context context) {
protected boolean applyIndentToTheFirstBlockOnLine(@NotNull IndentData alignmentAnchorIndent, @NotNull Context context) {
WhiteSpace whiteSpace = context.targetBlock.getWhiteSpace();
whiteSpace.setSpaces(alignmentAnchorIndent.getSpaces(), alignmentAnchorIndent.getIndentSpaces());
return true;
}
@Override
@@ -52,15 +52,50 @@ public class RightEdgeAlignmentProcessor extends AbstractBlockAlignmentProcessor
}
@Override
protected void applyIndentToTheFirstBlockOnLine(@NotNull IndentData alignmentAnchorIndent, @NotNull Context context) {
protected boolean applyIndentToTheFirstBlockOnLine(@NotNull IndentData alignmentAnchorIndent, @NotNull Context context) {
WhiteSpace whiteSpace = context.targetBlock.getWhiteSpace();
int indentSpaces = alignmentAnchorIndent.getIndentSpaces();
int spaces = alignmentAnchorIndent.getSpaces() - context.targetBlock.getSymbolsAtTheLastLine();
if (spaces < 0) {
indentSpaces = Math.max(0, indentSpaces + spaces);
indentSpaces += spaces;
spaces = 0;
}
whiteSpace.setSpaces(spaces, indentSpaces);
if (indentSpaces >= 0) {
whiteSpace.setSpaces(spaces, indentSpaces);
return true;
}
if (whiteSpace.getTotalSpaces() > 0) {
// The general idea is that there is a possible case that particular block that starts new line is much wider than its
// preceding aligned block and its white space is not empty. We may move it to the left then trying to preserve its
// indent.
//
// Example:
// block11 block12
// test-block-that-has-rather-big-width-and-aligned-to-block12
// Let's say, the last block has indent '10', hence, the result would be:
// block11 block12
// test-block-that-has-rather-big-width-and-aligned-to-block12
CompositeBlockWrapper parent = context.targetBlock.getParent();
if (parent != null) {
IndentData childOffset = CoreFormatterUtil.getIndent(
context.indentOptions, context.targetBlock, context.targetBlock.getStartOffset()
);
if (whiteSpace.getTotalSpaces() > childOffset.getTotalSpaces()) {
int leftShift = whiteSpace.getTotalSpaces() - childOffset.getTotalSpaces();
if (leftShift >= whiteSpace.getSpaces()) {
spaces = 0;
indentSpaces = whiteSpace.getIndentSpaces() - (leftShift - whiteSpace.getSpaces());
}
else {
spaces = whiteSpace.getSpaces() - leftShift;
indentSpaces = whiteSpace.getIndentSpaces();
}
}
whiteSpace.setSpaces(spaces, indentSpaces);
}
}
return false;
}
@Override
@@ -107,7 +107,7 @@ public class NavBarModel {
updateModel(psiElement);
}
else {
if (UISettings.getInstance().SHOW_NAVIGATION_BAR) return;
if (UISettings.getInstance().SHOW_NAVIGATION_BAR && !myModel.isEmpty()) return;
Object moduleOrProject = LangDataKeys.MODULE.getData(dataContext);
if (moduleOrProject == null) {
@@ -25,6 +25,7 @@ import com.intellij.ide.ui.UISettingsListener;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.wm.IdeRootPaneNorthExtension;
@@ -48,6 +49,8 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
private NavBarPanel myNavigationBar;
private JPanel myRunPanel;
private boolean myNavToolbarGroupExist;
private JScrollPane myScrollPane;
private JLabel myCloseIcon;
public NavBarRootPaneExtension(Project project) {
myProject = project;
@@ -122,7 +125,6 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
}
};
myWrapperPanel.add(buildNavBarPanel(), BorderLayout.CENTER);
myWrapperPanel.putClientProperty("NavBarPanel", myNavigationBar);
toggleRunPanel(!UISettings.getInstance().SHOW_MAIN_TOOLBAR);
}
@@ -185,6 +187,49 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
private JComponent buildNavBarPanel() {
final JComponent result = new JPanel(new BorderLayout()) {
@Override
public void updateUI() {
super.updateUI();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
removeAll();
myScrollPane = null;
myCloseIcon = null;
if (myNavigationBar != null && !Disposer.isDisposed(myNavigationBar)) {
Disposer.dispose(myNavigationBar);
}
myNavigationBar = new NavBarPanel(myProject);
myWrapperPanel.putClientProperty("NavBarPanel", myNavigationBar);
myNavigationBar.getModel().setFixedComponent(true);
myScrollPane = ScrollPaneFactory.createScrollPane(myNavigationBar);
myScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
myScrollPane.setHorizontalScrollBar(null);
myScrollPane.setBorder(null);
myScrollPane.setOpaque(false);
myScrollPane.getViewport().setOpaque(false);
setBackground(UIUtil.isUnderGTKLookAndFeel() ? Color.WHITE : UIUtil.getListBackground());
setOpaque(!UIUtil.isUnderAquaLookAndFeel() || UISettings.getInstance().SHOW_MAIN_TOOLBAR);
setBorder(UIUtil.isUnderAquaLookAndFeel() ? BorderFactory.createEmptyBorder(2, 0, 2, 4) : new NavBarBorder(true, 0));
myNavigationBar.setBorder(null);
add(myScrollPane, BorderLayout.CENTER);
if (!SystemInfo.isMac) {
myCloseIcon = new JLabel(CROSS_ICON);
myCloseIcon.addMouseListener(new MouseAdapter() {
public void mouseClicked(final MouseEvent e) {
UISettings.getInstance().SHOW_NAVIGATION_BAR = false;
uiSettingsChanged(UISettings.getInstance());
}
});
add(myCloseIcon, BorderLayout.EAST);
}
}
});
}
@Override
protected void paintComponent(Graphics g) {
if (UIUtil.isUnderAquaLookAndFeel()) {
@@ -231,9 +276,9 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
final Rectangle r = getBounds();
final Insets insets = getInsets();
int x = insets.left;
final Component navBar = getComponent(0);
final Component closeLabel = getComponentCount() == 2 ? getComponent(1) : null;
if (myScrollPane == null) return;
final Component navBar = myScrollPane;
final Component closeLabel = myCloseIcon;
final Dimension preferredSize = navBar.getPreferredSize();
final Dimension closePreferredSize = closeLabel == null ? new Dimension() : closeLabel.getPreferredSize();
@@ -248,37 +293,7 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
}
}
};
result.setBackground(UIUtil.isUnderGTKLookAndFeel() ? Color.WHITE : UIUtil.getListBackground());
result.setOpaque(!UIUtil.isUnderAquaLookAndFeel() || UISettings.getInstance().SHOW_MAIN_TOOLBAR);
myNavigationBar = new NavBarPanel(myProject);
myNavigationBar.getModel().setFixedComponent(true);
JScrollPane scroller = ScrollPaneFactory.createScrollPane(myNavigationBar);
scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
scroller.setHorizontalScrollBar(null);
scroller.setBorder(null);
scroller.setOpaque(false);
scroller.getViewport().setOpaque(false);
result.add(scroller, BorderLayout.CENTER);
if (!SystemInfo.isMac) {
JLabel closeLabel = new JLabel(CROSS_ICON);
closeLabel.addMouseListener(new MouseAdapter() {
public void mouseClicked(final MouseEvent e) {
UISettings.getInstance().SHOW_NAVIGATION_BAR = false;
uiSettingsChanged(UISettings.getInstance());
}
});
result.add(closeLabel, BorderLayout.EAST);
}
result.setBorder(UIUtil.isUnderAquaLookAndFeel() ? BorderFactory.createEmptyBorder(2, 0, 2, 4) : new NavBarBorder(true, 0));
myNavigationBar.setBorder(null);
return result;
}
@@ -1,44 +0,0 @@
/*
* Copyright 2000-2010 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;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.patterns.ElementPattern;
/**
* @author Gregory.Shrago
*/
public class PsiReferenceContributorImpl extends PsiReferenceContributor {
public static final ExtensionPointName<PsiReferenceProviderBean> PSI_REFERENCE_PROVIDERS_EP =
new ExtensionPointName<PsiReferenceProviderBean>("com.intellij.psi.referenceProvider");
@Override
public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
for (PsiReferenceProviderBean providerBean : PSI_REFERENCE_PROVIDERS_EP.getExtensions()) {
registerReferenceProvider(registrar, providerBean);
}
}
private static void registerReferenceProvider(PsiReferenceRegistrar registrar, PsiReferenceProviderBean providerBean) {
final ElementPattern<PsiElement> pattern = providerBean.createElementPattern();
if (pattern != null) {
final PsiReferenceProvider provider = providerBean.instantiate();
if (provider != null) {
registrar.registerReferenceProvider(pattern, provider);
}
}
}
}
@@ -477,6 +477,8 @@ public class PostprocessReformattingAspect implements PomModelAspect, Disposable
protected boolean visitNode(TreeElement element) {
if (nodesToProcess.contains(element)) return false;
if (CodeEditUtil.isPostponedFormattingDisabled(element)) return false;
final boolean currentNodeGenerated = CodeEditUtil.isNodeGenerated(element);
CodeEditUtil.setNodeGenerated(element, false);
if (currentNodeGenerated && !inGeneratedContext) {
@@ -507,6 +509,8 @@ public class PostprocessReformattingAspect implements PomModelAspect, Disposable
inGeneratedContext = oldGeneratedContext;
}
});
CodeEditUtil.enablePostponedFormattingInTree(node);
}
}
@@ -29,10 +29,7 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.impl.source.tree.Factory;
import com.intellij.psi.impl.source.tree.LeafElement;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.impl.source.tree.TreeUtil;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.templateLanguages.OuterLanguageElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiUtilBase;
@@ -45,6 +42,7 @@ public class CodeEditUtil {
private static final Key<Integer> INDENT_INFO = new Key<Integer>("INDENT_INFO");
private static final Key<Boolean> REFORMAT_BEFORE_KEY = new Key<Boolean>("REFORMAT_BEFORE_KEY");
private static final Key<Boolean> REFORMAT_KEY = new Key<Boolean>("REFORMAT_KEY");
private static final Key<Boolean> DISABLE_POSTPONED_REFORMAT_KEY = new Key<Boolean>("DISABLE_POSTPONED_REFORMAT_KEY");
private static final ThreadLocal<Boolean> ALLOW_TO_MARK_NODES_TO_REFORMAT = new ThreadLocal<Boolean>() {
@Override
protected Boolean initialValue() {
@@ -330,12 +328,7 @@ public class CodeEditUtil {
}
public static void markToReformatBefore(final ASTNode right, boolean value) {
if (value) {
right.putCopyableUserData(REFORMAT_BEFORE_KEY, true);
}
else {
right.putCopyableUserData(REFORMAT_BEFORE_KEY, null);
}
right.putCopyableUserData(REFORMAT_BEFORE_KEY, value ? true : null);
}
private static int getBlankLines(final String text) {
@@ -400,12 +393,7 @@ public class CodeEditUtil {
public static void setNodeGenerated(final ASTNode next, final boolean value) {
if (next == null) return;
if (value) {
next.putCopyableUserData(GENERATED_FLAG, true);
}
else {
next.putCopyableUserData(GENERATED_FLAG, null);
}
next.putCopyableUserData(GENERATED_FLAG, value ? true : null);
}
public static void setOldIndentation(final TreeElement treeElement, final int oldIndentation) {
@@ -429,7 +417,7 @@ public class CodeEditUtil {
* @return <code>true</code> if given node is configured to be reformatted; <code>false</code> otherwise
*/
public static boolean isMarkedToReformat(final ASTNode node) {
return node.getCopyableUserData(REFORMAT_KEY) != null && ALLOW_NODES_REFORMATTING.get();
return node.getCopyableUserData(REFORMAT_KEY) != null && isSuspendedNodesReformattingAllowed();
}
/**
@@ -444,6 +432,26 @@ public class CodeEditUtil {
}
}
public static void disablePostponedFormatting(@NotNull final ASTNode node) {
markToReformat(node, false);
markToReformatBefore(node, false);
node.putUserData(DISABLE_POSTPONED_REFORMAT_KEY, true);
}
public static void enablePostponedFormattingInTree(@NotNull ASTNode root) {
((TreeElement)root).acceptTree(new RecursiveTreeElementVisitor() {
protected boolean visitNode(TreeElement element) {
element.putUserData(DISABLE_POSTPONED_REFORMAT_KEY, null);
return true;
}
});
}
public static boolean isPostponedFormattingDisabled(@NotNull final ASTNode node) {
return node.getUserData(DISABLE_POSTPONED_REFORMAT_KEY) != null;
}
/**
* We allow to mark particular {@link ASTNode AST nodes} to be reformatted later (e.g. we may want method definition and calls
* to be reformatted when we perform <code>'change method signature'</code> refactoring. Hence, we mark corresponding expressions
@@ -22,6 +22,7 @@ import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.util.Trinity;
import com.intellij.patterns.ElementPattern;
import com.intellij.psi.*;
import com.intellij.util.ProcessingContext;
import com.intellij.util.SmartList;
@@ -52,9 +53,16 @@ public class ReferenceProvidersRegistry {
return o2.getThird().compareTo(o1.getThird());
}
};
public final static PsiReferenceProvider NULL_REFERENCE_PROVIDER = new PsiReferenceProvider() {
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
return PsiReference.EMPTY_ARRAY;
}
};
@SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
private final static Map<Language, PsiReferenceRegistrarImpl> ourRegistrars = new FactoryMap<Language, PsiReferenceRegistrarImpl>() {
private final Map<Language, PsiReferenceRegistrarImpl> myRegistrars = new FactoryMap<Language, PsiReferenceRegistrarImpl>() {
@Override
protected PsiReferenceRegistrarImpl create(Language language) {
PsiReferenceRegistrarImpl registrar = new PsiReferenceRegistrarImpl();
@@ -70,8 +78,36 @@ public class ReferenceProvidersRegistry {
return ServiceManager.getService(ReferenceProvidersRegistry.class);
}
public PsiReferenceRegistrar getRegistrar(Language language) {
return ourRegistrars.get(language);
public ReferenceProvidersRegistry() {
PsiReferenceRegistrarImpl registrar = getRegistrar(Language.ANY);
for (final PsiReferenceProviderBean providerBean : PsiReferenceProviderBean.EP_NAME.getExtensions()) {
final ElementPattern<PsiElement> pattern = providerBean.createElementPattern();
if (pattern != null) {
registrar.registerReferenceProvider(pattern, new PsiReferenceProvider() {
PsiReferenceProvider myProvider;
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
if (myProvider == null) {
myProvider = providerBean.instantiate();
if (myProvider == null) {
myProvider = NULL_REFERENCE_PROVIDER;
}
}
return myProvider.getReferencesByElement(element, context);
}
});
}
}
}
public PsiReferenceRegistrarImpl getRegistrar(Language language) {
return myRegistrars.get(language);
}
@Deprecated
@@ -83,10 +119,11 @@ public class ReferenceProvidersRegistry {
ProgressManager.checkCanceled();
assert context.isValid() : "Invalid context: " + context;
PsiReferenceRegistrarImpl registrar = ourRegistrars.get(context.getLanguage());
ReferenceProvidersRegistry registry = getInstance();
PsiReferenceRegistrarImpl registrar = registry.getRegistrar(context.getLanguage());
SmartList<Trinity<PsiReferenceProvider, ProcessingContext, Double>> providers = new SmartList<Trinity<PsiReferenceProvider, ProcessingContext, Double>>();
providers.addAll(registrar.getPairsByElement(context, hints));
providers.addAll(ourRegistrars.get(Language.ANY).getPairsByElement(context, hints));
providers.addAll(registry.getRegistrar(Language.ANY).getPairsByElement(context, hints));
if (providers.isEmpty()) {
return PsiReference.EMPTY_ARRAY;
}
@@ -50,7 +50,7 @@ public class AstBufferUtil {
if (composite instanceof LazyParseableElement) {
LazyParseableElement lpe = (LazyParseableElement)composite;
int lpeResult = lpe.copyTo(buffer, result[0]);
if (lpeResult > 0) {
if (lpeResult >= 0) {
result[0] = lpeResult;
return;
}
@@ -30,7 +30,7 @@ public class EscapeHandler extends EditorActionHandler {
public void execute(Editor editor, DataContext dataContext) {
Project project = PlatformDataKeys.PROJECT.getData(dataContext);
if (project == null || !HintManagerImpl.getInstanceImpl().hideHints(HintManagerImpl.HIDE_BY_ESCAPE | HintManagerImpl.HIDE_BY_ANY_KEY, true, false)) {
if (project == null || !HintManagerImpl.getInstanceImpl().hideHints(HintManager.HIDE_BY_ESCAPE | HintManager.HIDE_BY_ANY_KEY, true, false)) {
myOriginalHandler.execute(editor, dataContext);
}
}
@@ -405,7 +405,9 @@ public class HintManagerImpl extends HintManager implements Disposable {
LOG.assertTrue(SwingUtilities.isEventDispatchThread());
List<HintInfo> hints = new ArrayList<HintInfo>(myHintsStack);
for (HintInfo info : hints) {
info.hint.hide();
if (!info.hint.vetoesHiding()) {
info.hint.hide();
}
}
cleanup();
}
@@ -16,10 +16,12 @@
package com.intellij.ide.actions;
import com.intellij.ide.IdeBundle;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorAction;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.editor.actions.TextComponentEditorAction;
import com.intellij.openapi.project.DumbAware;
@@ -27,7 +29,6 @@ import com.intellij.openapi.project.DumbAware;
public class SelectAllAction extends TextComponentEditorAction implements DumbAware {
public SelectAllAction() {
super(new Handler());
setEnabledInModalContext(true);
}
private static class Handler extends EditorActionHandler {
@@ -55,7 +55,7 @@ public class StatisticsConfigurable implements SearchableConfigurable {
@Nullable
@NonNls
public String getHelpTopic() {
return null;
return "preferences.usage.statictics";
}
public JComponent createComponent() {
@@ -14,7 +14,7 @@
</constraints>
<properties>
<font style="1"/>
<text value="Help improve IntelliJ IDEA by sending anonymous usage statistics to JetBrains"/>
<text value="Help improve our products by sending anonymous usage statistics to JetBrains"/>
</properties>
</component>
<grid id="2f6db" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -16,6 +16,7 @@
package com.intellij.internal.statistic.configurable;
import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.ui.ex.MultiLineLabel;
import javax.swing.*;
@@ -32,6 +33,7 @@ public class StatisticsConfigurationComponent {
private JLabel myLabel;
public StatisticsConfigurationComponent() {
myTitle.setText("Help improve "+ ApplicationNamesInfo.getInstance().getFullProductName() + " by sending anonymous usage statistics to JetBrains");
myLabel.setText("<html>We're asking your permission to send information about your plugins configuration (what is enabled and what is not) <br> and feature usage statistics (e.g. how frequently you're using code completion).<br> This data is anonymous, does not contain any personal information, collected for use only by JetBrains<br> and will never be transmitted to any third party.</html>");
}
@@ -29,6 +29,7 @@ import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
public class EscapeAction extends EditorAction {
public EscapeAction() {
super(new Handler());
setInjectedContext(true);
}
private static class Handler extends EditorActionHandler {
@@ -42,6 +42,7 @@ import com.intellij.openapi.vfs.VirtualFile;
public class TabAction extends EditorAction {
public TabAction() {
super(new Handler());
setInjectedContext(true);
}
private static class Handler extends EditorWriteActionHandler {
@@ -89,7 +90,7 @@ public class TabAction extends EditorAction {
EditorModificationUtil.typeInStringAtCaretHonorBlockSelection(editor, "\t", false);
}
else {
StringBuffer buffer = new StringBuffer();
StringBuilder buffer = new StringBuilder(spacesToAddCount);
for(int i=0; i<spacesToAddCount; i++) {
buffer.append(' ');
}
@@ -31,7 +31,6 @@ import javax.swing.text.JTextComponent;
public abstract class TextComponentEditorAction extends EditorAction {
protected TextComponentEditorAction(final EditorActionHandler defaultHandler) {
super(defaultHandler);
setEnabledInModalContext(true);
}
@Nullable
@@ -208,7 +208,7 @@ public class PluginDownloader {
pluginsTemp.mkdirs();
}
File file = FileUtil.createTempFile(pluginsTemp, "plugin", "download", true);
File file = FileUtil.createTempFile(pluginsTemp, "plugin", "download", true, false);
int responseCode = connection.getResponseCode();
switch (responseCode) {
@@ -66,7 +66,7 @@ import java.util.*;
public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
private static final VirtualFileSystemEntry NULL_VIRTUAL_FILE = new VirtualFileImpl("*?;%NULL", null, -42);
private final NewVirtualFileSystem myFS;
private static final boolean IS_UNIT_TESTS = ApplicationManager.getApplication().isUnitTestMode();
private static final boolean IS_UNIT_TESTS = false;//ApplicationManager.getApplication().isUnitTestMode();
// guarded by this
private Object myChildren; // Either HashMap<String, VFile> or VFile[]
@@ -206,7 +206,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
if (!isUnder) {
if (!allowed.isEmpty()) {
assert false : "File accessed outside project: " + child +"; project roots: "+new ArrayList(allowed);
//assert false : "File accessed outside project: " + child +"; project roots: "+new ArrayList(allowed);
}
}
}
@@ -120,6 +120,7 @@ action.EditorKillToWordEnd.text=Kill to Word End
action.EditorKillRegion.text=Kill Selected Region
action.EditorKillRingSave.text=Save to Kill Ring
action.EditorDuplicate.text=Duplicate Line or Block
action.EditorDuplicateLines.text=Duplicate Lines
action.EditorSelectWord.text=Select Word at Caret
action.EditorUnSelectWord.text=Unselect Word at Caret
action.EditorToggleInsertState.text=Toggle Insert/Overwrite
@@ -397,8 +397,6 @@
<applicationService serviceInterface="com.intellij.execution.console.ConsoleFoldingSettings" serviceImplementation="com.intellij.execution.console.ConsoleFoldingSettings"/>
<console.folding implementation="com.intellij.execution.console.SubstringConsoleFolding"/>
<psi.referenceContributor implementation="com.intellij.psi.PsiReferenceContributorImpl"/>
<lookup.charFilter implementation="com.intellij.codeInsight.template.impl.LiveTemplateCharFilter" order="first" id="liveTemplate"/>
<lookup.charFilter implementation="com.intellij.codeInsight.completion.CompletionCharFilter" order="last" id="completion"/>
<lookup.charFilter implementation="com.intellij.refactoring.IdentifierCharFilter" id="identifier"/>
@@ -354,12 +354,18 @@ public class FileUtil {
@NotNull
public static File createTempFile(@NonNls final File dir, @NotNull @NonNls String prefix, @NonNls String suffix, final boolean create) throws IOException{
return createTempFile(dir, prefix, suffix, create, true);
}
public static File createTempFile(@NonNls final File dir, @NotNull @NonNls String prefix, @NonNls String suffix, final boolean create, boolean removeOnExit) throws IOException {
File file = doCreateTempFile(prefix, suffix, dir);
file.delete();
if (create) {
file.createNewFile();
}
file.deleteOnExit();
if (removeOnExit) {
file.deleteOnExit();
}
return file;
}
@@ -1,20 +0,0 @@
/*
* Copyright 2000-2009 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.util.xmlb.annotations;
public @interface Collection {
}
@@ -270,4 +270,9 @@ public class XBreakpointBase<Self extends XBreakpoint<P>, P extends XBreakpointP
return new XBreakpointBase<B, P, BreakpointState<B,P,?>>(type, breakpointManager, this);
}
}
@Override
public String toString() {
return "XBreakpointBase(type=" + myType + ")";
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2009 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,19 +49,6 @@ public class ReplaceForEachLoopWithIteratorForLoopIntention extends Intention {
if (iteratedValue == null) {
return;
}
final PsiType type = iteratedValue.getType();
final PsiType iteratedValueParameterType;
if (type instanceof PsiClassType) {
final PsiClassType classType = (PsiClassType)type;
final PsiType[] parameterTypes = classType.getParameters();
if (parameterTypes.length == 0) {
iteratedValueParameterType = null;
} else {
iteratedValueParameterType = parameterTypes[0];
}
} else {
iteratedValueParameterType = null;
}
@NonNls final StringBuilder newStatement = new StringBuilder();
final PsiParameter iterationParameter =
statement.getIterationParameter();
@@ -71,13 +58,9 @@ public class ReplaceForEachLoopWithIteratorForLoopIntention extends Intention {
statement, true);
final String typeText = parameterType.getCanonicalText();
newStatement.append("for(java.util.Iterator");
if (iteratedValueParameterType == null) {
newStatement.append(' ');
} else {
newStatement.append('<');
newStatement.append(iteratedValueParameterType.getCanonicalText());
newStatement.append("> ");
}
newStatement.append('<');
newStatement.append(typeText);
newStatement.append("> ");
newStatement.append(iterator);
newStatement.append(" = ");
if (iteratedValue instanceof PsiTypeCastExpression) {
@@ -99,12 +82,6 @@ public class ReplaceForEachLoopWithIteratorForLoopIntention extends Intention {
newStatement.append(' ');
newStatement.append(iterationParameter.getName());
newStatement.append(" = ");
if (iteratedValueParameterType == null && !
"java.lang.Object".equals(typeText)) {
newStatement.append('(');
newStatement.append(typeText);
newStatement.append(')');
}
newStatement.append(iterator);
newStatement.append(".next();");
final PsiStatement body = statement.getBody();
@@ -51,6 +51,9 @@ import git4idea.commands.*;
import git4idea.config.GitVcsSettings;
import git4idea.i18n.GitBundle;
import git4idea.rebase.GitRebaser;
import git4idea.stash.GitChangesSaver;
import git4idea.stash.GitShelveChangesSaver;
import git4idea.stash.GitStashChangesSaver;
import git4idea.ui.GitUIUtil;
import git4idea.update.*;
import org.jetbrains.annotations.NotNull;
@@ -44,8 +44,8 @@ import git4idea.checkout.branches.GitBranchConfigurations.BranchChanges;
import git4idea.checkout.branches.GitBranchConfigurations.ChangeInfo;
import git4idea.checkout.branches.GitBranchConfigurations.ChangeListInfo;
import git4idea.commands.*;
import git4idea.stash.GitShelveUtils;
import git4idea.ui.GitUIUtil;
import git4idea.update.GitStashUtils;
import org.jetbrains.annotations.Nullable;
import java.io.File;
@@ -591,52 +591,53 @@ public class GitCheckoutProcess {
};
continuation.addExceptionHandler(VcsException.class, exceptionConsumer);
final GatheringContinuationContext initContext = new GatheringContinuationContext();
GitStashUtils.doSystemUnshelve(myProject, shelve, myShelveManager, new Runnable() {
@Override
public void run() {
final HashMap<Pair<String, String>, String> parsedChanges = new HashMap<Pair<String, String>, String>();
for (ChangeInfo changeInfo : changes.CHANGES) {
String before = changeInfo.BEFORE_PATH;
String after = changeInfo.AFTER_PATH;
parsedChanges.put(Pair.create(before, after), changeInfo.CHANGE_LIST_NAME);
}
try {
HashMap<String, LocalChangeList> lists = new HashMap<String, LocalChangeList>();
final List<LocalChangeList> existedChangeLists = myChangeManager.getChangeLists();
for (LocalChangeList localChangeList : existedChangeLists) {
lists.put(localChangeList.getName(), localChangeList);
}
LocalChangeList defaultList = myChangeManager.getDefaultChangeList();
for (ChangeListInfo changeListInfo : changes.CHANGE_LISTS) {
LocalChangeList changeList = lists.get(changeListInfo.NAME);
if (changeList == null) {
changeList = myChangeManager.addChangeList(changeListInfo.NAME, changeListInfo.COMMENT);
lists.put(changeListInfo.NAME, changeList);
}
if (changeListInfo.IS_DEFAULT) {
myChangeManager.setDefaultChangeList(changeList);
}
}
for (Change change : defaultList.getChanges()) {
ContentRevision beforeRevision = change.getBeforeRevision();
String before = beforeRevision == null ? null : beforeRevision.getFile().getPath();
ContentRevision afterRevision = change.getAfterRevision();
String after = afterRevision == null ? null : afterRevision.getFile().getPath();
Pair<String, String> key = Pair.create(before, after);
String listName = parsedChanges.get(key);
assert listName != null : "List name should be found: " + key;
if (!listName.equals(defaultList.getName())) {
LocalChangeList changeList = lists.get(listName);
assert changeList != null : "Change List should be found: " + listName;
myChangeManager.moveChangesTo(changeList, new Change[]{change});
}
}
}
catch (Throwable t) {
exceptionConsumer.consume(new VcsException(t));
}
}
}, initContext);
GitShelveUtils.doSystemUnshelve(myProject, shelve, myShelveManager, new Runnable() {
@Override
public void run() {
final HashMap<Pair<String, String>, String> parsedChanges =
new HashMap<Pair<String, String>, String>();
for (ChangeInfo changeInfo : changes.CHANGES) {
String before = changeInfo.BEFORE_PATH;
String after = changeInfo.AFTER_PATH;
parsedChanges.put(Pair.create(before, after), changeInfo.CHANGE_LIST_NAME);
}
try {
HashMap<String, LocalChangeList> lists = new HashMap<String, LocalChangeList>();
final List<LocalChangeList> existedChangeLists = myChangeManager.getChangeLists();
for (LocalChangeList localChangeList : existedChangeLists) {
lists.put(localChangeList.getName(), localChangeList);
}
LocalChangeList defaultList = myChangeManager.getDefaultChangeList();
for (ChangeListInfo changeListInfo : changes.CHANGE_LISTS) {
LocalChangeList changeList = lists.get(changeListInfo.NAME);
if (changeList == null) {
changeList = myChangeManager.addChangeList(changeListInfo.NAME, changeListInfo.COMMENT);
lists.put(changeListInfo.NAME, changeList);
}
if (changeListInfo.IS_DEFAULT) {
myChangeManager.setDefaultChangeList(changeList);
}
}
for (Change change : defaultList.getChanges()) {
ContentRevision beforeRevision = change.getBeforeRevision();
String before = beforeRevision == null ? null : beforeRevision.getFile().getPath();
ContentRevision afterRevision = change.getAfterRevision();
String after = afterRevision == null ? null : afterRevision.getFile().getPath();
Pair<String, String> key = Pair.create(before, after);
String listName = parsedChanges.get(key);
assert listName != null : "List name should be found: " + key;
if (!listName.equals(defaultList.getName())) {
LocalChangeList changeList = lists.get(listName);
assert changeList != null : "Change List should be found: " + listName;
myChangeManager.moveChangesTo(changeList, new Change[]{change});
}
}
}
catch (Throwable t) {
exceptionConsumer.consume(new VcsException(t));
}
}
}, initContext);
continuation.run(initContext.getList());
}
@@ -742,7 +743,7 @@ public class GitCheckoutProcess {
if (progress != null) {
progress.setText("Creating shelve: " + description);
}
ShelvedChangeList shelved = GitStashUtils.shelveChanges(myProject, myShelveManager, toShelve, description, myExceptions);
ShelvedChangeList shelved = GitShelveUtils.shelveChanges(myProject, myShelveManager, toShelve, description, myExceptions);
if (shelved == null) {
return null;
}
@@ -60,15 +60,6 @@ public class GitFileUtils {
}
}
public static void cherryPick(final Project project, final VirtualFile root, final String hash) throws VcsException {
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.CHERRY_PICK);
handler.addParameters("-x", "-n", hash);
handler.endOptions();
//handler.addRelativePaths(new FilePathImpl(root));
handler.setNoSSH(true);
handler.run();
}
/**
* Delete files
*
@@ -35,20 +35,14 @@ import git4idea.config.GitVcsSettings;
import git4idea.config.GitVersionSpecialty;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.git4idea.ssh.GitSSHHandler;
import org.jetbrains.git4idea.ssh.GitSSHService;
import java.io.File;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
/**
@@ -635,7 +629,7 @@ public abstract class GitHandler {
return myCommandLine.getCommandLineString().length() > VcsFileUtil.FILE_PATH_LIMIT;
}
public void runInCurrentThread(Runnable postStartAction) {
public void runInCurrentThread(@Nullable Runnable postStartAction) {
final GitVcs vcs = GitVcs.getInstance(myProject);
if (vcs == null) { return; }
@@ -502,7 +502,7 @@ public class GitHistoryUtils {
final String s = parseRefs(refs, currentRefs, locals, remotes, tags);
gitCommit = new GitCommit(AbstractHash.create(record.getShortHash()), new SHAHash(record.getHash()), record.getAuthorName(),
record.getCommitterName(),
record.getDate(), record.getFullMessage(),
record.getDate(), record.getSubject(), record.getFullMessage(),
new HashSet<String>(Arrays.asList(record.getParentsShortHashes())), record.getFilePaths(root),
record.getAuthorEmail(),
record.getCommitterEmail(), tags, locals, remotes,
@@ -17,13 +17,13 @@ package git4idea.history.browser;
import com.intellij.lifecycle.PeriodicalTasksCloser;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.vcs.AbstractVcsHelper;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.*;
import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
@@ -31,6 +31,8 @@ import git4idea.GitVcs;
import java.util.*;
import static com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier.showOverChangesView;
public class CherryPicker {
private final GitVcs myVcs;
private final List<GitCommit> myCommits;
@@ -41,6 +43,7 @@ public class CherryPicker {
private final List<FilePath> myDirtyFiles;
private final List<String> myMessagesInOrder;
private final Map<String, Collection<FilePath>> myFilesToMove;
private boolean myConflictsExist;
public CherryPicker(GitVcs vcs, final List<GitCommit> commits, LowLevelAccess access) {
myVcs = vcs;
@@ -90,15 +93,19 @@ public class CherryPicker {
}
private void showResults() {
if (myExceptions.isEmpty()) {
VcsBalloonProblemNotifier
.showOverChangesView(myVcs.getProject(), "Successful cherry-pick into working tree, please commit changes", MessageType.INFO);
final Project project = myVcs.getProject();
if (myExceptions.isEmpty() && !myConflictsExist) {
showOverChangesView(project, "Successful cherry-pick into working tree, please commit changes", MessageType.INFO);
} else {
VcsBalloonProblemNotifier.showOverChangesView(myVcs.getProject(), "Errors in cherry-pick", MessageType.ERROR);
if (myExceptions.isEmpty()) {
showOverChangesView(project, "Unresolved conflicts while cherry-picking. Resolve conflicts, then commit changes", MessageType.WARNING);
} else {
showOverChangesView(project, "Errors in cherry-pick", MessageType.ERROR);
}
}
if ((! myExceptions.isEmpty()) || (! myWarnings.isEmpty())) {
myExceptions.addAll(myWarnings);
AbstractVcsHelper.getInstance(myVcs.getProject()).showErrors(myExceptions, "Cherry-pick problems");
AbstractVcsHelper.getInstance(project).showErrors(myExceptions, "Cherry-pick problems");
}
}
@@ -129,9 +136,10 @@ public class CherryPicker {
private void cherryPickStep(CheckinEnvironment ce, int i) {
final GitCommit commit = myCommits.get(i);
final SHAHash hash = commit.getHash();
try {
myAccess.cherryPick(hash);
if (!myAccess.cherryPick(commit)) {
myConflictsExist = true;
}
}
catch (VcsException e) {
myExceptions.add(e);
@@ -141,7 +149,7 @@ public class CherryPicker {
final Collection<FilePath> paths = ChangesUtil.getPaths(changes);
String message = ce.getDefaultMessageFor(paths.toArray(new FilePath[paths.size()]));
message = (message == null) ? new StringBuilder().append(commit.getDescription()).append("(cherry picked from commit ")
.append(hash.getValue()).append(")").toString() : message;
.append(commit.getShortHash()).append(")").toString() : message;
myMessagesInOrder.add(message);
myFilesToMove.put(message, paths);
@@ -31,6 +31,7 @@ public class GitCommit {
private final SHAHash myHash;
private final String myAuthor;
private final String myCommitter;
private final String mySubject;
private final String myDescription;
private final Date myDate;
@@ -60,6 +61,7 @@ public class GitCommit {
final String author,
final String committer,
final Date date,
final String subject,
final String description,
final Set<String> parentsHashes,
final List<FilePath> pathsList,
@@ -74,6 +76,7 @@ public class GitCommit {
myAuthor = author;
myCommitter = committer;
myDate = date;
mySubject = subject;
myDescription = description;
myHash = hash;
myParentsHashes = parentsHashes;
@@ -223,4 +226,8 @@ public class GitCommit {
}
});
}
public String getSubject() {
return mySubject;
}
}
@@ -16,7 +16,6 @@
package git4idea.history.browser;
import com.intellij.openapi.util.Getter;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.AsynchConsumer;
@@ -57,7 +56,14 @@ public interface LowLevelAccess {
void loadAllTags(final Collection<String> sink) throws VcsException;
void cherryPick(SHAHash hash) throws VcsException;
/**
* Cherry-picks the specified commit.
* Doesn't autocommit - instead puts the changes into a separate changelist.
* In the case of merge conflict provides the Conflict Resolver dialog.
* @return true if all conflicts were resolved or there were no merge conflicts; false if unresolved files remain.
* @throws VcsException
*/
boolean cherryPick(GitCommit hash) throws VcsException;
void loadHashesWithParents(final @NotNull Collection<String> startingPoints, @NotNull final Collection<ChangesFilter.Filter> filters,
final AsynchConsumer<CommitHashPlusParents> consumer, Getter<Boolean> isCanceled, int useMaxCnt) throws VcsException;
List<GitCommit> getCommitDetails(final Collection<String> commitIds, SymbolicRefs refs) throws VcsException;
@@ -16,24 +16,37 @@
*/
package git4idea.history.browser;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Getter;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vcs.FilePathImpl;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.merge.MergeDialogCustomizer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.AsynchConsumer;
import git4idea.GitBranch;
import git4idea.GitTag;
import git4idea.commands.GitFileUtils;
import git4idea.GitVcs;
import git4idea.commands.GitCommand;
import git4idea.commands.GitLineHandler;
import git4idea.commands.GitLineHandlerAdapter;
import git4idea.config.GitConfigUtil;
import git4idea.history.GitHistoryUtils;
import git4idea.history.wholeTree.CommitHashPlusParents;
import git4idea.merge.GitMergeConflictResolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.event.HyperlinkEvent;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
public class LowLevelAccessImpl implements LowLevelAccess {
private final static Logger LOG = Logger.getInstance("#git4idea.history.browser.LowLevelAccessImpl");
@@ -181,7 +194,94 @@ public class LowLevelAccessImpl implements LowLevelAccess {
GitTag.listAsStrings(myProject, myRoot, sink, null);
}
public void cherryPick(SHAHash hash) throws VcsException {
GitFileUtils.cherryPick(myProject, myRoot, hash.getValue());
public boolean cherryPick(GitCommit commit) throws VcsException {
final GitLineHandler handler = new GitLineHandler(myProject, myRoot, GitCommand.CHERRY_PICK);
handler.addParameters("-x", "-n", commit.getHash().getValue());
handler.endOptions();
handler.setNoSSH(true);
final AtomicBoolean conflict = new AtomicBoolean();
handler.addLineListener(new GitLineHandlerAdapter() {
public void onLineAvailable(String line, Key outputType) {
if (line.contains("after resolving the conflicts, mark the corrected paths")) {
conflict.set(true);
}
}
});
handler.runInCurrentThread(null);
if (conflict.get()) {
boolean allConflictsResolved = new CherryPickConflictResolver(myProject, commit.getShortHash().getString(), commit.getAuthor(), commit.getSubject()).merge(Collections.singleton(myRoot));
return allConflictsResolved;
} else {
final List<VcsException> errors = handler.errors();
if (!errors.isEmpty()) {
throw errors.get(0);
} else { // no conflicts, no errors
return true;
}
}
}
private static class CherryPickConflictResolver extends GitMergeConflictResolver {
private String myCommitHash;
private String myCommitAuthor;
private String myCommitMessage;
public CherryPickConflictResolver(Project project, String commitHash, String commitAuthor, String commitMessage) {
super(project, false, new CherryPickMergeDialogCustomizer(commitHash, commitAuthor, commitMessage), "Cherry-picked with conflicts", "");
myCommitHash = commitHash;
myCommitAuthor = commitAuthor;
myCommitMessage = commitMessage;
}
@Override
protected void notifyUnresolvedRemain(final Collection<VirtualFile> roots) {
Notifications.Bus.notify(new Notification(GitVcs.IMPORTANT_ERROR_NOTIFICATION, "Conflicts were not resolved during cherry-pick",
"Cherry-pick is not complete, you have unresolved merges in your working tree<br/>" +
"<a href='resolve'>Resolve</a> conflicts.",
NotificationType.WARNING, new NotificationListener() {
@Override
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
if (event.getDescription().equals("resolve")) {
new CherryPickConflictResolver(myProject, myCommitHash, myCommitAuthor, myCommitMessage).justMerge(roots);
}
}
}
}));
}
}
private static class CherryPickMergeDialogCustomizer extends MergeDialogCustomizer {
private String myCommitHash;
private String myCommitAuthor;
private String myCommitMessage;
public CherryPickMergeDialogCustomizer(String commitHash, String commitAuthor, String commitMessage) {
myCommitHash = commitHash;
myCommitAuthor = commitAuthor;
myCommitMessage = commitMessage;
}
@Override
public String getMultipleFileMergeDescription(Collection<VirtualFile> files) {
return "<html>Conflicts during cherry-picking commit <code>" + myCommitHash + "</code> made by " + myCommitAuthor + "<br/>" +
"<code>\"" + myCommitMessage + "\"</code></html>";
}
@Override
public String getLeftPanelTitle(VirtualFile file) {
return "Local changes";
}
@Override
public String getRightPanelTitle(VirtualFile file, VcsRevisionNumber lastRevisionNumber) {
return "<html>Changes from cherry-pick <code>" + myCommitHash + "</code>";
}
}
}
@@ -194,7 +194,7 @@ public class DetailsLoaderImpl implements DetailsLoader {
private GitCommit createNotLoadedCommit(AbstractHash shortHash) {
final String notKnown = "Can not load";
return new GitCommit(shortHash, SHAHash.emulate(shortHash), notKnown, notKnown, new Date(0),
return new GitCommit(shortHash, SHAHash.emulate(shortHash), notKnown, notKnown, new Date(0), notKnown,
"Can not load details", Collections.<String>emptySet(), Collections.<FilePath>emptyList(), notKnown,
notKnown, Collections.<String>emptyList(), Collections.<String>emptyList(), Collections.<String>emptyList(),
Collections.<Change>emptyList(), 0);
@@ -42,7 +42,7 @@ import java.util.Collection;
public class GitMergeConflictResolver {
private static final Logger LOG = Logger.getInstance(GitMergeConflictResolver.class);
private final @NotNull Project myProject;
protected final @NotNull Project myProject;
private final boolean myReverseMerge;
private final @NotNull String myErrorNotificationTitle;
private final @NotNull String myErrorNotificationAdditionalDescription;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package git4idea.update;
package git4idea.stash;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package git4idea.update;
package git4idea.stash;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
@@ -62,7 +62,7 @@ public class GitShelveChangesSaver extends GitChangesSaver {
String oldProgressTitle = myProgressIndicator.getText();
myProgressIndicator.setText(GitBundle.getString("update.shelving.changes"));
List<VcsException> exceptions = new ArrayList<VcsException>(1);
myShelvedChangeList = GitStashUtils.shelveChanges(myProject, myShelveManager, changes, myStashMessage, exceptions);
myShelvedChangeList = GitShelveUtils.shelveChanges(myProject, myShelveManager, changes, myStashMessage, exceptions);
myProgressIndicator.setText(oldProgressTitle);
if (!exceptions.isEmpty()) {
LOG.info("save " + exceptions, exceptions.get(0));
@@ -77,7 +77,7 @@ public class GitShelveChangesSaver extends GitChangesSaver {
String oldProgressTitle = myProgressIndicator.getText();
myProgressIndicator.setText(GitBundle.getString("update.unshelving.changes"));
if (myShelvedChangeList != null) {
GitStashUtils.doSystemUnshelve(myProject, myShelvedChangeList, myShelveManager, restoreListsRunnable, context);
GitShelveUtils.doSystemUnshelve(myProject, myShelvedChangeList, myShelveManager, restoreListsRunnable, context);
}
myProgressIndicator.setText(oldProgressTitle);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2011 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.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package git4idea.update;
package git4idea.stash;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
@@ -33,21 +33,13 @@ import com.intellij.openapi.vcs.changes.shelf.ShelvedChange;
import com.intellij.openapi.vcs.changes.shelf.ShelvedChangeList;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import com.intellij.util.continuation.ContinuationContext;
import com.intellij.util.continuation.TaskDescriptor;
import com.intellij.util.continuation.Where;
import com.intellij.vcsUtil.VcsUtil;
import git4idea.GitUtil;
import git4idea.GitVcs;
import git4idea.commands.GitCommand;
import git4idea.commands.GitFileUtils;
import git4idea.commands.GitSimpleHandler;
import git4idea.commands.StringScanner;
import git4idea.config.GitConfigUtil;
import git4idea.config.GitVersion;
import git4idea.ui.GitUIUtil;
import git4idea.ui.StashInfo;
import git4idea.vfs.GitVFSListener;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -55,61 +47,13 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.event.ChangeEvent;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.*;
/**
* The class contains utilities for creating and removing stashes.
* @author Kirill Likhodedov
*/
public class GitStashUtils {
/**
* The version when quiet stash supported
*/
private final static GitVersion QUIET_STASH_SUPPORTED = new GitVersion(1, 6, 4, 0);
private static final Logger LOG = Logger.getInstance(GitStashUtils.class.getName());
private GitStashUtils() {
}
/**
* Create stash for later use
*
* @param project the project to use
* @param root the root
* @param message the message for the stash
* @return true if the stash was created, false otherwise
*/
public static boolean saveStash(@NotNull Project project, @NotNull VirtualFile root, final String message) throws VcsException {
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.STASH);
handler.setNoSSH(true);
handler.addParameters("save", message);
String output = handler.run();
return !output.startsWith("No local changes to save");
}
public static void loadStashStack(@NotNull Project project, @NotNull VirtualFile root, Consumer<StashInfo> consumer) {
loadStashStack(project, root, Charset.forName(GitConfigUtil.getLogEncoding(project, root)), consumer);
}
public static void loadStashStack(@NotNull Project project, @NotNull VirtualFile root, final Charset charset,
final Consumer<StashInfo> consumer) {
GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.STASH);
h.setSilent(true);
h.setNoSSH(true);
h.addParameters("list");
String out;
try {
h.setCharset(charset);
out = h.run();
}
catch (VcsException e) {
GitUIUtil.showOperationError(project, e, h.printableCommandLine());
return;
}
for (StringScanner s = new StringScanner(out); s.hasMoreData();) {
consumer.consume(new StashInfo(s.boundedToken(':'), s.boundedToken(':'), s.line().trim()));
}
}
public class GitShelveUtils {
private static final Logger LOG = Logger.getInstance(GitShelveUtils.class.getName());
/**
* Perform system level unshelve operation
@@ -165,9 +109,9 @@ public class GitStashUtils {
});
}
private static void addFilesAfterUnshelve(Project project,
ShelvedChangeList shelvedChangeList,
String projectPath, ContinuationContext context) {
public static void addFilesAfterUnshelve(Project project,
ShelvedChangeList shelvedChangeList,
String projectPath, ContinuationContext context) {
Collection<FilePath> paths = new ArrayList<FilePath>();
for (ShelvedChange c : shelvedChangeList.getChanges()) {
if (c.getBeforePath() == null || !c.getBeforePath().equals(c.getAfterPath()) || c.getFileStatus() == FileStatus.ADDED) {
@@ -195,7 +139,7 @@ public class GitStashUtils {
}
}
private static void refreshFilesBeforeUnshelve(ShelvedChangeList shelvedChangeList, String projectPath) {
public static void refreshFilesBeforeUnshelve(ShelvedChangeList shelvedChangeList, String projectPath) {
HashSet<File> filesToRefresh = new HashSet<File>();
for (ShelvedChange c : shelvedChangeList.getChanges()) {
if (c.getBeforePath() != null) {
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package git4idea.update;
package git4idea.stash;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
@@ -176,7 +176,7 @@ public class GitStashChangesSaver extends GitChangesSaver {
boolean conflictsResolved = new UnstashConflictResolver().merge(Collections.singleton(root));
if (conflictsResolved) {
LOG.info("loadRoot " + root + " conflicts resolved, dropping stash");
dropStash(root);
GitStashUtils.dropStash(myProject, root);
}
} else {
LOG.info("unstash failed " + handler.errors());
@@ -185,22 +185,6 @@ public class GitStashChangesSaver extends GitChangesSaver {
}
}
// drops stash (after completing conflicting merge during unstashing), shows a warning in case of error
private void dropStash(VirtualFile root) {
final GitSimpleHandler handler = new GitSimpleHandler(myProject, root, GitCommand.STASH);
handler.setNoSSH(true);
handler.addParameters("drop");
String output = null;
try {
output = handler.run();
} catch (VcsException e) {
LOG.info("dropStash " + output, e);
GitUIUtil.notifyMessage(myProject, "Couldn't drop stash",
"Couldn't drop stash after resolving conflicts.<br/>Please drop stash manually.",
WARNING, false, handler.errors());
}
}
// Sort changes from myChangesLists by their git roots.
// And use only supplied roots, ignoring changes from other roots.
private Map<VirtualFile, Collection<Change>> groupChangesByRoots(Collection<VirtualFile> rootsToSave) {
@@ -0,0 +1,101 @@
/*
* Copyright 2000-2009 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 git4idea.stash;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import git4idea.commands.GitCommand;
import git4idea.commands.GitSimpleHandler;
import git4idea.commands.StringScanner;
import git4idea.config.GitConfigUtil;
import git4idea.ui.GitUIUtil;
import git4idea.ui.StashInfo;
import org.jetbrains.annotations.NotNull;
import java.nio.charset.Charset;
import static com.intellij.notification.NotificationType.WARNING;
/**
* The class contains utilities for creating and removing stashes.
*/
public class GitStashUtils {
private static final Logger LOG = Logger.getInstance(GitStashUtils.class);
private GitStashUtils() {
}
/**
* Create stash for later use
*
* @param project the project to use
* @param root the root
* @param message the message for the stash
* @return true if the stash was created, false otherwise
*/
public static boolean saveStash(@NotNull Project project, @NotNull VirtualFile root, final String message) throws VcsException {
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.STASH);
handler.setNoSSH(true);
handler.addParameters("save", message);
String output = handler.run();
return !output.startsWith("No local changes to save");
}
public static void loadStashStack(@NotNull Project project, @NotNull VirtualFile root, Consumer<StashInfo> consumer) {
loadStashStack(project, root, Charset.forName(GitConfigUtil.getLogEncoding(project, root)), consumer);
}
public static void loadStashStack(@NotNull Project project, @NotNull VirtualFile root, final Charset charset,
final Consumer<StashInfo> consumer) {
GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.STASH);
h.setSilent(true);
h.setNoSSH(true);
h.addParameters("list");
String out;
try {
h.setCharset(charset);
out = h.run();
}
catch (VcsException e) {
GitUIUtil.showOperationError(project, e, h.printableCommandLine());
return;
}
for (StringScanner s = new StringScanner(out); s.hasMoreData();) {
consumer.consume(new StashInfo(s.boundedToken(':'), s.boundedToken(':'), s.line().trim()));
}
}
// drops stash (after completing conflicting merge during unstashing), shows a warning in case of error
public static void dropStash(Project project, VirtualFile root) {
final GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.STASH);
handler.setNoSSH(true);
handler.addParameters("drop");
String output = null;
try {
output = handler.run();
} catch (VcsException e) {
LOG.info("dropStash " + output, e);
GitUIUtil.notifyMessage(project, "Couldn't drop stash",
"Couldn't drop stash after resolving conflicts.<br/>Please drop stash manually.",
WARNING, false, handler.errors());
}
}
}
@@ -15,6 +15,11 @@
*/
package git4idea.ui;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
@@ -23,6 +28,8 @@ import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.merge.MergeDialogCustomizer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.DocumentAdapter;
import com.intellij.util.Consumer;
@@ -33,19 +40,19 @@ import git4idea.actions.GitShowAllSubmittedFilesAction;
import git4idea.commands.*;
import git4idea.config.GitVersionSpecialty;
import git4idea.i18n.GitBundle;
import git4idea.update.GitStashUtils;
import git4idea.merge.GitMergeConflictResolver;
import git4idea.stash.GitStashUtils;
import git4idea.validators.GitBranchNameValidator;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -102,6 +109,7 @@ public class GitUnstashDialog extends DialogWrapper {
*/
private final Project myProject;
private GitVcs myVcs;
private static final Logger LOG = Logger.getInstance(GitUnstashDialog.class);
/**
* A constructor
@@ -406,10 +414,14 @@ public class GitUnstashDialog extends DialogWrapper {
affectedRoots.add(d.getGitRoot());
GitLineHandler h = d.handler(false);
final AtomicBoolean needToEscapedBraces = new AtomicBoolean(false);
final AtomicBoolean conflict = new AtomicBoolean();
h.addLineListener(new GitLineHandlerAdapter() {
public void onLineAvailable(String line, Key outputType) {
if (line.startsWith("fatal: Needed a single revision")) {
needToEscapedBraces.set(true);
} else if (line.contains("Merge conflict")) {
conflict.set(true);
}
}
});
@@ -418,8 +430,66 @@ public class GitUnstashDialog extends DialogWrapper {
h = d.handler(true);
rc = GitHandlerUtil.doSynchronously(h, GitBundle.getString("unstash.unstashing"), h.printableCommandLine(), false);
}
if (rc != 0) {
if (conflict.get()) {
VirtualFile root = d.getGitRoot();
boolean conflictsResolved = new UnstashConflictResolver(project, d.getSelectedStash()).merge(Collections.singleton(root));
if (conflictsResolved) {
LOG.info("loadRoot " + root + " conflicts resolved, dropping stash");
GitStashUtils.dropStash(project, root);
}
} else if (rc != 0) {
GitUIUtil.showOperationErrors(project, h.errors(), h.printableCommandLine());
}
}
private static class UnstashConflictResolver extends GitMergeConflictResolver {
private StashInfo myStashInfo;
public UnstashConflictResolver(Project project, StashInfo stashInfo) {
super(project, false, new UnstashMergeDialogCustomizer(stashInfo), "Unstashed with conflicts", "");
myStashInfo = stashInfo;
}
@Override
protected void notifyUnresolvedRemain(final Collection<VirtualFile> roots) {
Notifications.Bus.notify(new Notification(GitVcs.IMPORTANT_ERROR_NOTIFICATION, "Conflicts were not resolved during unstash",
"Unstash is not complete, you have unresolved merges in your working tree<br/>" +
"<a href='resolve'>Resolve</a> conflicts.",
NotificationType.WARNING, new NotificationListener() {
@Override
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
if (event.getDescription().equals("resolve")) {
new UnstashConflictResolver(myProject, myStashInfo).justMerge(roots);
}
}
}
}));
}
}
private static class UnstashMergeDialogCustomizer extends MergeDialogCustomizer {
private final StashInfo myStashInfo;
public UnstashMergeDialogCustomizer(StashInfo stashInfo) {
myStashInfo = stashInfo;
}
@Override
public String getMultipleFileMergeDescription(Collection<VirtualFile> files) {
return "<html>Conflicts during unstashing <code>" + myStashInfo.getStash() + "\"" + myStashInfo.getMessage() + "\"</code></html>";
}
@Override
public String getLeftPanelTitle(VirtualFile file) {
return "Local changes";
}
@Override
public String getRightPanelTitle(VirtualFile file, VcsRevisionNumber lastRevisionNumber) {
return "Changes from stash";
}
}
}
@@ -35,6 +35,7 @@ import git4idea.merge.GitMergeConflictResolver;
import git4idea.merge.GitMergeUtil;
import git4idea.merge.GitMerger;
import git4idea.rebase.GitRebaser;
import git4idea.stash.GitChangesSaver;
import git4idea.ui.GitUIUtil;
import org.jetbrains.annotations.NotNull;
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.groovy.findUsages;
import com.intellij.openapi.application.QueryExecutorBase;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.*;
import com.intellij.psi.search.searches.ReferencesSearch;
@@ -42,7 +43,7 @@ public class GrAliasedImportedElementSearcher extends QueryExecutorBase<PsiRefer
if (!(target instanceof PsiMember) || !(target instanceof PsiNamedElement)) return;
final String name = ((PsiNamedElement)target).getName();
if (name == null) return;
if (name == null || StringUtil.isEmptyOrSpaces(name)) return;
final SearchScope onlyGroovy = PsiUtil.restrictScopeToGroovyFiles(parameters.getEffectiveSearchScope());
@@ -491,14 +491,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
PsiClass containingClass = method.getContainingClass();
if (containingClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName()) &&
"getClass".equals(method.getName())) {
final GrExpression qualifier = getQualifier();
if (PsiUtil.seemsToBeQualifiedClassName(qualifier)) {
result = TypesUtil.createJavaLangClassType(facade.getElementFactory().createTypeFromText(qualifier.getText(), this),
getProject(), getResolveScope());
}
else {
result = getTypeForObjectGetClass(method);
}
result = TypesUtil.createJavaLangClassType(getQualifierType(), getProject(), getResolveScope());
} else {
result = PsiUtil.getSmartReturnType(method);
}
@@ -520,13 +513,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
else if (resolved == null) {
GrExpression qualifier = getQualifierExpression();
if ("class".equals(getReferenceName())) {
if (PsiUtil.seemsToBeQualifiedClassName(qualifier)) {
assert qualifier != null;
result = TypesUtil.createJavaLangClassType(facade.getElementFactory().createTypeFromText(qualifier.getText(), this), getProject(),
getResolveScope());
} else {
result = TypesUtil.createJavaLangClassType(getQualifierType(), getProject(), getResolveScope());
}
result = TypesUtil.createJavaLangClassType(getQualifierType(), getProject(), getResolveScope());
}
else {
if (qualifier != null) {
@@ -577,21 +564,6 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
}
}
@Nullable
private PsiType getTypeForObjectGetClass(PsiMethod method) {
PsiType type = PsiUtil.getSmartReturnType(method);
if (type instanceof PsiClassType) {
PsiClass clazz = ((PsiClassType)type).resolve();
if (clazz != null && CommonClassNames.JAVA_LANG_CLASS.equals(clazz.getQualifiedName())) {
PsiTypeParameter[] typeParameters = clazz.getTypeParameters();
if (typeParameters.length == 1) {
return TypesUtil.createJavaLangClassType(getQualifierType(), getProject(), getResolveScope());
}
}
}
return type;
}
private static final class OurTypesCalculator implements Function<GrReferenceExpressionImpl, PsiType> {
@Nullable
public PsiType fun(GrReferenceExpressionImpl refExpr) {
@@ -1128,7 +1128,7 @@ public class PsiUtil {
return ((GrListOrMap)firstArg).getNamedArguments();
}
public static boolean seemsToBeQualifiedClassName(@Nullable GrExpression qualifier) {
private static boolean seemsToBeQualifiedClassName(@Nullable GrExpression qualifier) {
if (qualifier == null) return false;
while (qualifier instanceof GrReferenceExpression) {
final PsiElement nameElement = ((GrReferenceExpression)qualifier).getReferenceNameElement();