Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2012-12-20 18:57:39 +01:00
49 changed files with 538 additions and 209 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 64 KiB

@@ -82,7 +82,7 @@ import java.util.List;
* @author anna
* @since 26-Jun-2007
*/
public class ExternalAnnotationsManagerImpl extends BaseExternalAnnotationsManager {
public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsManager {
private static final Logger LOG = Logger.getInstance("#" + ExternalAnnotationsManagerImpl.class.getName());
private final MessageBus myBus;
@@ -625,10 +625,8 @@ public class JavaCompletionData extends JavaAwareCompletionData {
afterNew ||
expressionPosition ||
isStatementPosition(position)) {
boolean needSpace = !inCast && !typeFragment && !expressionPosition && !inGenerics && !afterNew;
for (String primitiveType : PRIMITIVE_TYPES) {
LookupElement keyword = createKeyword(position, primitiveType);
result.addElement(needSpace ? new OverrideableSpace(keyword, TailType.HUMBLE_SPACE_BEFORE_WORD) : keyword);
result.addElement(createKeyword(position, primitiveType));
}
}
if (declaration) {
@@ -1558,7 +1558,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
return myFactory.getVarFactory().createVariableValue(var, refExpr.getType(), false, null, isCall);
}
if (var instanceof PsiField && var.hasModifierProperty(PsiModifier.FINAL)) {
if (DfaVariableState.isFinalField(var)) {
DfaVariableValue qualifierValue = createChainedVariableValue(qualifier);
if (qualifierValue != null) {
return myFactory.getVarFactory().createVariableValue(var, refExpr.getType(), false, qualifierValue, isCall || qualifierValue.isViaMethods());
@@ -790,7 +790,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
public void flushVariable(@NotNull DfaVariableValue variable) {
PsiVariable psiVariable = variable.getPsiVariable();
if (psiVariable instanceof PsiField && psiVariable.hasModifierProperty(PsiModifier.FINAL)) {
if (DfaVariableState.isFinalField(psiVariable)) {
return;
}
@@ -63,7 +63,7 @@ public class DfaVariableState implements Cloneable {
}
private static boolean isNullableInitialized(PsiVariable var, boolean nullable) {
if (!var.hasModifierProperty(PsiModifier.FINAL) || !(var instanceof PsiField)) {
if (!isFinalField(var)) {
return false;
}
@@ -90,6 +90,10 @@ public class DfaVariableState implements Cloneable {
return !nullable;
}
public static boolean isFinalField(PsiVariable var) {
return var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && var instanceof PsiField;
}
public boolean isNullable() {
return myNullable;
}
@@ -122,7 +122,7 @@ public class DfaValueFactory {
}
final PsiVariable variable = (PsiVariable)psiSource;
if (variable.hasModifierProperty(PsiModifier.FINAL)) {
if (variable.hasModifierProperty(PsiModifier.FINAL) && !variable.hasModifierProperty(PsiModifier.TRANSIENT)) {
DfaValue constValue = getConstFactory().create(variable);
if (constValue != null) return constValue;
@@ -0,0 +1,81 @@
/*
* 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.codeInsight;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.PsiManager;
import com.intellij.util.ThreeState;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class ReadableExternalAnnotationsManager extends BaseExternalAnnotationsManager {
@NotNull private volatile ThreeState myHasAnyAnnotationsRoots = ThreeState.UNSURE;
public ReadableExternalAnnotationsManager(PsiManager psiManager) {
super(psiManager);
}
@Override
protected boolean hasAnyAnnotationsRoots() {
if (myHasAnyAnnotationsRoots == ThreeState.UNSURE) {
final Module[] modules = ModuleManager.getInstance(myPsiManager.getProject()).getModules();
for (Module module : modules) {
for (OrderEntry entry : ModuleRootManager.getInstance(module).getOrderEntries()) {
final String[] urls = AnnotationOrderRootType.getUrls(entry);
if (urls.length > 0) {
myHasAnyAnnotationsRoots = ThreeState.YES;
return true;
}
}
}
myHasAnyAnnotationsRoots = ThreeState.NO;
}
return myHasAnyAnnotationsRoots == ThreeState.YES;
}
@NotNull
@Override
protected List<VirtualFile> getExternalAnnotationsRoots(@NotNull VirtualFile libraryFile) {
final List<OrderEntry> entries = ProjectRootManager.getInstance(myPsiManager.getProject()).getFileIndex().getOrderEntriesForFile(
libraryFile);
List<VirtualFile> result = new ArrayList<VirtualFile>();
for (OrderEntry entry : entries) {
if (entry instanceof ModuleOrderEntry) {
continue;
}
final String[] externalUrls = AnnotationOrderRootType.getUrls(entry);
for (String url : externalUrls) {
VirtualFile root = VirtualFileManager.getInstance().findFileByUrl(url);
if (root != null) {
result.add(root);
}
}
}
return result;
}
@Override
protected void dropCache() {
myHasAnyAnnotationsRoots = ThreeState.UNSURE;
super.dropCache();
}
}
@@ -16,21 +16,16 @@
package com.intellij.codeInsight;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ThreeState;
import com.intellij.util.containers.ConcurrentSoftHashMap;
import com.intellij.util.containers.ConcurrentSoftValueHashMap;
import com.intellij.util.containers.MultiMap;
@@ -45,11 +40,11 @@ import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentMap;
public class BaseExternalAnnotationsManager extends ExternalAnnotationsManager {
public abstract class BaseExternalAnnotationsManager extends ExternalAnnotationsManager{
private static final Logger LOG = Logger.getInstance("#" + BaseExternalAnnotationsManager.class.getName());
@NotNull private static final List<PsiFile> NULL = new ArrayList<PsiFile>();
@NotNull protected final ConcurrentMap<String, List<PsiFile>> myExternalAnnotations = new ConcurrentSoftValueHashMap<String, List<PsiFile>>();
@NotNull private volatile ThreeState myHasAnyAnnotationsRoots = ThreeState.UNSURE;
@NotNull protected final ConcurrentMap<String, List<PsiFile>>
myExternalAnnotations = new ConcurrentSoftValueHashMap<String, List<PsiFile>>();
protected final PsiManager myPsiManager;
public BaseExternalAnnotationsManager(final PsiManager psiManager) {
@@ -95,22 +90,7 @@ public class BaseExternalAnnotationsManager extends ExternalAnnotationsManager {
return StringUtil.trimEnd(buf.toString(), ", ") + externalName.substring(rightIdx);
}
protected boolean hasAnyAnnotationsRoots() {
if (myHasAnyAnnotationsRoots == ThreeState.UNSURE) {
final Module[] modules = ModuleManager.getInstance(myPsiManager.getProject()).getModules();
for (Module module : modules) {
for (OrderEntry entry : ModuleRootManager.getInstance(module).getOrderEntries()) {
final String[] urls = AnnotationOrderRootType.getUrls(entry);
if (urls.length > 0) {
myHasAnyAnnotationsRoots = ThreeState.YES;
return true;
}
}
}
myHasAnyAnnotationsRoots = ThreeState.NO;
}
return myHasAnyAnnotationsRoots == ThreeState.YES;
}
protected abstract boolean hasAnyAnnotationsRoots();
@Override
@Nullable
@@ -216,7 +196,7 @@ public class BaseExternalAnnotationsManager extends ExternalAnnotationsManager {
if (onlyWritable && !file.isWritable()) continue;
final MultiMap<String, AnnotationData> fileData = getDataFromFile(file);
collectAnnotations(result, fileData.get(externalName), factory);
collectAnnotations(result, fileData.get(oldExternalName), factory);
}
@@ -241,24 +221,7 @@ public class BaseExternalAnnotationsManager extends ExternalAnnotationsManager {
}
@NotNull
protected List<VirtualFile> getExternalAnnotationsRoots(@NotNull VirtualFile libraryFile) {
final List<OrderEntry> entries = ProjectRootManager.getInstance(myPsiManager.getProject()).getFileIndex().getOrderEntriesForFile(
libraryFile);
List<VirtualFile> result = new ArrayList<VirtualFile>();
for (OrderEntry entry : entries) {
if (entry instanceof ModuleOrderEntry) {
continue;
}
final String[] externalUrls = AnnotationOrderRootType.getUrls(entry);
for (String url : externalUrls) {
VirtualFile root = VirtualFileManager.getInstance().findFileByUrl(url);
if (root != null) {
result.add(root);
}
}
}
return result;
}
protected abstract List<VirtualFile> getExternalAnnotationsRoots(@NotNull VirtualFile libraryFile);
@Override
@Nullable
@@ -321,7 +284,6 @@ public class BaseExternalAnnotationsManager extends ExternalAnnotationsManager {
protected void dropCache() {
myExternalAnnotations.clear();
annotationsFileToDataAndModificationStamp.clear();
myHasAnyAnnotationsRoots = ThreeState.UNSURE;
cache.clear();
}
@@ -217,7 +217,7 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements
if (is15OrHigher) {
final PsiSubstitutor substitutor = result.getSubstitutor();
PsiType substitutedReturnType = substitutor.substitute(ret);
if (substitutedReturnType == null) return TypeConversionUtil.erasure(ret);
if (PsiUtil.isRawSubstitutor(method, substitutor) && ret.equals(substitutedReturnType)) return TypeConversionUtil.erasure(ret);
PsiType lowerBound = PsiType.NULL;
if (substitutedReturnType instanceof PsiCapturedWildcardType) {
lowerBound = ((PsiCapturedWildcardType)substitutedReturnType).getLowerBound();
@@ -81,15 +81,15 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
// then noone can be more specific
if (!atLeastOneMatch) return null;
checkLambdaApplicable(conflicts);
if (conflicts.size() == 1) return conflicts.get(0);
checkSpecifics(conflicts, applicabilityLevel);
if (conflicts.size() == 1) return conflicts.get(0);
checkPrimitiveVarargs(conflicts, myActualParameterTypes.length);
if (conflicts.size() == 1) return conflicts.get(0);
checkLambdaApplicable(conflicts);
if (conflicts.size() == 1) return conflicts.get(0);
THashSet<CandidateInfo> uniques = new THashSet<CandidateInfo>(conflicts);
if (uniques.size() == 1) return uniques.iterator().next();
return null;
@@ -1,3 +1,3 @@
public class Foo {
Object foo(boolean <caret>){ }
Object foo(boolean<caret>){ }
}
@@ -1723,7 +1723,7 @@ class SystemClassLoaderAction implements <error descr="Cannot resolve symbol 'Pr
}
c = Class.forName<error descr="'forName(java.lang.String, boolean, java.lang.ClassLoader)' in 'java.lang.Class' cannot be applied to '(java.lang.String, boolean, ClassLoader)'">(cls, true, parent)</error>;
<error descr="Incompatible types. Found: 'java.lang.reflect.Constructor<T>', required: 'Constructor'">ctor = c.getDeclaredConstructor(cp)</error>;
ctor = c.getDeclaredConstructor(cp);
sys = (ClassLoader) ctor.<error descr="Cannot resolve method 'newInstance(java.lang.Object[])'">newInstance</error>(params);
Thread.currentThread().setContextClassLoader<error descr="'setContextClassLoader(java.lang.ClassLoader)' in 'java.lang.Thread' cannot be applied to '(ClassLoader)'">(sys)</error>;
return sys;
@@ -0,0 +1,23 @@
import java.util.*;
import java.io.File;
class Foo {
public Collection<BuildTarget<?>> getDependencies(LayoutElementBuilderService builder, JpsPackagingElement element, TargetOutputIndex outputIndex) {
return builder.getDependencies(element, outputIndex);
}
}
class BuildTarget<R extends BuildRootDescriptor> {}
interface TargetOutputIndex {
Collection<BuildTarget<?>> getTargetsByOutputFile(File file);
}
class BuildRootDescriptor {}
class LayoutElementBuilderService<E extends JpsPackagingElement> {
public Collection<? extends BuildTarget<?>> getDependencies(E element, TargetOutputIndex outputIndex) {
return Collections.emptyList();
}
}
class JpsPackagingElement {}
@@ -0,0 +1,25 @@
class X {
public static void main(final Stream<String> stream) throws Throwable {
stream.map(s -> s.substring("http://".length())).forEach(System.out::println);
}
}
interface Stream<T> {
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
IntStream map(IntFunction<? super T> mapper);
void forEach(Block<? super T> block);
}
interface IntFunction<T> extends Function<T, Integer> {
public int applyAsInt(T t);
}
interface Function<T, R> {
public R apply(T t);
}
interface IntStream extends BaseStream<Integer> {}
interface BaseStream<T> {}
interface Block<T> {
public void accept(T t);
}
@@ -0,0 +1,11 @@
final class Alive implements java.io.Serializable {
private transient final Object elvis = new Object();
@Override
public String toString() {
if (elvis != null) {
return "uh-huh-huh";
} else {
return "the king is dead";
}
}
}
@@ -125,10 +125,10 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase {
myFixture.complete(CompletionType.BASIC, 2);
}
public void _testDontDispreferImplsAfterNew() { //todo[peter]
public void testImplsAfterNew() {
myFixture.addClass("package foo; public interface Xxx {}");
configureSecondCompletion();
assertPreferredItems(0, "Xxx", "XxxImpl");
assertPreferredItems(0, "XxxImpl", "Xxx");
}
public void testPreferLessHumps() throws Throwable {
@@ -207,6 +207,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testIDEA97276() throws Exception { doTest17Incompatibility(false); }
public void testWildcardsBoundsIntersection() throws Exception { doTest17Incompatibility(false); }
public void testOverrideWithMoreSpecificReturn() throws Exception { doTest17Incompatibility(false); }
public void testIDEA97888() throws Exception { doTest17Incompatibility(false); }
public void testJavaUtilCollections_NoVerify() throws Exception {
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));
@@ -173,6 +173,10 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testReturnTypeCompatibilityBeforeSpecificsCheck() throws Exception {
doTest();
}
private void doTest() throws Exception {
doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
}
@@ -147,6 +147,9 @@ public class DataFlowInspectionFixtureTest extends JavaCodeInsightFixtureTestCas
public void testMethodCallFlushesField() { doTest(); }
public void testUnknownFloatMayBeNaN() { doTest(); }
public void testLastConstantConditionInAnd() { doTest(); }
public void testTransientFinalField() { doTest(); }
public void testNullableForeachVariable() {
setupCustomAnnotations();
doTest();
@@ -120,7 +120,7 @@ public final class LoadTextUtil {
Charset charset = virtualFile.isCharsetSet() ? virtualFile.getCharset() : detectCharset(virtualFile, content);
Pair<Charset,byte[]> bomAndCharset = getBOMAndCharset(content, charset);
final byte[] bom = bomAndCharset.second;
if (saveBOM && bom.length != 0) {
if (saveBOM && bom != null && bom.length != 0) {
virtualFile.setBOM(bom);
}
return bomAndCharset;
@@ -27,6 +27,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtilRt;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
@@ -216,6 +217,10 @@ public class JdkUtil {
}
String classpath = PathUtil.getJarPathForClass(commandLineWrapper);
final String utilRtPath = PathUtil.getJarPathForClass(StringUtilRt.class);
if (!classpath.equals(utilRtPath)) {
classpath += File.pathSeparator + utilRtPath;
}
final Class<UrlClassLoader> ourUrlClassLoader = UrlClassLoader.class;
if (ourUrlClassLoader.getName().equals(vmParametersList.getPropertyValue("java.system.class.loader"))) {
classpath += File.pathSeparator + PathUtil.getJarPathForClass(ourUrlClassLoader);
@@ -38,6 +38,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
public class Tool implements SchemeElement {
@NonNls public final static String ACTION_ID_PREFIX = "Tool_";
@@ -201,22 +202,22 @@ public class Tool implements SchemeElement {
}
public void copyFrom(Tool source) {
myName = source.myName;
myDescription = source.myDescription;
myGroup = source.myGroup;
myShownInMainMenu = source.myShownInMainMenu;
myShownInEditor = source.myShownInEditor;
myShownInProjectViews = source.myShownInProjectViews;
myShownInSearchResultsPopup = source.myShownInSearchResultsPopup;
myEnabled = source.myEnabled;
myUseConsole = source.myUseConsole;
myShowConsoleOnStdOut = source.myShowConsoleOnStdOut;
myShowConsoleOnStdErr = source.myShowConsoleOnStdErr;
mySynchronizeAfterExecution = source.mySynchronizeAfterExecution;
myWorkingDirectory = source.myWorkingDirectory;
myProgram = source.myProgram;
myParameters = source.myParameters;
myOutputFilters = (ArrayList<FilterInfo>)source.myOutputFilters.clone();
myName = source.getName();
myDescription = source.getDescription();
myGroup = source.getGroup();
myShownInMainMenu = source.isShownInMainMenu();
myShownInEditor = source.isShownInEditor();
myShownInProjectViews = source.isShownInProjectViews();
myShownInSearchResultsPopup = source.isShownInSearchResultsPopup();
myEnabled = source.isEnabled();
myUseConsole = source.isUseConsole();
myShowConsoleOnStdOut = source.isShowConsoleOnStdOut();
myShowConsoleOnStdErr = source.isShowConsoleOnStdErr();
mySynchronizeAfterExecution = source.synchronizeAfterExecution();
myWorkingDirectory = source.getWorkingDirectory();
myProgram = source.getProgram();
myParameters = source.getParameters();
myOutputFilters = new ArrayList<FilterInfo>(Arrays.asList(source.getOutputFilters()));
}
public boolean equals(Object obj) {
@@ -72,7 +72,7 @@
</constraints>
<properties>
<text value="Remember passwords &amp;until the application is closed"/>
<toolTipText value="The passwords are stored only in the memory. They will be forgotten when IDEA session terminates."/>
<toolTipText value="The passwords are stored only in the memory. They will be forgotten when application terminates."/>
</properties>
</component>
<component id="4e7bb" class="javax.swing.JRadioButton" binding="myRememberOnDiskProtectedRadioButton" default-binding="true">
@@ -24,7 +24,6 @@ import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.util.TextRange;
class MoveCaretLeftOrRightHandler extends EditorActionHandler {
enum Direction {LEFT, RIGHT}
@@ -48,11 +47,12 @@ class MoveCaretLeftOrRightHandler extends EditorActionHandler {
else {
int start = selectionModel.getSelectionStart();
int end = selectionModel.getSelectionEnd();
int caretOffset = caretModel.getOffset();
int leftGuard = start + (myDirection == Direction.LEFT ? 1 : 0);
int rightGuard = end - (myDirection == Direction.RIGHT ? 1 : 0);
if (TextRange.from(leftGuard, rightGuard - leftGuard + 1).contains(caretModel.getOffset())) { // See IDEADEV-36957
//int leftGuard = start + (myDirection == Direction.LEFT ? 1 : 0);
//int rightGuard = end - (myDirection == Direction.RIGHT ? 1 : 0);
//if (TextRange.from(leftGuard, rightGuard - leftGuard + 1).contains(caretModel.getOffset())) { // See IDEADEV-36957
if (start <= caretOffset && end >= caretOffset) { // See IDEADEV-36957
selectionModel.removeSelection();
caretModel.moveToOffset(myDirection == Direction.RIGHT ? end : start);
scrollingModel.scrollToCaret(ScrollType.RELATIVE);
@@ -321,6 +321,10 @@ public class NameUtilTest extends UsefulTestCase {
assertFalse(pattern + " matches " + name + "!!!", caseInsensitiveMatcher(pattern).matches(name));
}
public void testUpperCaseMatchesLowerCase() {
assertMatches("ABC_B.C", "abc_b.c");
}
public void testLowerCaseHumps() {
assertMatches("foo", "foo");
assertDoesntMatch("foo", "fxoo");
@@ -61,7 +61,7 @@ public class MinusculeMatcher implements Matcher {
}
int i = 0;
while (isWildcard(i)) i++;
myHasHumps = hasHumps(i + 1);
myHasHumps = hasFlag(i + 1, isUpperCase) && hasFlag(i + 1, isLowerCase);
myHasDots = hasDots(i);
myHasWildCards = hasWildCards();
}
@@ -75,9 +75,9 @@ public class MinusculeMatcher implements Matcher {
return false;
}
private boolean hasHumps(int start) {
private boolean hasFlag(int start, boolean[] flags) {
for (int i = start; i < myPattern.length; i++) {
if (isUpperCase[i]) {
if (flags[i]) {
return true;
}
}
@@ -19,6 +19,7 @@ import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.win32.FileInfo;
import com.intellij.openapi.util.io.win32.IdeaWin32;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.TimeoutUtil;
import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Before;
@@ -30,7 +31,6 @@ import java.util.Arrays;
import static com.intellij.openapi.util.io.IoTestUtil.assertTimestampsEqual;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
public class FileAttributesReadingTest {
@@ -344,6 +344,33 @@ public class FileAttributesReadingTest {
assertEquals(link.getPath(), resolved);
}
@Test
public void stamps() throws Exception {
FileAttributes attributes = FileSystemUtil.getAttributes(myTempDirectory);
assumeTrue(attributes != null && attributes.lastModified > (attributes.lastModified/1000)*1000);
long t1 = System.currentTimeMillis();
TimeoutUtil.sleep(10);
File file = IoTestUtil.createTestFile(myTempDirectory, "test.txt");
TimeoutUtil.sleep(10);
long t2 = System.currentTimeMillis();
attributes = getAttributes(file);
assertTrue(attributes.lastModified + " not in " + t1 + ".." + t2, t1 <= attributes.lastModified && attributes.lastModified <= t2);
t1 = System.currentTimeMillis();
TimeoutUtil.sleep(10);
FileUtil.writeToFile(file, myTestData);
TimeoutUtil.sleep(10);
t2 = System.currentTimeMillis();
attributes = getAttributes(file);
assertTrue(attributes.lastModified + " not in " + t1 + ".." + t2, t1 <= attributes.lastModified && attributes.lastModified <= t2);
ProcessBuilder cmd = SystemInfo.isWindows ? new ProcessBuilder("attrib", "-A", file.getPath()) : new ProcessBuilder("chmod", "644", file.getPath());
assertEquals(0, cmd.start().waitFor());
attributes = getAttributes(file);
assertTrue(attributes.lastModified + " not in " + t1 + ".." + t2, t1 <= attributes.lastModified && attributes.lastModified <= t2);
}
@NotNull
private static FileAttributes getAttributes(@NotNull final File file) {
return getAttributes(file, true);
@@ -112,9 +112,6 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati
if (avdInfo == null) {
throw new RuntimeConfigurationError(AndroidBundle.message("avd.not.found.error", PREFERRED_AVD));
}
if (!facet.isCompatibleAvd(avdInfo)) {
throw new RuntimeConfigurationError(AndroidBundle.message("avd.not.compatible.error", PREFERRED_AVD));
}
if (avdInfo.getStatus() != AvdInfo.AvdStatus.OK) {
throw new RuntimeConfigurationError(AndroidBundle.message("avd.not.valid.error", PREFERRED_AVD));
}
@@ -15,6 +15,8 @@
*/
package org.jetbrains.android.run;
import com.android.sdklib.internal.avd.AvdInfo;
import com.android.sdklib.internal.avd.AvdManager;
import com.intellij.execution.ui.ConfigurationModuleSelector;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.application.ModalityState;
@@ -98,17 +100,28 @@ public class AndroidRunConfigurationEditor<T extends AndroidRunConfigurationBase
});
myAvdCombo = myAvdComboComponent.getComponent();
myAvdCombo.getComboBox().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final String warning = myEmulatorRadioButton.isSelected()
? getAvdCompatibilityWarning()
: null;
resetAvdCompatibilityWarningLabel(warning);
}
});
myMinSdkInfoMessageLabel.setBorder(IdeBorderFactory.createEmptyBorder(10, 0, 0, 0));
myMinSdkInfoMessageLabel.setIcon(AllIcons.General.Warning);
myMinSdkInfoMessageLabel.setDisabledIcon(AllIcons.General.Warning);
myMinSdkInfoMessageLabel.setIcon(AllIcons.General.BalloonWarning);
Disposer.register(this, myAvdCombo);
final ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
boolean enabled = myEmulatorRadioButton.isSelected();
myAvdComboComponent.setEnabled(enabled);
myMinSdkInfoMessageLabel.setEnabled(enabled);
boolean emulatorSelected = myEmulatorRadioButton.isSelected();
myAvdComboComponent.setEnabled(emulatorSelected);
final String warning = emulatorSelected
? getAvdCompatibilityWarning()
: null;
resetAvdCompatibilityWarningLabel(warning);
}
};
myModulesComboBox.addActionListener(new ActionListener() {
@@ -124,6 +137,36 @@ public class AndroidRunConfigurationEditor<T extends AndroidRunConfigurationBase
myNetworkLatencyCombo.setModel(new DefaultComboBoxModel(NETWORK_LATENCIES));
}
private void resetAvdCompatibilityWarningLabel(@Nullable String warning) {
if (warning != null) {
myMinSdkInfoMessageLabel.setVisible(true);
myMinSdkInfoMessageLabel.setText(warning);
}
else {
myMinSdkInfoMessageLabel.setVisible(false);
}
}
private String getAvdCompatibilityWarning() {
final String selectedAvdName = (String)myAvdCombo.getComboBox().getSelectedItem();
if (selectedAvdName != null) {
final Module module = getModuleSelector().getModule();
final AndroidFacet facet = module != null ? AndroidFacet.getInstance(module) : null;
final AvdManager avdManager = facet != null ? facet.getAvdManagerSilently() : null;
if (avdManager != null) {
final AvdInfo avd = avdManager.getAvd(selectedAvdName, false);
if (avd != null && !facet.isCompatibleAvd(avd)) {
// todo: provide info about current module configuration
return "'" + selectedAvdName + "' may be incompatible with your configuration";
}
}
}
return null;
}
@Override
public JComponent getAnchor() {
return anchor;
@@ -173,7 +216,10 @@ public class AndroidRunConfigurationEditor<T extends AndroidRunConfigurationBase
myUsbDeviceRadioButton.setSelected(targetSelectionMode == TargetSelectionMode.USB_DEVICE);
myAvdComboComponent.setEnabled(targetSelectionMode == TargetSelectionMode.EMULATOR);
myMinSdkInfoMessageLabel.setEnabled(targetSelectionMode == TargetSelectionMode.EMULATOR);
resetAvdCompatibilityWarningLabel(targetSelectionMode == TargetSelectionMode.EMULATOR
? getAvdCompatibilityWarning()
: null);
myCommandLineField.setText(configuration.COMMAND_LINE);
myConfigurationSpecificEditor.resetFrom(configuration);
@@ -110,7 +110,7 @@ public abstract class AvdComboBox extends ComboboxWithBrowseButton {
if (myAddEmptyElement) {
newAvdList.add("");
}
for (AvdInfo avd : facet.getAllCompatibleAvds()) {
for (AvdInfo avd : facet.getAllAvds()) {
final String avdName = avd.getName();
if (!filteringSet.contains(avdName)) {
newAvdList.add(avdName);
@@ -157,7 +157,8 @@ public class DetailsCache {
@Override
public void run(@NotNull ProgressIndicator indicator) {
if (!recheck.process(abstractHash)) return;
if (getBranches(root, abstractHash) != null) return;
List<String> branches1 = getBranches(root, abstractHash);
if (branches1 != null && ! branches1.isEmpty()) return;
List<String> branches;
try {
branches = new LowLevelAccessImpl(myProject, root).getBranchesWithCommit(abstractHash.getString());
@@ -495,7 +495,7 @@ public class GitLogUI implements Disposable {
if (commitI == null) return;
final VirtualFile root = commitI.selectRepository(myRootsUnderVcs);
final List<String> branches = myDetailsCache.getBranches(root, commitI.getHash());
if (branches != null) {
if (branches != null && ! branches.isEmpty()) {
try {
myBranchesLoader.take(commitI, branches);
}
@@ -2,6 +2,7 @@ package org.jetbrains.plugins.gradle.diff.project;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.config.PlatformFacade;
@@ -9,10 +10,12 @@ import org.jetbrains.plugins.gradle.diff.GradleChangesCalculationContext;
import org.jetbrains.plugins.gradle.diff.GradleDiffUtil;
import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChange;
import org.jetbrains.plugins.gradle.diff.GradleStructureChangesCalculator;
import org.jetbrains.plugins.gradle.diff.library.GradleLibraryStructureChangesCalculator;
import org.jetbrains.plugins.gradle.diff.module.GradleModuleStructureChangesCalculator;
import org.jetbrains.plugins.gradle.model.gradle.GradleModule;
import org.jetbrains.plugins.gradle.model.gradle.GradleProject;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
@@ -26,12 +29,16 @@ import java.util.Set;
*/
public class GradleProjectStructureChangesCalculator implements GradleStructureChangesCalculator<GradleProject, Project> {
private final GradleModuleStructureChangesCalculator myModuleChangesCalculator;
private final PlatformFacade myPlatformFacade;
@NotNull private final GradleModuleStructureChangesCalculator myModuleChangesCalculator;
@NotNull private final GradleLibraryStructureChangesCalculator myLibraryChangesCalculator;
@NotNull private final PlatformFacade myPlatformFacade;
public GradleProjectStructureChangesCalculator(@NotNull GradleModuleStructureChangesCalculator moduleCalculator,
@NotNull PlatformFacade platformFacade) {
@NotNull GradleLibraryStructureChangesCalculator calculator,
@NotNull PlatformFacade platformFacade)
{
myModuleChangesCalculator = moduleCalculator;
myLibraryChangesCalculator = calculator;
myPlatformFacade = platformFacade;
}
@@ -45,6 +52,9 @@ public class GradleProjectStructureChangesCalculator implements GradleStructureC
final Set<? extends GradleModule> gradleSubEntities = gradleEntity.getModules();
final Collection<Module> intellijSubEntities = myPlatformFacade.getModules(intellijEntity);
GradleDiffUtil.calculate(myModuleChangesCalculator, gradleSubEntities, intellijSubEntities, context);
LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(intellijEntity);
GradleDiffUtil.calculate(myLibraryChangesCalculator, gradleEntity.getLibraries(), Arrays.asList(libraryTable.getLibraries()), context);
}
@NotNull
@@ -62,7 +62,7 @@ public class GradleJarManager {
Library.ModifiableModel model = library.getModifiableModel();
try {
for (VirtualFile file : model.getFiles(OrderRootType.CLASSES)) {
if (jar.getPath().equals(file.getPath())) {
if (jar.getPath().equals(GradleUtil.getLocalFileSystemPath(file))) {
return;
}
}
@@ -5,7 +5,9 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ExportableOrderEntry;
import com.intellij.openapi.roots.LibraryOrderEntry;
import com.intellij.openapi.roots.ModuleOrderEntry;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
@@ -189,16 +191,34 @@ public class GradleLocalNodeManageHelper {
private void collectLibraryDependencyEntities(@NotNull GradleLibraryDependency dependency, @NotNull Context context) {
final LibraryOrderEntry intellijDependency
= myProjectStructureHelper.findIntellijLibraryDependency(dependency.getOwnerModule().getName(), dependency.getName());
if (intellijDependency != null) {
// Already imported.
return;
Set<String> intellijPaths = ContainerUtilRt.newHashSet();
GradleLibrary gradleLibrary = dependency.getTarget();
Library intellijLibrary = null;
if (intellijDependency == null) {
context.dependencies.add(dependency);
}
context.dependencies.add(dependency);
final GradleLibrary gradleLibrary = dependency.getTarget();
final Library intellijLibrary = myProjectStructureHelper.findIntellijLibrary(gradleLibrary);
else {
intellijLibrary = intellijDependency.getLibrary();
}
if (intellijLibrary == null) {
intellijLibrary = myProjectStructureHelper.findIntellijLibrary(gradleLibrary);
}
if (intellijLibrary == null) {
context.libraries.add(gradleLibrary);
}
else {
for (VirtualFile jarFile : intellijLibrary.getFiles(OrderRootType.CLASSES)) {
intellijPaths.add(GradleUtil.getLocalFileSystemPath(jarFile));
}
}
for (String gradleJarPath : gradleLibrary.getPaths(LibraryPathType.BINARY)) {
if (!intellijPaths.contains(gradleJarPath)) {
context.jars.add(new GradleJar(gradleJarPath, null, gradleLibrary));
}
}
}
/**
@@ -256,7 +276,6 @@ public class GradleLocalNodeManageHelper {
}
});
}
GradleUtil.refreshProject(myProjectStructureHelper.getProject());
}
public void removeNodes(@NotNull Collection<GradleProjectStructureNode<?>> nodes) {
@@ -283,7 +302,9 @@ public class GradleLocalNodeManageHelper {
for (GradleProjectStructureNode<?> node : nodes) {
GradleProjectStructureNodeDescriptor<? extends GradleEntityId> descriptor = node.getDescriptor();
if (descriptor.getAttributes() != GradleTextAttributes.INTELLIJ_LOCAL_CHANGE) {
if (descriptor.getAttributes() == GradleTextAttributes.GRADLE_LOCAL_CHANGE
|| descriptor.getElement().getType() == GradleEntityType.SYNTHETIC
|| node.getParent() == null /* is root */) {
continue;
}
Object entity = myIdMapper.mapIdToEntity(descriptor.getElement());
@@ -300,7 +321,6 @@ public class GradleLocalNodeManageHelper {
myModuleDependencyManager.removeDependencies(dependencies);
myModuleManager.removeModules(modules);
myLibraryManager.removeLibraries(libraries);
GradleUtil.refreshProject(myProjectStructureHelper.getProject());
}
private class Context {
@@ -32,6 +32,7 @@ import org.jetbrains.plugins.gradle.config.GradleSettings;
import org.jetbrains.plugins.gradle.model.gradle.GradleLibrary;
import org.jetbrains.plugins.gradle.model.gradle.GradleModule;
import org.jetbrains.plugins.gradle.model.gradle.GradleProject;
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesModel;
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureHelper;
import org.jetbrains.plugins.gradle.task.GradleResolveProjectTask;
import org.jetbrains.plugins.gradle.util.GradleBundle;
@@ -240,6 +241,9 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder<GradleProje
assert intellijModule != null;
myDependencyManager.importDependencies(module.getDependencies(), intellijModule);
}
GradleProjectStructureChangesModel changesModel = project.getComponent(GradleProjectStructureChangesModel.class);
changesModel.update(projectWithResolvedLibraries);
}
});
}
@@ -155,7 +155,7 @@ public class GradleProjectStructureChangesDetector extends AbstractProjectCompon
// There is a possible case that we need to add/remove IJ-specific new nodes because of the IJ project structure changes.
rebuildTreeModel();
GradleUtil.refreshProject(myProject);
//GradleUtil.refreshProject(myProject);
}
});
}
@@ -63,8 +63,7 @@ public class GradleProjectStructureChangesModel extends AbstractProjectComponent
*/
public void update(@NotNull GradleProject gradleProject) {
myGradleProject.set(gradleProject);
GradleChangesCalculationContext context = new GradleChangesCalculationContext(myChanges.get(), myPlatformFacade);
myChangesCalculator.calculate(gradleProject, myProject, context);
GradleChangesCalculationContext context = getCurrentChangesContext(gradleProject);
if (!context.hasNewChanges()) {
return;
}
@@ -93,6 +92,13 @@ public class GradleProjectStructureChangesModel extends AbstractProjectComponent
return myListeners.add(listener);
}
@NotNull
public GradleChangesCalculationContext getCurrentChangesContext(@NotNull GradleProject gradleProject) {
GradleChangesCalculationContext context = new GradleChangesCalculationContext(myChanges.get(), myPlatformFacade);
myChangesCalculator.calculate(gradleProject, myProject, context);
return context;
}
/**
* @return collection of project structure changes registered within the current model
*/
@@ -17,10 +17,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.plugins.gradle.config.GradleTextAttributes;
import org.jetbrains.plugins.gradle.config.PlatformFacade;
import org.jetbrains.plugins.gradle.diff.GradleAbstractConflictingPropertyChange;
import org.jetbrains.plugins.gradle.diff.GradleAbstractEntityPresenceChange;
import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChange;
import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChangeVisitor;
import org.jetbrains.plugins.gradle.diff.*;
import org.jetbrains.plugins.gradle.diff.contentroot.GradleContentRootPresenceChange;
import org.jetbrains.plugins.gradle.diff.dependency.GradleDependencyExportedChange;
import org.jetbrains.plugins.gradle.diff.dependency.GradleDependencyScopeChange;
@@ -33,6 +30,7 @@ import org.jetbrains.plugins.gradle.diff.project.GradleProjectRenameChange;
import org.jetbrains.plugins.gradle.model.GradleEntityOwner;
import org.jetbrains.plugins.gradle.model.gradle.GradleLibrary;
import org.jetbrains.plugins.gradle.model.gradle.GradleModule;
import org.jetbrains.plugins.gradle.model.gradle.GradleProject;
import org.jetbrains.plugins.gradle.model.gradle.LibraryPathType;
import org.jetbrains.plugins.gradle.model.id.*;
import org.jetbrains.plugins.gradle.model.intellij.ModuleAwareContentRoot;
@@ -110,27 +108,7 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
public void onChanges(@NotNull final Collection<GradleProjectStructureChange> oldChanges,
@NotNull final Collection<GradleProjectStructureChange> currentChanges)
{
final Runnable task = new Runnable() {
@Override
public void run() {
List<GradleProjectStructureChange> currentChangesToUse = ContainerUtilRt.newArrayList(currentChanges);
Collection<GradleProjectStructureChange> obsoleteChangesToUse = ContainerUtil.subtract(oldChanges, currentChanges);
if (myChangesComparator != null) {
List<GradleProjectStructureChange> toSort = ContainerUtilRt.newArrayList(obsoleteChangesToUse);
Collections.sort(toSort, myChangesComparator);
obsoleteChangesToUse = toSort;
Collections.sort(currentChangesToUse, myChangesComparator);
}
processObsoleteChanges(obsoleteChangesToUse);
processCurrentChanges(currentChangesToUse);
}
};
if (myProcessChangesAtTheSameThread) {
task.run();
}
else {
UIUtil.invokeLaterIfNeeded(task);
}
processChanges(oldChanges, currentChanges);
}
});
@@ -138,6 +116,39 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
rebuild();
}
}
private void processChanges(@NotNull final Collection<GradleProjectStructureChange> oldChanges,
@NotNull final Collection<GradleProjectStructureChange> currentChanges)
{
final Runnable task = new Runnable() {
@Override
public void run() {
Collection<GradleProjectStructureChange> obsoleteChangesToUse = ContainerUtil.subtract(oldChanges, currentChanges);
Collection<GradleProjectStructureChange> currentChangesToUse = currentChanges;
if (myChangesComparator != null) {
obsoleteChangesToUse = sort(obsoleteChangesToUse, myChangesComparator);
currentChangesToUse = sort(currentChangesToUse, myChangesComparator);
}
processObsoleteChanges(obsoleteChangesToUse);
processCurrentChanges(currentChangesToUse);
}
};
if (myProcessChangesAtTheSameThread) {
task.run();
}
else {
UIUtil.invokeLaterIfNeeded(task);
}
}
@NotNull
private static Collection<GradleProjectStructureChange> sort(@NotNull Collection<GradleProjectStructureChange> changes,
@NotNull Comparator<GradleProjectStructureChange> myChangesComparator)
{
List<GradleProjectStructureChange> toSort = ContainerUtilRt.newArrayList(changes);
Collections.sort(toSort, myChangesComparator);
return toSort;
}
@SuppressWarnings("unchecked")
@Override
@@ -209,8 +220,13 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
}
}
}
processCurrentChanges(myChangesModel.getChanges());
filterNodes(root);
GradleProject project = myChangesModel.getGradleProject();
if (project != null) {
GradleChangesCalculationContext context = myChangesModel.getCurrentChangesContext(project);
processChanges(context.getKnownChanges(), context.getCurrentChanges());
filterNodes(root);
}
}
private void populateLibraryDependencyNode(@NotNull GradleProjectStructureNode<GradleLibraryDependencyId> node,
@@ -470,18 +486,56 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
private void processNewLibraryDependencyPresenceChange(@NotNull GradleLibraryDependencyPresenceChange change) {
GradleProjectStructureNode<GradleLibraryDependencyId> dependencyNode = processNewDependencyPresenceChange(change);
GradleLibraryDependencyId id = change.getGradleEntity();
if (dependencyNode != null && id != null) {
GradleLibrary library = myProjectStructureHelper.findGradleLibrary(id.getLibraryId());
if (library != null) {
GradleLibraryId libraryId = dependencyNode.getDescriptor().getElement().getLibraryId();
for (String path : library.getPaths(LibraryPathType.BINARY)) {
GradleJarId jarId = new GradleJarId(path, libraryId);
GradleProjectStructureNode<GradleJarId> jarNode = buildNode(jarId, GradleUtil.extractNameFromPath(jarId.getPath()));
jarNode.setAttributes(GradleTextAttributes.GRADLE_LOCAL_CHANGE);
jarNode.getDescriptor().setToolTip(jarId.getPath());
dependencyNode.add(jarNode);
if (dependencyNode == null || id == null) {
return;
}
GradleLibrary gradleLibrary = myProjectStructureHelper.findGradleLibrary(id.getLibraryId());
if (gradleLibrary == null) {
return;
}
Map<GradleJarId, GradleProjectStructureNode<GradleJarId>> existingJarNodes = ContainerUtilRt.newHashMap();
for (GradleProjectStructureNode<GradleJarId> jarNode : dependencyNode.getChildren(GradleJarId.class)) {
existingJarNodes.put(jarNode.getDescriptor().getElement(), jarNode);
}
Map<GradleJarId, GradleProjectStructureNode<GradleJarId>> gradleJarIds = ContainerUtilRt.newHashMap();
GradleLibraryId libraryId = dependencyNode.getDescriptor().getElement().getLibraryId();
for (String path : gradleLibrary.getPaths(LibraryPathType.BINARY)) {
GradleJarId jarId = new GradleJarId(path, libraryId);
GradleProjectStructureNode<GradleJarId> jarNode = existingJarNodes.get(jarId);
if (jarNode == null) {
jarNode = buildNode(jarId, GradleUtil.extractNameFromPath(jarId.getPath()));
jarNode.setAttributes(GradleTextAttributes.NO_CHANGE);
jarNode.getDescriptor().setToolTip(jarId.getPath());
dependencyNode.add(jarNode);
}
gradleJarIds.put(jarId, jarNode);
}
Library intellijLibrary = myProjectStructureHelper.findIntellijLibrary(gradleLibrary);
if (intellijLibrary == null) {
for (GradleProjectStructureNode<?> jarNode : dependencyNode) {
jarNode.setAttributes(GradleTextAttributes.GRADLE_LOCAL_CHANGE);
}
}
else {
Set<GradleJarId> intellijJarIds = ContainerUtilRt.newHashSet();
for (VirtualFile jarFile : intellijLibrary.getFiles(OrderRootType.CLASSES)) {
GradleJarId jarId = new GradleJarId(GradleUtil.getLocalFileSystemPath(jarFile), libraryId);
if (gradleJarIds.remove(jarId) == null) {
intellijJarIds.add(jarId);
}
}
for (GradleProjectStructureNode<GradleJarId> jarNode : gradleJarIds.values()) {
jarNode.setAttributes(GradleTextAttributes.GRADLE_LOCAL_CHANGE);
}
for (GradleJarId jarId : intellijJarIds) {
GradleProjectStructureNode<GradleJarId> jarNode = buildNode(jarId, GradleUtil.extractNameFromPath(jarId.getPath()));
jarNode.setAttributes(GradleTextAttributes.INTELLIJ_LOCAL_CHANGE);
jarNode.getDescriptor().setToolTip(jarId.getPath());
dependencyNode.add(jarNode);
}
}
}
@@ -227,7 +227,8 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest {
dependencies {
lib1('gradle') {
jar1('gradle')
jar2('gradle')} } }
jar2()
jar3('intellij')} } }
module1 {
dependencies {
lib1 {
@@ -346,51 +347,6 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest {
} }
}
@Test
public void "gradle local library dependency outweighs library path conflict"() {
init(
gradle: {
project {
module('module1') {
dependencies {
library('lib1', bin: ['jar1']) } }
module('module2') {
dependencies {
library('lib1') } } } },
intellij: {
project {
module('module1') {
dependencies {
library('lib1', bin: ['jar2']) } } } },
changesSorter: changeByClassSorter([
(GradleModulePresenceChange) : 1,
(GradleLibraryDependencyPresenceChange) : 2,
(GradleJarPresenceChange) : 3,
])
)
checkChanges {
presence {
module(gradle: gradle.modules['module2'])
jar(gradle: [findJarId('jar1')])
jar(intellij: [findJarId('jar2')])
libraryDependency(gradle: gradle.libraryDependencies[gradle.modules['module2']].first())
}
}
checkTree {
project {
module2('gradle') {
dependencies {
lib1('gradle') {
jar1('gradle') } } }
module1() {
dependencies {
lib1 {
jar1('gradle')
jar2('intellij') } } } } }
}
@Test
public void "mismatched module dependency import"() {
init(
@@ -789,7 +745,7 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest {
module('module1')
module('module2') {
dependencies {
library('lib1', bin: ['1'])
library('lib1', bin: ['jar1'])
module('module1', scope: 'compile')
} } } }
init(gradle: gradleProject, intellij: {
@@ -797,7 +753,7 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest {
module('module1')
module('module2') {
dependencies {
library('lib1', bin: ['2'])
library('lib1', bin: ['jar2'])
module('module1', scope: 'test')
} } } })
@@ -814,4 +770,88 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest {
project {
} }
}
@Test
public void "gradle-local library dependency with mixed jars state"() {
init(
gradle: {
project {
module('module1') {
dependencies {
library('lib1', bin: ['jar1', 'jar2']) } }
module('module2') {
dependencies {
library('lib1', bin: ['jar1', 'jar2'])} } } },
intellij: {
project {
module('module1') {
dependencies {
library('lib1', bin: ['jar2', 'jar3']) }}
module('module2') }}
)
checkChanges {
presence {
libraryDependency(gradle: gradle.modules['module2'].dependencies)
jar(gradle: [findJarId('jar1')])
jar(intellij: [findJarId('jar3')])
}
}
checkTree {
project {
module1 {
dependencies {
lib1 {
jar1('gradle')
jar2()
jar3('intellij')} } }
module2 {
dependencies {
lib1('gradle') {
jar1('gradle')
jar2()
jar3('intellij') } } } } }
}
@Test
public void "intellij-local library dependency with mixed jars state"() {
init(
gradle: {
project {
module('module1') {
dependencies {
library('lib1', bin: ['jar1', 'jar2']) } }
module('module2')} },
intellij: {
project {
module('module1') {
dependencies {
library('lib1', bin: ['jar2', 'jar3']) }}
module('module2') {
dependencies {
library('lib1', bin: ['jar1', 'jar2'])}}}}
)
checkChanges {
presence {
libraryDependency(intellij: intellij.libraryDependencies[intellij.modules['module2']])
jar(gradle: [findJarId('jar1')])
jar(intellij: [findJarId('jar3')])
}
}
checkTree {
project {
module1 {
dependencies {
lib1 {
jar1('gradle')
jar2()
jar3('intellij')} } }
module2 {
dependencies {
lib1('intellij') {
jar1('gradle')
jar2()
jar3('intellij') } } } } }
}
}
@@ -43,7 +43,7 @@ public abstract class AbstractGradleTest {
GradleProjectStructureTreeModel treeModel
GradleProjectBuilder gradle
IntellijProjectBuilder intellij
def changesBuilder
ChangeBuilder changesBuilder
ProjectStructureChecker treeChecker
def container
private Map<TextAttributesKey, GradleProjectStructureNodeFilter> treeFilters = [:]
@@ -128,7 +128,7 @@ public abstract class AbstractTableView<T> extends JPanel implements TypeSafeDat
final ActionManager actionManager = ActionManager.getInstance();
final ToolbarPosition position = getToolbarPosition();
final ActionToolbar myActionToolbar = actionManager.createActionToolbar(ActionPlaces.PROJECT_VIEW_TOOLBAR, actionGroup, position == ToolbarPosition.TOP || position == ToolbarPosition.BOTTOM);
myActionToolbar.setTargetComponent(myTable);
myActionToolbar.setTargetComponent(myInnerPanel);
final JComponent toolbarComponent = myActionToolbar.getComponent();
final MatteBorder matteBorder = BorderFactory.createMatteBorder(0, 0, position == ToolbarPosition.TOP ? 1 : 0, 0, JBColor.DARK_GRAY);
toolbarComponent.setBorder(BorderFactory.createCompoundBorder(matteBorder, toolbarComponent.getBorder()));
@@ -167,7 +167,9 @@ public class DomCollectionControl<T extends DomElement> extends DomUIControl imp
}
protected DefaultActionGroup createPopupActionGroup() {
return (DefaultActionGroup)ActionManager.getInstance().getAction("DomCollectionControl");
final DefaultActionGroup group = new DefaultActionGroup();
group.addAll((DefaultActionGroup)ActionManager.getInstance().getAction("DomCollectionControl"));
return group;
}
protected ColumnInfo[] createColumnInfos(DomElement parent) {
@@ -275,7 +275,7 @@ public class DefaultXmlExtension extends XmlExtension {
final Collection<VirtualFile> files = XmlTagNamesIndex.getFilesByTagName(tagName, project);
final Set<String> possibleUris = new LinkedHashSet<String>(files.size());
for (VirtualFile virtualFile : files) {
final String namespace = XmlNamespaceIndex.getNamespace(virtualFile, project);
final String namespace = XmlNamespaceIndex.getNamespace(virtualFile, project, file);
if (namespace != null) {
possibleUris.add(namespace);
}
@@ -63,13 +63,13 @@ public class SchemaDefinitionsSearch implements QueryExecutor<PsiElement, PsiEle
});
if (infos != null && ! infos.isEmpty()) {
final Project project = XmlUtil.getContainingFile(xml).getProject();
XmlFile file = XmlUtil.getContainingFile(xml);
final Project project = file.getProject();
final Module module = ModuleUtil.findModuleForPsiElement(queryParameters);
//if (module == null) return false;
final XmlFile file = XmlUtil.getContainingFile(xml);
final VirtualFile vf = file.getVirtualFile();
String thisNs = XmlNamespaceIndex.getNamespace(vf, project);
String thisNs = XmlNamespaceIndex.getNamespace(vf, project, file);
thisNs = thisNs == null ? getDefaultNs(file) : thisNs;
// so thisNs can be null
if (thisNs == null) return false;
@@ -45,8 +45,8 @@ import java.util.*;
public class XmlNamespaceIndex extends XmlIndex<XsdNamespaceBuilder> {
@Nullable
public static String getNamespace(@NotNull VirtualFile file, final Project project) {
if (DumbService.isDumb(project)) {
public static String getNamespace(@NotNull VirtualFile file, final Project project, PsiFile context) {
if (DumbService.isDumb(project) || (context != null && XmlUtil.isStubBuilding(context))) {
try {
return XsdNamespaceBuilder.computeNamespace(file.getInputStream());
}