mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
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;
|
||||
|
||||
|
||||
+81
@@ -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();
|
||||
}
|
||||
}
|
||||
+6
-44
@@ -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();
|
||||
}
|
||||
|
||||
+1
-1
@@ -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();
|
||||
|
||||
+3
-3
@@ -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
-1
@@ -1,3 +1,3 @@
|
||||
public class Foo {
|
||||
Object foo(boolean <caret>){ }
|
||||
Object foo(boolean<caret>){ }
|
||||
}
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+23
@@ -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 {}
|
||||
+25
@@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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()));
|
||||
|
||||
+4
@@ -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) {
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Remember passwords &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">
|
||||
|
||||
+5
-5
@@ -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);
|
||||
}
|
||||
|
||||
+13
-3
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+29
-9
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+8
-2
@@ -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
|
||||
*/
|
||||
|
||||
+91
-37
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+88
-48
@@ -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') } } } } }
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user