Merge remote-tracking branch 'origin/master'

This commit is contained in:
Kirill Likhodedov
2012-03-15 20:01:27 +04:00
41 changed files with 478 additions and 115 deletions
@@ -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;
}
}
@@ -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);
@@ -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);
@@ -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];
@@ -0,0 +1,18 @@
public class Util2 {
void foo(XmlAttribute o ) {
if (o instanceof XmlAttributeImpl) {
o.getpar<caret>
}
}
}
interface PsiElement {
PsiElement getParent();
}
interface XmlAttribute extends PsiElement {}
class XmlAttributeImpl implements XmlAttribute {
@Override
public PsiElement getParent() {
return null;
}
}
@@ -0,0 +1,18 @@
public class Util2 {
void foo(XmlAttribute o ) {
if (o instanceof XmlAttributeImpl) {
o.getParent()<caret>
}
}
}
interface PsiElement {
PsiElement getParent();
}
interface XmlAttribute extends PsiElement {}
class XmlAttributeImpl implements XmlAttribute {
@Override
public PsiElement getParent() {
return null;
}
}
@@ -0,0 +1,14 @@
import org.jetbrains.annotations.Nullable;
public class DDD {
int test(boolean t) {
if (t && <warning descr="Dereference of 'fff()' may produce 'java.lang.NullPointerException'">fff()</warning>.length == 1) {
return 0;
}
return 1;
}
public @Nullable DDD[] fff() {
return new DDD[8];
}
}
@@ -0,0 +1,9 @@
import org.jetbrains.annotations.Nullable;
public class DDD {
@Nullable
String field;
int test() {
return <warning descr="Method invocation 'new DDD().field.hashCode()' may produce 'java.lang.NullPointerException'">new DDD().field.hashCode()</warning>;
}
}
@@ -1325,5 +1325,6 @@ public class ListUtils {
}
public void testListArrayListCast() { doTest('\n') }
public void testInterfaceImplementationNoCast() { doTest() }
}
@@ -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(); }
}
@@ -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());
}
}
}
@@ -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<Boolean> update(final NodeDescriptor nodeDescriptor, boolean now) {
final AsyncResult<Boolean> result = new AsyncResult<Boolean>();
@@ -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<T> {
/**
* @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. <code>null</code> value indicates
* that no state should be stored
* @see XmlSerializer
*/
@Nullable
T getState();
/**
@@ -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;
}
@@ -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();
}
@@ -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;
}
}
@@ -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() {
@@ -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
type.ahead.logging.enabled=false
fast.tree.expand.in.structure.view=false
@@ -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();
}
}
@@ -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<VirtualFile> addedFiles = acquireAddedFiles();
for (Iterator<VirtualFile> 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);
}
}
}
+1
View File
@@ -61,6 +61,7 @@
<!--Conflict UI components-->
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.sync.conflict.GradleConflictControlFactory"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.sync.conflict.GradleProjectConflictControlFactory"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.sync.conflict.GradleCommonDependencyConflictControlFactory"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.sync.conflict.GradleLibraryDependencyConflictControlFactory"/>
@@ -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;
}
}
@@ -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<GradleSettings>,
@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());
@@ -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<GradleModule, Module> moduleMappings,
@@ -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<GradleProje
public List<Module> 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() {
@@ -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);
}
}
}
@@ -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();
}
@@ -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
@@ -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<GradleProjectStructureChange> changes) {
final Ref<GradleProjectRenameChange> renameChangeRef = new Ref<GradleProjectRenameChange>();
final Ref<GradleLanguageLevelChange> languageLevelChangeRef = new Ref<GradleLanguageLevelChange>();
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('_', '.');
}
}
@@ -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;
}
}
@@ -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";
@@ -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 {
@@ -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);
@@ -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);
@@ -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<G
String oldText = expr.getText();
final String quote = GrStringUtil.getStartQuote(oldText);
if (quote.startsWith("'")) {
newContent = GrStringUtil.escapeSymbolsForString(newContent, !quote.equals("'''"), false);
if (StringUtil.startsWithChar(quote, '\'')) {
newContent = GrStringUtil.escapeSymbolsForString(newContent, !quote.equals("'''"), true);
}
else if (quote.startsWith("\"")) {
else if (StringUtil.startsWithChar(quote, '\"')) {
newContent = GrStringUtil.escapeSymbolsForGString(newContent, !quote.equals("\"\"\""), true);
}
else if ("/".equals(quote)) {
@@ -274,7 +274,8 @@ public class ExtractClosureFromMethodProcessor extends ExtractClosureProcessorBa
@NotNull
@Override
public PsiType getForcedType() {
return myHelper.getSelectedType();
PsiType type = myHelper.getSelectedType();
return type != null ? type : PsiType.getJavaLangObject(PsiManager.getInstance(myProject), GlobalSearchScope.allScope(myProject));
}
@NotNull
@@ -44,6 +44,7 @@ public class ExtractClosureHelperImpl extends ExtractInfoHelperBase implements G
private final boolean myForceReturn;
private PsiType myType = null;
private boolean myForceDef;
public ExtractClosureHelperImpl(IntroduceParameterInfo info,
String name,
@@ -51,9 +52,10 @@ public class ExtractClosureHelperImpl extends ExtractInfoHelperBase implements G
TIntArrayList toRemove,
boolean generateDelegate,
int replaceFieldsWithGetters,
boolean forceReturn) {
boolean forceReturn, boolean forceDef) {
super(info);
myForceReturn = forceReturn;
myForceDef = forceDef;
myOwner = info.getToReplaceIn();
myToSearchFor = info.getToSearchFor();
myName = name;
@@ -102,6 +104,8 @@ public class ExtractClosureHelperImpl extends ExtractInfoHelperBase implements G
@Override
public PsiType getSelectedType() {
if (myForceDef) return null;
if (myType == null) {
final GrClosableBlock closure = ExtractClosureProcessorBase.generateClosure(this);
PsiType type = closure.getType();
@@ -39,7 +39,7 @@ public class GrIntroduceExpressionSettingsImpl extends ExtractClosureHelperImpl
GrVariable var,
PsiType selectedType,
boolean forceReturn) {
super(info, name, declareFinal, toRemove, generateDelegate, replaceFieldsWithGetters, forceReturn);
super(info, name, declareFinal, toRemove, generateDelegate, replaceFieldsWithGetters, forceReturn, false);
myExpr = expr;
myVar = var;
mySelectedType = selectedType;
@@ -325,7 +325,7 @@ public class GrIntroduceParameterDialog extends DialogWrapper implements GrIntro
@Nullable
private PsiType inferClosureReturnType() {
final ExtractClosureHelperImpl mockHelper =
new ExtractClosureHelperImpl(myInfo, "__test___n_", false, new TIntArrayList(), false, 0, false);
new ExtractClosureHelperImpl(myInfo, "__test___n_", false, new TIntArrayList(), false, 0, false, false);
final PsiType returnType;
final AccessToken token = WriteAction.start();
try {
@@ -469,7 +469,8 @@ public class GrIntroduceParameterDialog extends DialogWrapper implements GrIntro
getParametersToRemove(),
myDelegateViaOverloadingMethodCheckBox.isSelected(),
getReplaceFieldsWithGetter(),
myForceReturnCheckBox.isSelected());
myForceReturnCheckBox.isSelected(),
myTypeComboBox.getSelectedType() == null);
if (toReplaceIn instanceof GrMethod) {
invokeRefactoring(new ExtractClosureFromMethodProcessor(settings));
}
@@ -46,7 +46,8 @@ public abstract class ExtractClosureTest extends LightGroovyTestCase {
GrIntroduceParameterSettings helper = new ExtractClosureHelperImpl(info, "closure", false,
new TIntArrayList(toRemove as int[]), false,
IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, forceReturn)
IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE,
forceReturn, false)
for (p in notToUseAsParams) {
helper.parameterInfos[p].passAsParameter = false
}
@@ -1,4 +1,6 @@
print '\n'
print <error descr="Illegal escape character in string literal">'\u000a'</error>
print <error descr="Illegal escape character in string literal">"\u000d"</error>
print <error descr="Illegal escape character in string literal">'\y'</error>
ptint <error descr="Illegal escape character in string literal">"\n\a\t"</error>
print <error descr="Illegal escape character in string literal">"\n\a${x}\t"</error>