diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java index 800db37461d2..fb8437096563 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java @@ -504,28 +504,29 @@ public class JavaCompletionUtil { } if (plainQualifier != null) { Object o = item.getObject(); - if (containsMember(plainQualifier, o)) { - if (!(o instanceof PsiMethod)) { - return item; - } + if (o instanceof PsiMethod) { PsiType castType = castTypeItem.getPsiType(); if (plainQualifier instanceof PsiClassType && castType instanceof PsiClassType) { PsiMethod method = (PsiMethod)o; PsiClassType.ClassResolveResult plainResult = ((PsiClassType)plainQualifier).resolveGenerics(); PsiClass plainClass = plainResult.getElement(); - PsiClass castClass = ((PsiClassType)castType).resolveGenerics().getElement(); + if (plainClass != null && plainClass.findMethodBySignature(method, true) != null) { + PsiClass castClass = ((PsiClassType)castType).resolveGenerics().getElement(); - if (castClass == null || plainClass == null || !castClass.isInheritor(plainClass, true)) { - return item; - } + if (castClass == null || !castClass.isInheritor(plainClass, true)) { + return item; + } - PsiSubstitutor plainSub = plainResult.getSubstitutor(); - PsiSubstitutor castSub = TypeConversionUtil.getSuperClassSubstitutor(plainClass, (PsiClassType)castType); - if (method.getSignature(plainSub).equals(method.getSignature(castSub)) && - plainSub.substitute(method.getReturnType()).equals(castSub.substitute(method.getReturnType()))) { - return item; + PsiSubstitutor plainSub = plainResult.getSubstitutor(); + PsiSubstitutor castSub = TypeConversionUtil.getSuperClassSubstitutor(plainClass, (PsiClassType)castType); + if (method.getSignature(plainSub).equals(method.getSignature(castSub)) && + plainSub.substitute(method.getReturnType()).equals(castSub.substitute(method.getReturnType()))) { + return item; + } } } + } else if (containsMember(plainQualifier, o)) { + return item; } } diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index 3e0381d52e60..e99d06cbf2ad 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -16,6 +16,7 @@ package com.intellij.codeInspection.dataFlow; import com.intellij.codeInsight.ExceptionUtil; +import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.codeInspection.dataFlow.instructions.*; import com.intellij.codeInspection.dataFlow.value.DfaUnknownValue; import com.intellij.codeInspection.dataFlow.value.DfaValue; @@ -1431,6 +1432,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { startElement(expression); DfaValue dfaValue = myFactory.create(expression); + PsiElement resolved = expression.resolve(); if (dfaValue instanceof DfaVariableValue) { DfaVariableValue dfaVariable = (DfaVariableValue)dfaValue; PsiVariable psiVariable = dfaVariable.getPsiVariable(); @@ -1442,7 +1444,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { final PsiExpression qualifierExpression = expression.getQualifierExpression(); if (qualifierExpression != null) { qualifierExpression.accept(this); - if (expression.resolve() instanceof PsiField) { + if (resolved instanceof PsiField) { addInstruction(new FieldReferenceInstruction(expression, null)); } else { @@ -1450,6 +1452,12 @@ class ControlFlowAnalyzer extends JavaElementVisitor { } } + if (dfaValue == null && resolved instanceof PsiField) { + // Accessing a field from another instance + dfaValue = myFactory.getTypeFactory().create(((PsiField)resolved).getType(), + NullableNotNullManager.isNullable((PsiModifierListOwner)resolved)); + } + addInstruction(new PushInstruction(dfaValue, expression)); finishElement(expression); diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java index 5ce2fbd6c1f5..ee177909adad 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java @@ -123,7 +123,11 @@ public class StandardInstructionVisitor extends InstructionVisitor { final DfaValue qualifier = memState.pop(); if (instruction.getExpression().isPhysical() && !memState.applyNotNull(qualifier)) { onInstructionProducesNPE(instruction, runner); - return DfaInstructionState.EMPTY_ARRAY; + + if (qualifier instanceof DfaVariableValue) { + final DfaNotNullValue.Factory factory = runner.getFactory().getNotNullFactory(); + memState.setVarValue((DfaVariableValue)qualifier, factory.create(((DfaVariableValue)qualifier).getPsiVariable().getType())); + } } return nextInstruction(instruction, runner, memState); diff --git a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java index 32f5489fa54a..e5bd42743749 100644 --- a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java @@ -45,6 +45,7 @@ import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.VisibilityUtil; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -156,6 +157,14 @@ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefacto builderClass.add(method); } + //fix visibilities + final PsiMethod constructor = getWorkingConstructor(); + VisibilityUtil.escalateVisibility(constructor, builderClass); + PsiClass containingClass = constructor.getContainingClass(); + while (containingClass != null) { + VisibilityUtil.escalateVisibility(containingClass, builderClass); + containingClass = containingClass.getContainingClass(); + } } private void createSetter(PsiClass builderClass, ParameterData parameterData, PsiField field) { @@ -221,13 +230,7 @@ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefacto private PsiMethod createMethodSignature(String createMethodName) { JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(myProject); final StringBuffer buf = new StringBuffer(); - PsiMethod constructor = getMostCommonConstructor(); - if (constructor == null){ - constructor = myConstructors[0]; - if (constructor.getParameterList().getParametersCount() == 0) { - constructor = myConstructors[1]; - } - } + final PsiMethod constructor = getWorkingConstructor(); for (PsiParameter parameter : constructor.getParameterList().getParameters()) { final String pureParamName = styleManager.variableNameToPropertyName(parameter.getName(), VariableKind.PARAMETER); if (buf.length() > 0) buf.append(", "); @@ -245,6 +248,17 @@ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefacto ";\n}", constructor); } + private PsiMethod getWorkingConstructor() { + PsiMethod constructor = getMostCommonConstructor(); + if (constructor == null){ + constructor = myConstructors[0]; + if (constructor.getParameterList().getParametersCount() == 0) { + constructor = myConstructors[1]; + } + } + return constructor; + } + @Nullable private PsiMethod getMostCommonConstructor() { if (myConstructors.length == 1) return myConstructors[0]; diff --git a/java/java-tests/testData/codeInsight/completion/normal/InterfaceImplementationNoCast.java b/java/java-tests/testData/codeInsight/completion/normal/InterfaceImplementationNoCast.java new file mode 100644 index 000000000000..5f342695a4fe --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/InterfaceImplementationNoCast.java @@ -0,0 +1,18 @@ +public class Util2 { + void foo(XmlAttribute o ) { + if (o instanceof XmlAttributeImpl) { + o.getpar + } + } +} + +interface PsiElement { + PsiElement getParent(); +} +interface XmlAttribute extends PsiElement {} +class XmlAttributeImpl implements XmlAttribute { + @Override + public PsiElement getParent() { + return null; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/InterfaceImplementationNoCast_after.java b/java/java-tests/testData/codeInsight/completion/normal/InterfaceImplementationNoCast_after.java new file mode 100644 index 000000000000..94718eeb8f2e --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/InterfaceImplementationNoCast_after.java @@ -0,0 +1,18 @@ +public class Util2 { + void foo(XmlAttribute o ) { + if (o instanceof XmlAttributeImpl) { + o.getParent() + } + } +} + +interface PsiElement { + PsiElement getParent(); +} +interface XmlAttribute extends PsiElement {} +class XmlAttributeImpl implements XmlAttribute { + @Override + public PsiElement getParent() { + return null; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/CanBeNullDoesntImplyIsNull.java b/java/java-tests/testData/inspection/dataFlow/fixture/CanBeNullDoesntImplyIsNull.java new file mode 100644 index 000000000000..56f577112808 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/CanBeNullDoesntImplyIsNull.java @@ -0,0 +1,14 @@ +import org.jetbrains.annotations.Nullable; + +public class DDD { + int test(boolean t) { + if (t && fff().length == 1) { + return 0; + } + return 1; + } + + public @Nullable DDD[] fff() { + return new DDD[8]; + } +} diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/NullableField.java b/java/java-tests/testData/inspection/dataFlow/fixture/NullableField.java new file mode 100644 index 000000000000..0a341d37e4e9 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/NullableField.java @@ -0,0 +1,9 @@ +import org.jetbrains.annotations.Nullable; + +public class DDD { + @Nullable + String field; + int test() { + return new DDD().field.hashCode(); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy index 49f4a214442c..772881af6d50 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy @@ -1325,5 +1325,6 @@ public class ListUtils { } public void testListArrayListCast() { doTest('\n') } + public void testInterfaceImplementationNoCast() { doTest() } } diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java index af8d11f9b962..9b6bd4cf2ce7 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java @@ -33,5 +33,6 @@ public class DataFlowInspectionFixtureTest extends JavaCodeInsightFixtureTestCas public void testNullableAnonymousVolatileNotNull() throws Throwable { doTest(); } public void testFieldInAnonymous() throws Throwable { doTest(); } - + public void testNullableField() throws Throwable { doTest(); } + public void testCanBeNullDoesntImplyIsNull() throws Throwable { doTest(); } } diff --git a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java index 5a9529260e5b..46b0b86a675c 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java +++ b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,6 +39,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.*; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.psi.PsiDocumentManager; @@ -49,6 +50,7 @@ import com.intellij.ui.popup.AbstractPopup; import com.intellij.ui.popup.PopupUpdateProcessor; import com.intellij.ui.speedSearch.ElementFilter; import com.intellij.ui.speedSearch.SpeedSearchUtil; +import com.intellij.ui.treeStructure.AlwaysExpandedTree; import com.intellij.ui.treeStructure.Tree; import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder; import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure; @@ -76,6 +78,7 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.lang.reflect.Field; import java.util.*; import java.util.List; @@ -101,7 +104,7 @@ public class FileStructurePopup implements Disposable { @NonNls private static final String narrowDownPropertyKey = "FileStructurePopup.narrowDown"; private boolean myShouldNarrowDown = true; - private Tree myTree; + private FileStructureTree myTree; private FilteringTreeBuilder myAbstractTreeBuilder; private String myTitle; private TreeSpeedSearch mySpeedSearch; @@ -154,13 +157,9 @@ public class FileStructurePopup implements Disposable { return "structure view tree structure(model=" + myTreeModel + ")"; } }; - myTree = new JBTreeWithHintProvider(new DefaultMutableTreeNode(myTreeStructure.getRootElement())) { - @Override - protected PsiElement getPsiElementForHint(Object selectedValue) { - //noinspection ConstantConditions - return getPsi((FilteringTreeStructure.FilteringNode)((DefaultMutableTreeNode)selectedValue).getUserObject()); - } - }; + + myTree = new FileStructureTree(myTreeStructure.getRootElement(), Registry.is("fast.tree.expand.in.structure.view")); + myTree.setCellRenderer(new NodeRenderer() { @Override protected void doAppend(@NotNull @Nls String fragment, @@ -180,8 +179,6 @@ public class FileStructurePopup implements Disposable { SpeedSearchUtil.appendFragmentsForSpeedSearch(myTree, fragment, SimpleTextAttributes.REGULAR_ATTRIBUTES, selected, this); } }); - myTree.setRootVisible(false); - myTree.setShowsRootHandles(true); mySpeedSearch = new MyTreeSpeedSearch(); mySpeedSearch.setComparator(new SpeedSearchComparator(false, true)); @@ -271,7 +268,7 @@ public class FileStructurePopup implements Disposable { } //final long cur = System.currentTimeMillis(); - myAbstractTreeBuilder.expandAll(new Runnable() { + final Runnable expandIsDone = new Runnable() { @Override public void run() { //System.out.println(System.currentTimeMillis() - cur); @@ -286,7 +283,14 @@ public class FileStructurePopup implements Disposable { } }); } - }); + }; + + //if (myTree.isAlwaysExpanded() || true) { + expandIsDone.run(); + //} else { + // myAbstractTreeBuilder.expandAll(expandIsDone); + //} + if (!ApplicationManager.getApplication().isUnitTestMode()) { final Alarm alarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, myPopup); alarm.addRequest(new Runnable() { @@ -903,4 +907,59 @@ public class FileStructurePopup implements Disposable { } } + + class FileStructureTree extends JBTreeWithHintProvider implements AlwaysExpandedTree { + private final boolean fast; + + public FileStructureTree(Object rootElement, boolean fastExpand) { + super(new DefaultMutableTreeNode(rootElement)); + if (fastExpand) { + boolean newValueIsSet; + try { + final Field field = JTree.class.getDeclaredField("expandedState"); + field.setAccessible(true); + field.set(this, new Hashtable() { + @Override + public synchronized Object get(Object key) { + return Boolean.TRUE; + } + }); + newValueIsSet = true; + } + catch (Exception e) { + newValueIsSet = false; + } + fast = newValueIsSet; + } else { + fast = false; + } + + //TODO[kb]: hack expanded states in getUI().treeState + + setRootVisible(false); + setShowsRootHandles(true); + setHorizontalAutoScrollingEnabled(false); + } + + @Override + public boolean isAlwaysExpanded() { + return fast; + } + + @Override + public boolean isExpanded(TreePath path) { + return fast || super.isExpanded(path); + } + + @Override + public boolean isExpanded(int row) { + return fast || super.isExpanded(row); + } + + @Override + protected PsiElement getPsiElementForHint(Object selectedValue) { + //noinspection ConstantConditions + return getPsi((FilteringTreeStructure.FilteringNode)((DefaultMutableTreeNode)selectedValue).getUserObject()); + } + } } diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java index 36eb0ce043ca..55269e50ea8b 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java @@ -27,6 +27,7 @@ import com.intellij.openapi.util.*; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.registry.RegistryValue; import com.intellij.ui.LoadingNode; +import com.intellij.ui.treeStructure.AlwaysExpandedTree; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.Alarm; import com.intellij.util.ArrayUtil; @@ -751,7 +752,7 @@ public class AbstractTreeUi { } private boolean isAutoExpand(NodeDescriptor descriptor, boolean validate) { - if (descriptor == null) return false; + if (descriptor == null || isAlwaysExpandedTree()) return false; boolean autoExpand = getBuilder().isAutoExpandNode(descriptor); @@ -821,6 +822,10 @@ public class AbstractTreeUi { return isAutoExpand(getDescriptorFrom(node)); } + private boolean isAlwaysExpandedTree() { + return myTree instanceof AlwaysExpandedTree && ((AlwaysExpandedTree)myTree).isAlwaysExpanded(); + } + private AsyncResult update(final NodeDescriptor nodeDescriptor, boolean now) { final AsyncResult result = new AsyncResult(); diff --git a/platform/platform-api/src/com/intellij/openapi/components/PersistentStateComponent.java b/platform/platform-api/src/com/intellij/openapi/components/PersistentStateComponent.java index 8e2656131128..43d411c6ba1e 100644 --- a/platform/platform-api/src/com/intellij/openapi/components/PersistentStateComponent.java +++ b/platform/platform-api/src/com/intellij/openapi/components/PersistentStateComponent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -17,6 +17,7 @@ package com.intellij.openapi.components; import com.intellij.util.xmlb.XmlSerializer; +import org.jetbrains.annotations.Nullable; /** * Every component which would like to persist its state across IDEA restarts @@ -28,9 +29,11 @@ import com.intellij.util.xmlb.XmlSerializer; public interface PersistentStateComponent { /** * @return a component state. All properties and public fields are serialized. Only values, which differ - * from default (i.e. the value of newly instantiated class) are serialized. + * from default (i.e. the value of newly instantiated class) are serialized. null value indicates + * that no state should be stored * @see XmlSerializer */ + @Nullable T getState(); /** diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ComboBox.java b/platform/platform-api/src/com/intellij/openapi/ui/ComboBox.java index b84c801e1b21..d1e0120f5423 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/ComboBox.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/ComboBox.java @@ -76,7 +76,7 @@ public class ComboBox extends ComboBoxWithWidePopup implements AWTEventListener arrowButton.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { - if (!mySwingPopup) { + if (!isSwingPopup()) { e.consume(); setPopupVisible(true); } @@ -115,6 +115,9 @@ public class ComboBox extends ComboBoxWithWidePopup implements AWTEventListener } }); } + else if (!visible) { + super.setPopupVisible(visible); + } return; } diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/AlwaysExpandedTree.java b/platform/platform-api/src/com/intellij/ui/treeStructure/AlwaysExpandedTree.java new file mode 100644 index 000000000000..870cb8e999a7 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/treeStructure/AlwaysExpandedTree.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2012 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.ui.treeStructure; + +/** + * @author Konstantin Bulenkov + */ +public interface AlwaysExpandedTree { + boolean isAlwaysExpanded(); +} diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java index e4cc48f5e191..9b40cc59082a 100644 --- a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java +++ b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java @@ -57,6 +57,7 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith private Dimension myHoldSize; private final MySelectionModel mySelectionModel = new MySelectionModel(); + private boolean myHorizontalAutoScrolling = false; public Tree() { initTree_(); @@ -683,4 +684,12 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith return size; } + + public boolean isHorizontalAutoScrollingEnabled() { + return myHorizontalAutoScrolling; + } + + public void setHorizontalAutoScrollingEnabled(boolean enabled) { + myHorizontalAutoScrolling = enabled; + } } \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java b/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java index 8cc2d97de28b..3990fe048820 100644 --- a/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java +++ b/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.ListScrollingUtil; import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.awt.RelativePoint; +import com.intellij.ui.treeStructure.Tree; import com.intellij.util.Range; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -565,6 +566,10 @@ public final class TreeUtil { bounds.width = visible.width; } + if (tree instanceof Tree && !((Tree)tree).isHorizontalAutoScrollingEnabled()) { + bounds.x = 0; + } + final Rectangle b1 = bounds; final Runnable runnable = new Runnable() { public void run() { diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 659a40f86395..0720f81f856a 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -199,4 +199,5 @@ core.pooled.threads=20 editor.dumb.mode.available=true enable.animation.on.dialogs=false vcs.remote.management.ready=false -type.ahead.logging.enabled=false \ No newline at end of file +type.ahead.logging.enabled=false +fast.tree.expand.in.structure.view=false \ No newline at end of file diff --git a/platform/testFramework/src/com/intellij/testFramework/ParsingTestCase.java b/platform/testFramework/src/com/intellij/testFramework/ParsingTestCase.java index 81275c29dd81..72249ee72680 100644 --- a/platform/testFramework/src/com/intellij/testFramework/ParsingTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/ParsingTestCase.java @@ -61,6 +61,8 @@ import java.io.IOException; import java.util.Set; public abstract class ParsingTestCase extends PlatformLiteFixture { + protected static boolean OVERWRITE_TESTDATA = false; + protected String myFilePrefix = ""; protected String myFileExt; @NonNls protected final String myFullDataPath; @@ -270,21 +272,29 @@ public abstract class ParsingTestCase extends PlatformLiteFixture { } private static void doCheckResult(String myFullDataPath, String targetDataName, String text) throws IOException { + text = text.trim(); + String expectedFileName = myFullDataPath + File.separatorChar + targetDataName; + if (OVERWRITE_TESTDATA) { + writeFile(expectedFileName, text); + System.out.println("File " + expectedFileName + " created."); + } try { - text = text.trim(); String expectedText = doLoadFile(myFullDataPath, targetDataName); assertEquals(targetDataName, expectedText, text); } catch(FileNotFoundException e){ - String fullName = myFullDataPath + File.separatorChar + targetDataName; - FileWriter writer = new FileWriter(fullName); - try { - writer.write(text); - } - finally { - writer.close(); - } - fail("No output text found. File " + fullName + " created."); + writeFile(expectedFileName, text); + fail("No output text found. File " + expectedFileName + " created."); + } + } + + private static void writeFile(String fullName, String text) throws IOException { + FileWriter writer = new FileWriter(fullName); + try { + writer.write(text); + } + finally { + writer.close(); } } diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java index 028ed64d1b18..eee08caf705e 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java @@ -93,14 +93,19 @@ public abstract class VcsVFSListener implements Disposable { protected boolean isEventIgnored(final VirtualFileEvent event, boolean putInDirty) { if (event.isFromRefresh()) return true; - boolean vcsIgnored = myVcsManager.getVcsFor(event.getFile()) != myVcs || - (!myVcsManager.isFileInContent(event.getFile())) || myChangeListManager.isIgnoredFile(event.getFile()); + boolean vcsIgnored = !isUnderMyVcs(event.getFile()); if (vcsIgnored) { myDirtyFiles.add(event.getFile()); } return vcsIgnored; } + private boolean isUnderMyVcs(VirtualFile file) { + return myVcsManager.getVcsFor(file) == myVcs && + (myVcsManager.isFileInContent(file)) && + !myChangeListManager.isIgnoredFile(file); + } + protected void executeAdd() { final List addedFiles = acquireAddedFiles(); for (Iterator iterator = addedFiles.iterator(); iterator.hasNext(); ) { @@ -308,7 +313,10 @@ public abstract class VcsVFSListener implements Disposable { private class MyVirtualFileAdapter extends VirtualFileAdapter { public void fileCreated(final VirtualFileEvent event) { - VcsVFSListener.this.fileAdded(event, event.getFile()); + VirtualFile file = event.getFile(); + if (isUnderMyVcs(file)) { + VcsVFSListener.this.fileAdded(event, file); + } } public void fileCopied(final VirtualFileCopyEvent event) { @@ -385,8 +393,11 @@ public abstract class VcsVFSListener implements Disposable { @Override public void beforeContentsChange(VirtualFileEvent event) { - assert !event.getFile().isDirectory(); - VcsVFSListener.this.beforeContentsChange(event, event.getFile()); + VirtualFile file = event.getFile(); + assert !file.isDirectory(); + if (isUnderMyVcs(file)) { + VcsVFSListener.this.beforeContentsChange(event, file); + } } } diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml index b6a5ec5aa1e0..177380050a79 100644 --- a/plugins/gradle/src/META-INF/plugin.xml +++ b/plugins/gradle/src/META-INF/plugin.xml @@ -61,6 +61,7 @@ + diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleLibraryPresentationProvider.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleLibraryPresentationProvider.java index 5cd1ebef6282..4c5496bf566c 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleLibraryPresentationProvider.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleLibraryPresentationProvider.java @@ -32,6 +32,7 @@ import org.jetbrains.plugins.groovy.config.GroovyLibraryProperties; import javax.swing.*; import java.io.File; +import java.util.regex.Matcher; /** * @author nik @@ -114,11 +115,10 @@ public class GradleLibraryPresentationProvider extends GroovyLibraryPresentation @Nullable private static String getGradleJarVersion(VirtualFile file) { - // TODO den implement - //final Matcher matcher = GRADLE_JAR_FILE_PATTERN.matcher(file.getName()); - //if (matcher.matches()) { - // return matcher.group(2); - //} + final Matcher matcher = GradleLibraryManager.GRADLE_JAR_FILE_PATTERN.matcher(file.getName()); + if (matcher.matches()) { + return matcher.group(2); + } return null; } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleSettings.java index 2efdb62e35b8..68f23649e804 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleSettings.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleSettings.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.gradle.config; import com.intellij.openapi.components.*; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.xmlb.XmlSerializerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -57,6 +58,10 @@ public class GradleSettings implements PersistentStateComponent, @Override public GradleSettings getState() { + if (StringUtil.isEmpty(getLinkedProjectPath())) { + // Don't save state for the gradle-unaware projects. + return null; + } myExpandStates.get().clear(); if (PRESERVE_EXPAND_STATE) { myExpandStates.get().putAll(myWorkingExpandStates.get()); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java index 41c0725e5078..18d7dfe121b8 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java @@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.config.GradleGroovyEnabler; import org.jetbrains.plugins.gradle.config.GradleSettings; import org.jetbrains.plugins.gradle.model.gradle.*; +import org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesModel; import org.jetbrains.plugins.gradle.task.GradleResolveProjectTask; import org.jetbrains.plugins.gradle.util.GradleBundle; import org.jetbrains.plugins.gradle.util.GradleLog; @@ -318,6 +319,21 @@ public class GradleModulesImporter { finally { writeLock.finish(); } + final GradleSettings settings = GradleSettings.getInstance(intellijProject); + final String gradleHome = settings.getGradleHome(); + if (gradleHome != null) { + final GradleGroovyEnabler groovyEnabler = intellijProject.getComponent(GradleGroovyEnabler.class); + libraryToPreserve.set(groovyEnabler.setupGroovySdkIfNecessary(gradleHome)); + } + + // Force refresh the infrastructure in order to apply newly introduce intellij project structure changes + final GradleProjectStructureChangesModel changesModel = intellijProject.getComponent(GradleProjectStructureChangesModel.class); + if (changesModel != null) { + final GradleProject project = changesModel.getGradleProject(); + if (project != null) { + changesModel.update(project); + } + } } }; @@ -337,21 +353,8 @@ public class GradleModulesImporter { }); } }; - - Runnable setupGroovyTask = new Runnable() { - @Override - public void run() { - final GradleSettings settings = GradleSettings.getInstance(intellijProject); - final String gradleHome = settings.getGradleHome(); - if (gradleHome != null) { - final GradleGroovyEnabler groovyEnabler = intellijProject.getComponent(GradleGroovyEnabler.class); - libraryToPreserve.set(groovyEnabler.setupGroovySdkIfNecessary(gradleHome)); - } - resolveDependenciesTask.run(); - } - }; - - UIUtil.invokeLaterIfNeeded(setupGroovyTask); + + UIUtil.invokeLaterIfNeeded(resolveDependenciesTask); } private static void doSetupLibraries(@NotNull Map moduleMappings, diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java index fa12623f17ca..7b27347971c7 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java @@ -10,10 +10,12 @@ import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.projectRoots.JavaSdk; import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Ref; import com.intellij.packaging.artifacts.ModifiableArtifactModel; +import com.intellij.pom.java.LanguageLevel; import com.intellij.projectImport.ProjectImportBuilder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -23,6 +25,7 @@ import org.jetbrains.plugins.gradle.model.gradle.GradleModule; import org.jetbrains.plugins.gradle.model.gradle.GradleProject; import org.jetbrains.plugins.gradle.ui.GradleIcons; import org.jetbrains.plugins.gradle.util.GradleBundle; +import org.jetbrains.plugins.gradle.util.GradleConstants; import org.jetbrains.plugins.gradle.util.GradleUtil; import javax.swing.*; @@ -78,8 +81,16 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder commit(final Project project, ModifiableModuleModel model, ModulesProvider modulesProvider, - ModifiableArtifactModel artifactModel) - { + ModifiableArtifactModel artifactModel) { + System.setProperty(GradleConstants.NEWLY_IMPORTED_PROJECT, Boolean.TRUE.toString()); + final GradleProject gradleProject = getGradleProject(); + if (gradleProject != null) { + final LanguageLevel gradleLanguageLevel = gradleProject.getLanguageLevel(); + final LanguageLevelProjectExtension languageLevelExtension = LanguageLevelProjectExtension.getInstance(project); + if (gradleLanguageLevel != languageLevelExtension.getLanguageLevel()) { + languageLevelExtension.setLanguageLevel(gradleLanguageLevel); + } + } final Runnable task = new Runnable() { @Override public void run() { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleInitialProjectRefresher.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleInitialProjectRefresher.java index 7f0680d7b1f9..d1fd5d25b6b3 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleInitialProjectRefresher.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleInitialProjectRefresher.java @@ -3,6 +3,7 @@ package org.jetbrains.plugins.gradle.sync; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupActivity; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.gradle.util.GradleConstants; import org.jetbrains.plugins.gradle.util.GradleUtil; /** @@ -14,8 +15,11 @@ import org.jetbrains.plugins.gradle.util.GradleUtil; * @since 3/13/12 12:01 PM */ public class GradleInitialProjectRefresher implements StartupActivity { + @SuppressWarnings("UseOfArchaicSystemPropertyAccessors") @Override public void runActivity(@NotNull Project project) { - GradleUtil.refreshProject(project); + if (!Boolean.getBoolean(GradleConstants.NEWLY_IMPORTED_PROJECT)) { + GradleUtil.refreshProject(project); + } } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java index fbb2edcd5409..f42a25f92389 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java @@ -73,6 +73,7 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel { private Object myNodeUnderMouse; private Object myNodeWithActiveToolbar; private Balloon myToolbar; + private JComponent myToolbarComponent; private boolean mySuppressToolbar; private boolean mySuppressCollapseTracking; @@ -226,7 +227,7 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel { final Point mouseLocation = MouseInfo.getPointerInfo().getLocation(); SwingUtilities.convertPointFromScreen(mouseLocation, myTree); final TreePath path = myTree.getPathForLocation(mouseLocation.x, mouseLocation.y); - if (path == null) { + if (path == null && !isUnderMouse(myToolbarComponent)) { hideToolbar(); return; } @@ -252,6 +253,7 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel { .createBalloon(); Disposer.register(getProject(), balloon); Point hintPosition = GradleUtil.getHintPosition(node, myTree); + myToolbarComponent = toolbarComponent; myToolbar = balloon; myNodeWithActiveToolbar = node; balloon.show(new RelativePoint(myTree, hintPosition), Balloon.Position.below); @@ -269,9 +271,7 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel { if (myToolbar == null) { return; } - final Point location = MouseInfo.getPointerInfo().getLocation(); - SwingUtilities.convertPointFromScreen(location, GradleProjectStructureChangesPanel.this); - if (GradleProjectStructureChangesPanel.this.contains(location)) { + if (isUnderMouse(GradleProjectStructureChangesPanel.this) || isUnderMouse(myToolbarComponent)) { myToolbarTrackingAlarm.addRequest(this, delayMillis); } else { @@ -280,6 +280,15 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel { } }, delayMillis); } + + private static boolean isUnderMouse(@Nullable JComponent component) { + if (component == null) { + return false; + } + final Point location = MouseInfo.getPointerInfo().getLocation(); + SwingUtilities.convertPointFromScreen(location, component); + return component.contains(location); + } private void hideToolbar() { final Balloon toolbar = myToolbar; @@ -287,6 +296,7 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel { if (toolbar != null && !toolbar.isDisposed()) { toolbar.hide(); myToolbar = null; + myToolbarComponent = null; myToolbarAppearanceAlarm.cancelAllRequests(); myToolbarTrackingAlarm.cancelAllRequests(); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/conflict/GradleConflictControlFactory.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/conflict/GradleConflictControlFactory.java index 746d19479961..9399f0eeca0c 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/conflict/GradleConflictControlFactory.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/conflict/GradleConflictControlFactory.java @@ -30,12 +30,15 @@ import java.util.Collection; * @since 3/2/12 3:03 PM */ public class GradleConflictControlFactory { - + + @NotNull private final GradleProjectConflictControlFactory myProjectFactory; @NotNull private final GradleLibraryDependencyConflictControlFactory myLibraryDependencyFactory; @NotNull private final GradleCommonDependencyConflictControlFactory myCommonDependencyFactory; - public GradleConflictControlFactory(@NotNull GradleLibraryDependencyConflictControlFactory libraryFactory, + public GradleConflictControlFactory(@NotNull GradleProjectConflictControlFactory factory, + @NotNull GradleLibraryDependencyConflictControlFactory libraryFactory, @NotNull GradleCommonDependencyConflictControlFactory commonDependencyFactory) { + myProjectFactory = factory; myLibraryDependencyFactory = libraryFactory; myCommonDependencyFactory = commonDependencyFactory; } @@ -54,6 +57,7 @@ public class GradleConflictControlFactory { GradleUtil.dispatch(entity, new IntellijEntityVisitor() { @Override public void visit(@NotNull Project project) { + result.set(myProjectFactory.getControl(changes)); } @Override diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/conflict/GradleProjectConflictControlFactory.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/conflict/GradleProjectConflictControlFactory.java new file mode 100644 index 000000000000..822b27fcec3f --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/conflict/GradleProjectConflictControlFactory.java @@ -0,0 +1,77 @@ +package org.jetbrains.plugins.gradle.sync.conflict; + +import com.intellij.openapi.util.Ref; +import com.intellij.pom.java.LanguageLevel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChange; +import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChangeVisitor; +import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChangeVisitorAdapter; +import org.jetbrains.plugins.gradle.diff.project.GradleLanguageLevelChange; +import org.jetbrains.plugins.gradle.diff.project.GradleProjectRenameChange; +import org.jetbrains.plugins.gradle.ui.MatrixControlBuilder; +import org.jetbrains.plugins.gradle.util.GradleBundle; +import org.jetbrains.plugins.gradle.util.GradleUtil; + +import javax.swing.*; +import java.util.Collection; + +/** + * Thread-safe. + * + * @author Denis Zhdanov + * @since 3/15/12 4:26 PM + */ +public class GradleProjectConflictControlFactory { + + @SuppressWarnings("MethodMayBeStatic") + @Nullable + public JComponent getControl(Collection changes) { + final Ref renameChangeRef = new Ref(); + final Ref languageLevelChangeRef = new Ref(); + + GradleProjectStructureChangeVisitor visitor = new GradleProjectStructureChangeVisitorAdapter() { + @Override + public void visit(@NotNull GradleProjectRenameChange change) { + renameChangeRef.set(change); + } + + @Override + public void visit(@NotNull GradleLanguageLevelChange change) { + languageLevelChangeRef.set(change); + } + }; + + for (GradleProjectStructureChange change : changes) { + if (renameChangeRef.get() != null && languageLevelChangeRef.get() != null) { + break; + } + change.invite(visitor); + } + + final GradleProjectRenameChange renameChange = renameChangeRef.get(); + final GradleLanguageLevelChange languageLevelChange = languageLevelChangeRef.get(); + if (renameChange == null && languageLevelChange == null) { + return null; + } + + MatrixControlBuilder builder = GradleUtil.getConflictChangeBuilder(); + if (renameChange != null) { + builder.addRow(GradleBundle.message("gradle.import.structure.settings.label.name"), + renameChange.getGradleValue(), renameChange.getIntellijValue()); + } + + if (languageLevelChange != null) { + builder.addRow(GradleBundle.message("gradle.import.structure.settings.label.language.level"), + getTextToShow(languageLevelChange.getGradleValue()), getTextToShow(languageLevelChange.getIntellijValue())); + } + + return builder.build(); + } + + @NotNull + private static String getTextToShow(@NotNull LanguageLevel level) { + final String s = level.toString(); + return s.substring(s.indexOf('1')).replace('_', '.'); + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/MatrixControlBuilder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/MatrixControlBuilder.java index abc73cc47962..b8581a6efa54 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/MatrixControlBuilder.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/MatrixControlBuilder.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableColumnModel; import java.awt.*; import java.util.Arrays; @@ -34,27 +35,36 @@ import java.util.Arrays; public class MatrixControlBuilder { private final DefaultTableModel myModel = new DefaultTableModel(); - private final JComponent result; + + private final JBTable myTable; + private final JComponent myResult; + private final int[] myColumnWidths; + private final FontMetrics myFontMetrics; public MatrixControlBuilder(@NotNull String ... columns) { myModel.addColumn(""); // Row name for (String column : columns) { myModel.addColumn(column); } - final JBTable table = new JBTable(myModel) { + myTable = new JBTable(myModel) { @Override public Dimension getPreferredScrollableViewportSize() { return getPreferredSize(); } }; - table.setStriped(true); + myTable.setStriped(true); DefaultTableCellRenderer renderer = new DefaultTableCellRenderer(); renderer.setHorizontalAlignment(SwingConstants.CENTER); - for (int i = 1/* don't align row name */, max = table.getColumnCount(); i < max; i++) { - table.getColumnModel().getColumn(i).setCellRenderer(renderer); + for (int i = 1/* don't align row name */, max = myTable.getColumnCount(); i < max; i++) { + myTable.getColumnModel().getColumn(i).setCellRenderer(renderer); + } + myResult = ScrollPaneFactory.createScrollPane(myTable); + + myColumnWidths = new int[columns.length + 1/*'name' column*/]; + myFontMetrics = myTable.getFontMetrics(myTable.getFont()); + for (int i = 0; i < columns.length; i++) { + myColumnWidths[i + 1] = myFontMetrics.stringWidth(columns[i]); } - //table.setDefaultRenderer(String.class, renderer); - result = ScrollPaneFactory.createScrollPane(table); } /** @@ -82,10 +92,18 @@ public class MatrixControlBuilder { rowData[0] = name; System.arraycopy(values, 0, rowData, 1, values.length); myModel.addRow(rowData); + + for (int i = 0; i < rowData.length; i++) { + myColumnWidths[i] = Math.max(myFontMetrics.stringWidth(rowData[i].toString()), myColumnWidths[i]); + } } @NotNull public JComponent build() { - return result; + final TableColumnModel columnModel = myTable.getColumnModel(); + for (int i = 0; i < myColumnWidths.length; i++) { + columnModel.getColumn(i).setMinWidth(myColumnWidths[i] + 4); + } + return myResult; } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java index 4e7f2d577923..6f976c121c77 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java @@ -12,6 +12,8 @@ import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNodeDescriptor; */ public class GradleConstants { + @NonNls public static final String NEWLY_IMPORTED_PROJECT = "gradle.newly.imported"; + @NonNls public static final String EXTENSION = "gradle"; @NonNls public static final String DEFAULT_SCRIPT_NAME = "build.gradle"; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java index b878565f40ca..a504b9627115 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java @@ -27,8 +27,9 @@ import java.util.regex.Pattern; @SuppressWarnings("MethodMayBeStatic") public class GradleLibraryManager { - private static final Pattern GRADLE_JAR_FILE_PATTERN; - private static final Pattern ANY_GRADLE_JAR_FILE_PATTERN; + public static final Pattern GRADLE_JAR_FILE_PATTERN; + public static final Pattern ANY_GRADLE_JAR_FILE_PATTERN; + private static final String[] GRADLE_START_FILE_NAMES; @NonNls private static final String GRADLE_ENV_PROPERTY_NAME; static { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/GroovyLiteralCopyPasteProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/GroovyLiteralCopyPasteProcessor.java index 89c710f3ebbf..659c100a0058 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/GroovyLiteralCopyPasteProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/GroovyLiteralCopyPasteProcessor.java @@ -157,13 +157,11 @@ public class GroovyLiteralCopyPasteProcessor extends StringLiteralCopyPasteProce } if (tokenType == mGSTRING_CONTENT || tokenType == mGSTRING_LITERAL) { - boolean escapeDoubleQuotes = !token.getText().contains("\"\"\""); - return GrStringUtil.escapeSymbolsForGString(s, escapeDoubleQuotes, false); + return GrStringUtil.escapeSymbolsForGString(s, !token.getText().contains("\"\"\""), false); } if (tokenType == mSTRING_LITERAL) { - boolean escapeQuotes = !token.getText().contains("'''"); - return GrStringUtil.escapeSymbolsForString(s, escapeQuotes, false); + return GrStringUtil.escapeSymbolsForString(s, !token.getText().contains("'''"), false); } return super.escapeCharCharacters(s, token); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java index edb3b8798b1f..9658515a2ac7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java @@ -242,20 +242,20 @@ public class GrStringUtil { buffer.append(hexCode); } - public static String escapeSymbolsForGString(String s, boolean escapeDoubleQuotes, boolean forInjection) { + public static String escapeSymbolsForGString(String s, boolean isSingleLine, boolean forInjection) { StringBuilder b = new StringBuilder(); - escapeStringCharacters(s.length(), s, escapeDoubleQuotes ? "$\"" : "$", forInjection, true, b); + escapeStringCharacters(s.length(), s, isSingleLine ? "$\"" : "$", isSingleLine, true, b); if (!forInjection) { - unescapeCharacters(b, escapeDoubleQuotes ? "'" : "'\"", true); + unescapeCharacters(b, isSingleLine ? "'" : "'\"", true); } return b.toString(); } - public static String escapeSymbolsForString(String s, boolean escapeQuotes, boolean forInjection) { + public static String escapeSymbolsForString(String s, boolean isSingleLine, boolean forInjection) { final StringBuilder builder = new StringBuilder(); - escapeStringCharacters(s.length(), s, escapeQuotes ? "'" : "", forInjection, true, builder); + escapeStringCharacters(s.length(), s, isSingleLine ? "'" : "", isSingleLine, true, builder); if (!forInjection) { - unescapeCharacters(builder, escapeQuotes ? "$\"" : "$'\"", true); + unescapeCharacters(builder, isSingleLine ? "$\"" : "$'\"", true); } return builder.toString(); } @@ -741,6 +741,8 @@ public class GrStringUtil { if (index + 4 <= chars.length()) { try { int code = Integer.parseInt(chars.substring(index, index + 4), 16); + //line separators are invalid here + if (code == 0x000a || code == 0x000d) return false; c = chars.charAt(index); if (c == '+' || c == '-') return false; outChars.append((char)code); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyStringLiteralManipulator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyStringLiteralManipulator.java index 0737a3e1aa64..67d975795cdc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyStringLiteralManipulator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyStringLiteralManipulator.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.lang.resolve; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.AbstractElementManipulator; import com.intellij.util.IncorrectOperationException; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; @@ -36,10 +37,10 @@ public class GroovyStringLiteralManipulator extends AbstractElementManipulator'\u000a' +print "\u000d" print '\y' ptint "\n\a\t" print "\n\a${x}\t"