Merge remote-tracking branch 'origin/master'

This commit is contained in:
irengrig
2015-10-22 14:04:18 +02:00
54 changed files with 928 additions and 383 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -56,7 +56,7 @@ public interface DebugProcess {
/**
* The usual place to call this method is vmAttachedEvent. No additional actions are needed in this case.
* If position manager is appended later, when DebugSession is up and running, one might need to call BreakpointManager.updateAllRequests()
* to ensure that just adedd position manager was considered when creating breakpoint requests
* to ensure that just added position manager was considered when creating breakpoint requests
* @param positionManager to be appended
*/
void appendPositionManager(PositionManager positionManager);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -27,16 +27,16 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
class ConvertReturnStatementsVisitor implements ReturnStatementsVisitor {
private final PsiElementFactory myFactory;
private final PsiMethod myMethod;
private final DeclarationSearcher mySearcher;
@NotNull private final PsiElementFactory myFactory;
@NotNull private final PsiMethod myMethod;
@NotNull private final DeclarationSearcher mySearcher;
@NotNull private final String myDefaultValue;
private PsiReturnStatement myLatestReturn;
private final String myDefaultValue;
public ConvertReturnStatementsVisitor(final PsiElementFactory factory, final PsiMethod method, final PsiType targetType) {
ConvertReturnStatementsVisitor(@NotNull PsiElementFactory factory, @NotNull PsiMethod method, @NotNull PsiType targetType) {
myFactory = factory;
myMethod = method;
mySearcher = new DeclarationSearcher(myMethod, targetType);
mySearcher = new DeclarationSearcher(method, targetType);
myDefaultValue = PsiTypesUtil.getDefaultValueOfType(targetType);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -22,17 +22,15 @@ import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
public class DeclarationSearcher {
class DeclarationSearcher {
private final PsiMethod myMethod;
private final PsiType myTargetType;
private final Map<PsiElement, PsiVariable> cache;
private final Map<PsiElement, PsiVariable> cache = new HashMap<PsiElement, PsiVariable>();
public DeclarationSearcher(final PsiMethod method, final PsiType targetType) {
DeclarationSearcher(@NotNull PsiMethod method, @NotNull PsiType targetType) {
myMethod = method;
myTargetType = targetType;
cache = new HashMap<PsiElement, PsiVariable>();
}
@Nullable
@@ -57,6 +55,7 @@ public class DeclarationSearcher {
@Nullable
private PsiVariable getLocalDeclaration(@NotNull PsiElement endPositionElement) {
final PsiElement parent = endPositionElement.getParent();
if (parent == null) return null;
// reuse of cache is possible IF requests are done up-to-down. otherwise - not first declaration can be returned
final PsiVariable cachedCandidate = cache.get(parent);
@@ -145,15 +145,15 @@ public class MethodReturnTypeFix extends LocalQuickFixAndIntentionActionOnPsiEle
// to clearly separate data
private static class ReturnStatementAdder {
private final PsiElementFactory factory;
private final PsiType myTargetType;
@NotNull private final PsiElementFactory factory;
@NotNull private final PsiType myTargetType;
private ReturnStatementAdder(@NotNull final PsiElementFactory factory, @NotNull final PsiType targetType) {
this.factory = factory;
myTargetType = targetType;
}
public PsiReturnStatement addReturnForMethod(final PsiFile file, final PsiMethod method) {
private PsiReturnStatement addReturnForMethod(final PsiFile file, final PsiMethod method) {
final PsiModifierList modifiers = method.getModifierList();
if (modifiers.hasModifierProperty(PsiModifier.ABSTRACT) || method.getBody() == null) {
return null;
@@ -170,7 +170,7 @@ public class MethodReturnTypeFix extends LocalQuickFixAndIntentionActionOnPsiEle
return null; //must be an error
}
PsiReturnStatement returnStatement;
if (controlFlow != null && ControlFlowUtil.processReturns(controlFlow, visitor)) {
if (ControlFlowUtil.processReturns(controlFlow, visitor)) {
// extra return statement not needed
// get latest modified return statement and select...
returnStatement = visitor.getLatestReturn();
@@ -233,12 +233,19 @@ public class TypeEvaluator {
}
}
}
else if (expr instanceof PsiFunctionalExpression) {
final PsiType functionalInterfaceType = ((PsiFunctionalExpression)expr).getFunctionalInterfaceType();
if (functionalInterfaceType != null) {
return functionalInterfaceType;
}
}
else if (expr instanceof PsiReferenceExpression) {
final PsiType type = evaluateReferenceExpressionType(expr);
if (type != null) {
return PsiImplUtil.normalizeWildcardTypeByPosition(type, expr);
}
} else if (expr instanceof PsiSuperExpression) {
}
else if (expr instanceof PsiSuperExpression) {
final PsiClass psiClass = PsiTreeUtil.getParentOfType(expr, PsiClass.class);
if (psiClass != null) {
final PsiClass superClass = psiClass.getSuperClass();
@@ -19,6 +19,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiSubstitutorImpl;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.InheritanceUtil;
@@ -26,6 +27,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
@@ -525,9 +527,12 @@ class TypeMigrationStatementProcessor extends JavaRecursiveElementVisitor {
public TypeView(PsiVariable var, PsiSubstitutor varSubstitutor, PsiSubstitutor evalSubstitutor) {
myOriginType = varSubstitutor != null ? varSubstitutor.substitute(var.getType()) : var.getType();
myType = evalSubstitutor != null
? evalSubstitutor.substitute(myTypeEvaluator.getType(var))
: myTypeEvaluator.getType(var);
Map<PsiTypeParameter, PsiType> realMap = new HashMap<PsiTypeParameter, PsiType>();
if (varSubstitutor != null) realMap.putAll(varSubstitutor.getSubstitutionMap());
if (evalSubstitutor != null) realMap.putAll(evalSubstitutor.getSubstitutionMap());
myType = PsiSubstitutorImpl.createSubstitutor(realMap).substitute(myTypeEvaluator.getType(var));
myChanged = (myOriginType == null || myType == null) ? false : !myType.equals(myOriginType);
}
@@ -319,7 +319,9 @@ class SliceUtil {
PsiExpression rExpression = ((PsiAssignmentExpression)parentExpr).getRExpression();
PsiType rtype = rExpression.getType();
PsiType ftype = field.getType();
if (TypeConversionUtil.isAssignable(parentSubstitutor.substitute(ftype), parentSubstitutor.substitute(rtype))) {
PsiType subFType = parentSubstitutor.substitute(ftype);
PsiType subRType = parentSubstitutor.substitute(rtype);
if (subFType != null && subRType != null && TypeConversionUtil.isAssignable(subFType, subRType)) {
return handToProcessor(rExpression, processor, parent, parentSubstitutor, parent.indexNesting, "");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -57,6 +57,7 @@ public class PsiTypesUtil {
private PsiTypesUtil() { }
@NotNull
public static String getDefaultValueOfType(PsiType type) {
if (type instanceof PsiArrayType) {
int count = type.getArrayDimensions() - 1;
@@ -79,17 +80,10 @@ public class PsiTypesUtil {
}
return buffer.toString();
}
else if (type instanceof PsiPrimitiveType) {
if (PsiType.BOOLEAN.equals(type)) {
return PsiKeyword.FALSE;
}
else {
return "0";
}
}
else {
return PsiKeyword.NULL;
if (type instanceof PsiPrimitiveType) {
return PsiType.BOOLEAN.equals(type) ? PsiKeyword.FALSE : "0";
}
return PsiKeyword.NULL;
}
/**
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>testSimple_0.iml</file>
<file>testSimple.iml</file>
<problem_class>Unused library</problem_class>
<description>Unused library 'JUnit'</description>
</problem>
@@ -40,6 +40,7 @@ import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
@@ -544,8 +545,16 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
String fullPath = getTestDataPath() + filePath;
allowRootAccess(fullPath);
final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
String vfsPath = FileUtil.toSystemIndependentName(fullPath);
VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(vfsPath);
assertNotNull("file " + fullPath + " not found", vFile);
String realVfsPath = vFile.getPath();
if (!SystemInfo.isFileSystemCaseSensitive && !vfsPath.equals(realVfsPath) &&
vfsPath.equalsIgnoreCase(realVfsPath)) {
fail("Please correct case-sensitivity of path to prevent test failure on case-sensitive file systems:\n" +
" path " + vfsPath + "\n" +
"real path " + realVfsPath);
}
return vFile;
}
@@ -13,6 +13,7 @@
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaFunctionConversionRule"/>
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaPredicateConversionRule"/>
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaSupplierConversionRule"/>
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.IterableStreamConversionRule"/>
<intentionAction>
<className>com.intellij.refactoring.typeMigration.intentions.ConvertFieldToAtomicIntention</className>
<category>Java/Concurrency</category>
@@ -57,6 +57,12 @@ public abstract class BaseGuavaTypeConversionRule extends TypeConversionRule {
return null;
};
@Nullable
protected TypeConversionDescriptorBase findConversionForVariableReference(@NotNull PsiReferenceExpression referenceExpression,
@NotNull PsiVariable psiVariable) {
return null;
}
@NotNull
public abstract String ruleFromClass();
@@ -70,7 +76,7 @@ public abstract class BaseGuavaTypeConversionRule extends TypeConversionRule {
PsiMember member,
PsiExpression context,
TypeMigrationLabeler labeler) {
if (from != null && to != null && !canConvert(from, to)) {
if (from != null && to != null && !canConvert(from, to, ruleFromClass(), ruleToClass())) {
return null;
}
if (member instanceof PsiMethod) {
@@ -92,10 +98,19 @@ public abstract class BaseGuavaTypeConversionRule extends TypeConversionRule {
};
}
}
else if (context instanceof PsiReferenceExpression) {
final PsiElement resolvedElement = ((PsiReferenceExpression)context).resolve();
if (resolvedElement instanceof PsiVariable) {
return findConversionForVariableReference((PsiReferenceExpression)context, (PsiVariable)resolvedElement);
}
}
return null;
}
private boolean canConvert(PsiType from, PsiType to) {
public static boolean canConvert(@Nullable PsiType from,
@Nullable PsiType to,
@NotNull String fromClassName,
@NotNull String toClassName) {
if (!(from instanceof PsiClassType)) {
return false;
}
@@ -108,13 +123,13 @@ public abstract class BaseGuavaTypeConversionRule extends TypeConversionRule {
if (fromClass instanceof PsiAnonymousClass) {
fromClass = ((PsiAnonymousClass)fromClass).getBaseClassType().resolve();
}
if (fromClass == null || !ruleFromClass().equals(fromClass.getQualifiedName())) {
if (fromClass == null || !fromClassName.equals(fromClass.getQualifiedName())) {
return false;
}
final PsiClassType.ClassResolveResult toResolveResult = ((PsiClassType)to).resolveGenerics();
final PsiClass toClass = toResolveResult.getElement();
if (toClass == null || !ruleToClass().equals(toClass.getQualifiedName())) {
if (toClass == null || !toClassName.equals(toClass.getQualifiedName())) {
return false;
}
@@ -45,8 +45,9 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
public static final Set<String> CHAIN_HEAD_METHODS = ContainerUtil.newHashSet("from", "of");
public static final String FLUENT_ITERABLE = "com.google.common.collect.FluentIterable";
public static final String STREAM_COLLECT_TO_LIST = "$it$.collect(java.util.stream.Collectors.toList())";
private static class TypeConversionDescriptorFactory {
static class TypeConversionDescriptorFactory {
private final String myStringToReplace;
private final String myReplaceByString;
private final boolean myWithLambdaParameter;
@@ -91,19 +92,18 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
DESCRIPTORS_MAP.put("isEmpty", new TypeConversionDescriptorFactory("$q$.isEmpty()", "$q$.findAny().isPresent()", false));
DESCRIPTORS_MAP.put("skip", new TypeConversionDescriptorFactory("$q$.skip($p$)", "$q$.skip($p$)", false, true, true));
DESCRIPTORS_MAP.put("limit", new TypeConversionDescriptorFactory("$q$.limit($p$)", "$q$.limit($p$)", false, true, true));
DESCRIPTORS_MAP.put("first", new TypeConversionDescriptorFactory("$q$.first()", "$q$.findFirst()", false));
DESCRIPTORS_MAP.put("first", new TypeConversionDescriptorFactory("$q$.first()", "$q$.findFirst()", false, true, false));
DESCRIPTORS_MAP.put("transform", new TypeConversionDescriptorFactory("$q$.transform($params$)", "$q$.map($params$)", true, true, true));
DESCRIPTORS_MAP.put("allMatch", new TypeConversionDescriptorFactory("$it$.allMatch($c$)", "$it$." + StreamApiConstants.ALL_MATCH + "($c$)", true));
DESCRIPTORS_MAP.put("anyMatch", new TypeConversionDescriptorFactory("$it$.anyMatch($c$)", "$it$." + StreamApiConstants.ANY_MATCH + "($c$)", true));
DESCRIPTORS_MAP.put("first", new TypeConversionDescriptorFactory("$it$.first()", "$it$." + StreamApiConstants.FIND_FIRST + "()", false));
DESCRIPTORS_MAP.put("firstMatch", new TypeConversionDescriptorFactory("$it$.firstMatch($p$)", "$it$.filter($p$).findFirst()", true, true, false));
DESCRIPTORS_MAP.put("size", new TypeConversionDescriptorFactory("$it$.size()", "(int) $it$.count()", false));
DESCRIPTORS_MAP.put("toMap", new TypeConversionDescriptorFactory("$it$.toMap($f$)",
"$it$.collect(java.util.stream.Collectors.toMap(java.util.function.Function.identity(), $f$))", true));
DESCRIPTORS_MAP.put("toList", new TypeConversionDescriptorFactory("$it$.toList()", "$it$.collect(java.util.stream.Collectors.toList())", false));
DESCRIPTORS_MAP.put("toList", new TypeConversionDescriptorFactory("$it$.toList()", STREAM_COLLECT_TO_LIST, false));
DESCRIPTORS_MAP.put("toSet", new TypeConversionDescriptorFactory("$it$.toSet()", "$it$.collect(java.util.stream.Collectors.toSet())", false));
DESCRIPTORS_MAP.put("toSortedList", new TypeConversionDescriptorFactory("$it$.toSortedList($c$)", "$it$.sorted($c$).collect(java.util.stream.Collectors.toList())", false));
DESCRIPTORS_MAP.put("toSortedSet", new TypeConversionDescriptorFactory("$it$.toSortedSet($c$)", "$it$.sorted($c$).collect(java.util.stream.Collectors.toSet())", false));
@@ -15,8 +15,12 @@
*/
package com.intellij.refactoring.typeMigration.rules.guava;
import com.intellij.psi.PsiReferenceExpression;
import com.intellij.psi.PsiVariable;
import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
@@ -31,6 +35,13 @@ public class GuavaFunctionConversionRule extends BaseGuavaTypeConversionRule {
descriptorsMap.put("apply", new FunctionalInterfaceTypeConversionDescriptor("apply", "apply"));
}
@Nullable
@Override
protected TypeConversionDescriptorBase findConversionForVariableReference(@NotNull PsiReferenceExpression referenceExpression,
@NotNull PsiVariable psiVariable) {
return new TypeConversionDescriptor("$f$", "$f$::apply");
}
@NotNull
@Override
public String ruleFromClass() {
@@ -88,6 +88,13 @@ public class GuavaOptionalConversionRule extends BaseGuavaTypeConversionRule {
return GuavaFluentIterableConversionRule.buildCompoundDescriptor((PsiMethodCallExpression) context, to, labeler);
}
@Nullable
@Override
protected TypeConversionDescriptorBase findConversionForVariableReference(@NotNull PsiReferenceExpression referenceExpression,
@NotNull PsiVariable psiVariable) {
return new TypeConversionDescriptor("$o$", "$o$::get");
}
private PsiClass getParameterClass(PsiMethod method) {
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length != 1) {
@@ -15,8 +15,12 @@
*/
package com.intellij.refactoring.typeMigration.rules.guava;
import com.intellij.psi.PsiReferenceExpression;
import com.intellij.psi.PsiVariable;
import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
@@ -32,6 +36,13 @@ public class GuavaPredicateConversionRule extends BaseGuavaTypeConversionRule {
descriptorsMap.put("apply", new FunctionalInterfaceTypeConversionDescriptor("apply", "test"));
}
@Nullable
@Override
protected TypeConversionDescriptorBase findConversionForVariableReference(@NotNull PsiReferenceExpression referenceExpression,
@NotNull PsiVariable psiVariable) {
return new TypeConversionDescriptor("$p$", "$p$::test");
}
@NotNull
@Override
public String ruleFromClass() {
@@ -0,0 +1,52 @@
/*
* Copyright 2000-2015 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.refactoring.typeMigration.rules.guava;
import com.intellij.codeInspection.java18StreamApi.StreamApiConstants;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
import com.intellij.refactoring.typeMigration.rules.TypeConversionRule;
import org.jetbrains.annotations.Nullable;
/**
* @author Dmitry Batkovich
*/
public class IterableStreamConversionRule extends TypeConversionRule {
@Nullable
@Override
public TypeConversionDescriptorBase findConversion(PsiType from,
PsiType to,
PsiMember member,
PsiExpression context,
TypeMigrationLabeler labeler) {
if (BaseGuavaTypeConversionRule
.canConvert(from, to, CommonClassNames.JAVA_LANG_ITERABLE, StreamApiConstants.JAVA_UTIL_STREAM_STREAM)) {
if (context instanceof PsiReferenceExpression) {
final PsiElement resolved = ((PsiReferenceExpression)context).resolve();
if (resolved instanceof PsiVariable) {
final PsiClass aClass = PsiTypesUtil.getPsiClass(((PsiVariable)resolved).getType());
if (aClass != null && GuavaFluentIterableConversionRule.FLUENT_ITERABLE.equals(aClass.getQualifiedName())) {
return new TypeConversionDescriptor("$it$", GuavaFluentIterableConversionRule.STREAM_COLLECT_TO_LIST);
}
}
}
}
return null;
}
}
@@ -154,6 +154,22 @@ public class GuavaInspectionTest extends JavaCodeInsightFixtureTestCase {
doTest();
}
public void testConvertFluentIterableAsIterableParameter() {
doTest();
}
public void testConvertFunctionAsParameter() {
doTest();
}
public void testFluentIterableMigrationInInheritance() {
doTest();
}
public void testFluentIterableAndOptional() {
doTest();
}
private void doTestNoQuickFixes(final Class<? extends IntentionAction>... quickFixesClasses) {
myFixture.configureByFile(getTestName(true) + ".java");
myFixture.enableInspections(new GuavaInspection());
@@ -0,0 +1,13 @@
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Iterables;
import java.util.ArrayList;
public class Main16 {
void m() {
FluentIterable<String> it = FluentIterable<caret>.from(new ArrayList<String>()).transform(s -> s);
//read-only method with Iterable<A> parameter
Iterables.cycle(it);
}
}
@@ -0,0 +1,14 @@
import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main16 {
void m() {
Stream<String> it = new ArrayList<String>().stream().map(s -> s);
//read-only method with Iterable<A> parameter
Iterables.cycle(it.collect(Collectors.toList()));
}
}
@@ -0,0 +1,15 @@
import com.google.common.base.Function;
import com.google.common.base.Functions;
public class Main16 {
void m() {
Function<String, String> <caret>f = new Function<String, String>() {
@Override
public String apply(String s) {
return s.substring(12) + "12";
}
};
Functions.compose(f, f);
}
}
@@ -0,0 +1,11 @@
import com.google.common.base.Functions;
import java.util.function.Function;
public class Main16 {
void m() {
Function<String, String> f = s -> s.substring(12) + "12";
Functions.compose(f::apply, f::apply);
}
}
@@ -0,0 +1,25 @@
import com.google.common.base.Optional;
import com.google.common.collect.FluentIterable;
import java.util.ArrayList;
public class Main18 {
class A {
private String i = "12";
Optional<String> getOpt() {
return Optional.fromNullable(i);
}
}
class B {
FluentIt<caret>erable<String> getFIterable() {
return FluentIterable.from(new ArrayList<String>()).filter(String.class);
}
}
void m(A a, B b) {
String sss = b.getFIterable().transform(s -> s).first().or(a.getOpt()).get();
}
}
@@ -0,0 +1,25 @@
import com.google.common.base.Optional;
import java.util.ArrayList;
import java.util.stream.Stream;
public class Main18 {
class A {
private String i = "12";
Optional<String> getOpt() {
return Optional.fromNullable(i);
}
}
class B {
Stream<String> getFIterable() {
return new ArrayList<String>().stream().filter(String.class::isInstance);
}
}
void m(A a, B b) {
String sss = java.util.Optional.ofNullable(b.getFIterable().map(s -> s).findFirst().orElseGet(a.getOpt()::get)).get();
}
}
@@ -0,0 +1,31 @@
import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
import java.util.ArrayList;
public class Main17 {
interface A {
FluentIterable<String> getIterable();
}
class B implements A {
@Override
public FluentIter<caret>able<String> getIterable() {
return FluentIterable.from(new ArrayList<String>()).transform(new Function<String, String>() {
@Override
public String apply(String s) {
return s.intern();
}
});
}
}
static void m(A a) {
int s = a.getIterable().transform(s1 -> s1).size();
}
static void m2(B b) {
int s = b.getIterable().size();
}
}
@@ -0,0 +1,24 @@
import java.util.ArrayList;
import java.util.stream.Stream;
public class Main17 {
interface A {
Stream<String> getIterable();
}
class B implements A {
@Override
public Stream<String> getIterable() {
return new ArrayList<String>().stream().map(s -> s.intern());
}
}
static void m(A a) {
int s = (int) a.getIterable().map(s1 -> s1).count();
}
static void m2(B b) {
int s = (int) b.getIterable().count();
}
}
@@ -66,9 +66,9 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass");
private static final String PRESENTABLE_NAME = DaemonBundle.message("pass.syntax");
private static final Key<Boolean> HAS_ERROR_ELEMENT = Key.create("HAS_ERROR_ELEMENT");
static final Condition<PsiFile> SHOULD_HIGHIGHT_FILTER = new Condition<PsiFile>() {
static final Condition<PsiFile> SHOULD_HIGHLIGHT_FILTER = new Condition<PsiFile>() {
@Override
public boolean value(PsiFile file) {
public boolean value(@NotNull PsiFile file) {
return HighlightingLevelManager.getInstance(file.getProject()).shouldHighlight(file);
}
};
@@ -198,7 +198,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
List<ProperTextRange> insideRanges = new ArrayList<ProperTextRange>();
List<ProperTextRange> outsideRanges = new ArrayList<ProperTextRange>();
Divider.divideInsideAndOutside(getFile(), myRestrictRange.getStartOffset(), myRestrictRange.getEndOffset(), myPriorityRange, insideElements, insideRanges, outsideElements,
outsideRanges, false, SHOULD_HIGHIGHT_FILTER);
outsideRanges, false, SHOULD_HIGHLIGHT_FILTER);
// put file element always in outsideElements
if (!insideElements.isEmpty() && insideElements.get(insideElements.size()-1) instanceof PsiFile) {
PsiElement file = insideElements.remove(insideElements.size() - 1);
@@ -157,7 +157,7 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
@NonNls
@Override
public String toString() {
return "UnionToLocal: (" + GlobalSearchScope.this.toString() + ", " + scope + ")";
return "UnionToLocal: (" + GlobalSearchScope.this + ", " + scope + ")";
}
};
}
@@ -446,7 +446,7 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
});
myNestingLevel = 1 + nested[0];
if (myNestingLevel > 1000) {
throw new IllegalStateException("Too many scopes combined: " + myNestingLevel + StringUtil.first(toString(), 500, true));
throw new IllegalStateException("Too many scopes combined: " + myNestingLevel + StringUtil.last(toString(), 500, true));
}
}
@@ -82,7 +82,7 @@ public class InjectedGeneralHighlightingPass extends GeneralHighlightingPass imp
List<ProperTextRange> outsideRanges = new ArrayList<ProperTextRange>();
//TODO: this thing is just called TWICE with same arguments eating CPU on huge files :(
Divider.divideInsideAndOutside(myFile, myRestrictRange.getStartOffset(), myRestrictRange.getEndOffset(), myPriorityRange, inside, insideRanges, outside,
outsideRanges, false, SHOULD_HIGHIGHT_FILTER);
outsideRanges, false, SHOULD_HIGHLIGHT_FILTER);
// all infos for the "injected fragment for the host which is inside" are indeed inside
@@ -440,7 +440,7 @@ class PassExecutorService implements Disposable {
return;
}
if (!myUpdateProgress.isCanceled()) {
if (!myUpdateProgress.isCanceled() && !myProject.isDisposed()) {
myPass.collectInformation(myUpdateProgress);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -16,7 +16,6 @@
package com.intellij.ide;
import com.intellij.ide.dnd.LinuxDragAndDropSupport;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -25,6 +24,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ProjectManagerAdapter;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.LocalFileSystem;
@@ -162,33 +162,29 @@ public class PsiCopyPasteManager {
public PsiElement[] getElements() {
if (myElements == null) return PsiElement.EMPTY_ARRAY;
int validElementsCount = 0;
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
int validElementsCount = 0;
for (PsiElement element : myElements) {
if (element.isValid()) {
validElementsCount++;
}
}
final AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
try {
for (PsiElement element : myElements) {
if (element.isValid()) {
validElementsCount++;
if (validElementsCount != myElements.length) {
PsiElement[] validElements = new PsiElement[validElementsCount];
int j = 0;
for (PsiElement element : myElements) {
if (element.isValid()) {
validElements[j++] = element;
}
}
myElements = validElements;
}
}
if (validElementsCount == myElements.length) {
return myElements;
}
PsiElement[] validElements = new PsiElement[validElementsCount];
int j=0;
for (PsiElement element : myElements) {
if (element.isValid()) {
validElements[j++] = element;
}
}
myElements = validElements;
}
finally {
token.finish();
}
});
return myElements;
}
@@ -261,33 +257,31 @@ public class PsiCopyPasteManager {
@Nullable
private String getDataAsText() {
final AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
try {
final List<String> names = new ArrayList<String>();
for (PsiElement element : myDataProxy.getElements()) {
if (element instanceof PsiNamedElement) {
String name = ((PsiNamedElement)element).getName();
if (name != null) {
names.add(name);
return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
@Override
public String compute() {
final List<String> names = new ArrayList<String>();
for (PsiElement element : myDataProxy.getElements()) {
if (element instanceof PsiNamedElement) {
String name = ((PsiNamedElement)element).getName();
if (name != null) {
names.add(name);
}
}
}
return names.isEmpty() ? null : StringUtil.join(names, "\n");
}
return names.isEmpty() ? null : StringUtil.join(names, "\n");
}
finally {
token.finish();
}
});
}
@Nullable
private List<File> getDataAsFileList() {
final AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
try {
return asFileList(myDataProxy.getElements());
}
finally {
token.finish();
}
return ApplicationManager.getApplication().runReadAction(new Computable<List<File>>() {
@Override
public List<File> compute() {
return asFileList(myDataProxy.getElements());
}
});
}
@Override
@@ -1166,103 +1166,107 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
@Override
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
protected void customizeCellRenderer(JList list, final Object value, int index, final boolean selected, boolean hasFocus) {
setPaintFocusBorder(false);
setIcon(EmptyIcon.ICON_16);
AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
try {
if (value instanceof PsiElement) {
String name = myClassModel.getElementName(value);
assert name != null;
append(name);
} else if (value instanceof ChooseRunConfigurationPopup.ItemWrapper) {
final ChooseRunConfigurationPopup.ItemWrapper wrapper = (ChooseRunConfigurationPopup.ItemWrapper)value;
append(wrapper.getText());
setIcon(wrapper.getIcon());
setLocationString(ourShiftIsPressed.get() ? "Run" : "Debug");
myLocationIcon = ourShiftIsPressed.get() ? AllIcons.Toolwindows.ToolWindowRun : AllIcons.Toolwindows.ToolWindowDebugger;
} else if (isVirtualFile(value)) {
final VirtualFile file = (VirtualFile)value;
if (file instanceof VirtualFilePathWrapper) {
append(((VirtualFilePathWrapper)file).getPresentablePath());
} else {
append(file.getName());
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
if (value instanceof PsiElement) {
String name = myClassModel.getElementName(value);
assert name != null;
append(name);
}
setIcon(IconUtil.getIcon(file, Iconable.ICON_FLAG_READ_STATUS, myProject));
}
else if (isActionValue(value)) {
final GotoActionModel.ActionWrapper actionWithParentGroup = value instanceof GotoActionModel.ActionWrapper ? (GotoActionModel.ActionWrapper)value : null;
final AnAction anAction = actionWithParentGroup == null ? (AnAction)value : actionWithParentGroup.getAction();
final Presentation templatePresentation = anAction.getTemplatePresentation();
Icon icon = templatePresentation.getIcon();
if (anAction instanceof ActivateToolWindowAction) {
final String id = ((ActivateToolWindowAction)anAction).getToolWindowId();
ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(id);
if (toolWindow != null) {
icon = toolWindow.getIcon();
else if (value instanceof ChooseRunConfigurationPopup.ItemWrapper) {
final ChooseRunConfigurationPopup.ItemWrapper wrapper = (ChooseRunConfigurationPopup.ItemWrapper)value;
append(wrapper.getText());
setIcon(wrapper.getIcon());
setLocationString(ourShiftIsPressed.get() ? "Run" : "Debug");
myLocationIcon = ourShiftIsPressed.get() ? AllIcons.Toolwindows.ToolWindowRun : AllIcons.Toolwindows.ToolWindowDebugger;
}
else if (isVirtualFile(value)) {
final VirtualFile file = (VirtualFile)value;
if (file instanceof VirtualFilePathWrapper) {
append(((VirtualFilePathWrapper)file).getPresentablePath());
}
else {
append(file.getName());
}
setIcon(IconUtil.getIcon(file, Iconable.ICON_FLAG_READ_STATUS, myProject));
}
else if (isActionValue(value)) {
final GotoActionModel.ActionWrapper actionWithParentGroup =
value instanceof GotoActionModel.ActionWrapper ? (GotoActionModel.ActionWrapper)value : null;
final AnAction anAction = actionWithParentGroup == null ? (AnAction)value : actionWithParentGroup.getAction();
final Presentation templatePresentation = anAction.getTemplatePresentation();
Icon icon = templatePresentation.getIcon();
if (anAction instanceof ActivateToolWindowAction) {
final String id = ((ActivateToolWindowAction)anAction).getToolWindowId();
ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(id);
if (toolWindow != null) {
icon = toolWindow.getIcon();
}
}
append(templatePresentation.getText());
if (actionWithParentGroup != null) {
final String groupName = actionWithParentGroup.getGroupName();
append(templatePresentation.getText());
if (actionWithParentGroup != null) {
final String groupName = actionWithParentGroup.getGroupName();
if (!StringUtil.isEmpty(groupName)) {
setLocationString(groupName);
}
}
final String groupName = actionWithParentGroup == null ? null : actionWithParentGroup.getGroupName();
if (!StringUtil.isEmpty(groupName)) {
setLocationString(groupName);
}
}
final String groupName = actionWithParentGroup == null ? null : actionWithParentGroup.getGroupName();
if (!StringUtil.isEmpty(groupName)) {
setLocationString(groupName);
}
if (icon != null && icon.getIconWidth() <= 16 && icon.getIconHeight() <= 16) {
setIcon(IconUtil.toSize(icon, 16, 16));
}
}
else if (isSetting(value)) {
String text = getSettingText((OptionDescription)value);
SimpleTextAttributes attrs = SimpleTextAttributes.REGULAR_ATTRIBUTES;
if (value instanceof Changeable && ((Changeable)value).hasChanged()) {
if (selected) {
attrs = SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES;
} else {
SimpleTextAttributes base = SimpleTextAttributes.LINK_BOLD_ATTRIBUTES;
attrs = base.derive(SimpleTextAttributes.STYLE_BOLD, base.getFgColor(), null, null);
if (icon != null && icon.getIconWidth() <= 16 && icon.getIconHeight() <= 16) {
setIcon(IconUtil.toSize(icon, 16, 16));
}
}
append(text, attrs);
final String id = ((OptionDescription)value).getConfigurableId();
final String name = myConfigurables.get(id);
if (name != null) {
setLocationString(name);
else if (isSetting(value)) {
String text = getSettingText((OptionDescription)value);
SimpleTextAttributes attrs = SimpleTextAttributes.REGULAR_ATTRIBUTES;
if (value instanceof Changeable && ((Changeable)value).hasChanged()) {
if (selected) {
attrs = SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES;
}
else {
SimpleTextAttributes base = SimpleTextAttributes.LINK_BOLD_ATTRIBUTES;
attrs = base.derive(SimpleTextAttributes.STYLE_BOLD, base.getFgColor(), null, null);
}
}
append(text, attrs);
final String id = ((OptionDescription)value).getConfigurableId();
final String name = myConfigurables.get(id);
if (name != null) {
setLocationString(name);
}
}
}
else if (value instanceof OptionsTopHitProvider) {
append("#" + ((OptionsTopHitProvider)value).getId());
}
else {
ItemPresentation presentation = null;
if (value instanceof ItemPresentation) {
presentation = (ItemPresentation)value;
else if (value instanceof OptionsTopHitProvider) {
append("#" + ((OptionsTopHitProvider)value).getId());
}
else if (value instanceof NavigationItem) {
presentation = ((NavigationItem)value).getPresentation();
}
if (presentation != null) {
final String text = presentation.getPresentableText();
append(text == null ? value.toString() : text);
final String location = presentation.getLocationString();
if (!StringUtil.isEmpty(location)) {
setLocationString(location);
else {
ItemPresentation presentation = null;
if (value instanceof ItemPresentation) {
presentation = (ItemPresentation)value;
}
else if (value instanceof NavigationItem) {
presentation = ((NavigationItem)value).getPresentation();
}
if (presentation != null) {
final String text = presentation.getPresentableText();
append(text == null ? value.toString() : text);
final String location = presentation.getLocationString();
if (!StringUtil.isEmpty(location)) {
setLocationString(location);
}
Icon icon = presentation.getIcon(false);
if (icon != null) setIcon(icon);
}
Icon icon = presentation.getIcon(false);
if (icon != null) setIcon(icon);
}
}
}
finally {
token.finish();
}
});
}
public void recalculateWidth() {
@@ -66,6 +66,8 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project
public static final String NAME_FILE = ".name";
public static final Key<Long> CREATION_TIME = Key.create("ProjectImpl.CREATION_TIME");
public static final Key<String> CREATION_TRACE = Key.create("ProjectImpl.CREATION_TRACE");
@TestOnly
public static final String LIGHT_PROJECT_NAME = "light_temp";
private ProjectManager myProjectManager;
private MyProjectManagerListener myProjectManagerListener;
@@ -103,7 +105,7 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project
}
// light project may be changed later during test, so we need to remember its initial state
myLight = ApplicationManager.getApplication().isUnitTestMode() && filePath.contains("light_temp_");
myLight = ApplicationManager.getApplication().isUnitTestMode() && filePath.contains(LIGHT_PROJECT_NAME);
}
@Override
@@ -61,6 +61,7 @@ import com.intellij.openapi.project.ModuleAdapter;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ex.ProjectManagerEx;
import com.intellij.openapi.project.impl.ProjectImpl;
import com.intellij.openapi.project.impl.ProjectManagerImpl;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootManager;
@@ -241,7 +242,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
token.finish();
}
final File projectFile = FileUtil.createTempFile("light_temp_", ProjectFileType.DOT_DEFAULT_EXTENSION);
final File projectFile = FileUtil.createTempFile(ProjectImpl.LIGHT_PROJECT_NAME, ProjectFileType.DOT_DEFAULT_EXTENSION);
LocalFileSystem.getInstance().refreshAndFindFileByIoFile(projectFile);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@@ -110,7 +110,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
protected boolean myAssertionsInTestDetected;
protected static final Logger LOG = Logger.getInstance("#com.intellij.testFramework.PlatformTestCase");
public static Thread ourTestThread;
private static TestCase ourTestCase = null;
private static TestCase ourTestCase;
public static final long DEFAULT_TEST_TIME = 300L;
public static long ourTestTime = DEFAULT_TEST_TIME;
private EditorListenerTracker myEditorListenerTracker;
@@ -191,6 +191,9 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
@Override
protected void setUp() throws Exception {
super.setUp();
File tempDir = new File(FileUtilRt.getTempDirectory());
myFilesToDelete.add(tempDir);
if (ourTestCase != null) {
String message = "Previous test " + ourTestCase + " hasn't called tearDown(). Probably overridden without super call.";
ourTestCase = null;
@@ -307,7 +310,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
}
protected File getIprFile() throws IOException {
File tempFile = FileUtil.createTempFile(getName() + "_", ProjectFileType.DOT_DEFAULT_EXTENSION);
File tempFile = FileUtil.createTempFile(getName(), ProjectFileType.DOT_DEFAULT_EXTENSION);
myFilesToDelete.add(tempFile);
return tempFile;
}
@@ -139,7 +139,7 @@ public abstract class UsefulTestCase extends TestCase {
String testName = FileUtil.sanitizeFileName(getTestName(true));
if (StringUtil.isEmptyOrSpaces(testName)) testName = "";
testName = new File(testName).getName(); // in case the test name contains file separators
myTempDir = FileUtil.toSystemDependentName(ORIGINAL_TEMP_DIR + "/" + TEMP_DIR_MARKER + testName + "_"+ RNG.nextInt(1000));
myTempDir = new File(ORIGINAL_TEMP_DIR, TEMP_DIR_MARKER + testName).getPath();
FileUtil.resetCanonicalTempPathCache(myTempDir);
}
ApplicationInfoImpl.setInPerformanceTest(isPerformanceTest());
@@ -315,7 +315,7 @@ public class FileUtilRt {
}
private static class FilesToDeleteHolder {
public static final Queue<String> ourFilesToDelete = createFilesToDelete();
private static final Queue<String> ourFilesToDelete = createFilesToDelete();
private static Queue<String> createFilesToDelete() {
final ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();
@@ -387,62 +387,47 @@ public class FileUtilRt {
prefix = (prefix + "___").substring(0, 3);
}
if (suffix == null) {
suffix = ".tmp";
suffix = "";
}
// normalize and use only the file name from the prefix
prefix = new File(prefix).getName();
int exceptionsCount = 0;
int i = 0;
while (true) {
try {
// If there was an IOException, there's no reason to do sequential search - fallback to random
final File temp = createTemp(prefix, suffix, dir, isDirectory, exceptionsCount > 0);
return normalizeFile(temp);
File f = calcName(dir, prefix, suffix, i);
boolean success = isDirectory ? f.mkdir() : f.createNewFile();
if (!success) {
throw new IOException("Unable to create temporary file " + f);
}
return normalizeFile(f);
}
catch (IOException e) { // Win32 createFileExclusively access denied
if (++exceptionsCount >= 100) {
throw e;
}
}
i++; // for some reason the file1 can't be created (previous file1 was deleted but got locked by anti-virus?). try file2.
if (i > 2) {
i = 2 + (int)(System.nanoTime() % 998); // generate random suffix if too many failures
}
}
}
@NotNull
private static File createTemp(@NotNull String prefix,
@NotNull String suffix,
@NotNull File directory,
boolean isDirectory,
boolean randomName) throws IOException {
// Fallback to the original File.createTempFile
if (randomName) {
@SuppressWarnings("SSBasedInspection")
File res = File.createTempFile(prefix, suffix, directory);
if (isDirectory) {
if (!res.delete() || !res.mkdir()) {
throw new IOException("Cannot create directory: " + res);
}
}
return res;
private static File calcName(@NotNull File dir, @NotNull String prefix, @NotNull String suffix, int i) throws IOException {
prefix += i == 0 ? "" : i;
if (prefix.endsWith(".") && suffix.startsWith(".")) {
prefix = prefix.substring(0, prefix.length() - 1);
}
// normalize and use only the file name from the prefix
prefix = new File(prefix).getName();
File f;
int i = 0;
do {
String name = prefix + i + suffix;
f = new File(directory, name);
if (!name.equals(f.getName())) {
throw new IOException("Unable to create temporary file " + f + " for name " + name);
}
i++;
String name = prefix + suffix;
File f = new File(dir, name);
if (!name.equals(f.getName())) {
throw new IOException("Unable to create temporary file " + f + " for name " + name);
}
while (f.exists());
boolean success = isDirectory ? f.mkdir() : f.createNewFile();
if (!success) {
throw new IOException("Unable to create temporary file " + f);
}
return f;
}
@@ -60,6 +60,7 @@ import org.gradle.tooling.model.idea.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.DefaultExternalDependencyId;
import org.jetbrains.plugins.gradle.ExternalDependencyId;
import org.jetbrains.plugins.gradle.model.*;
import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData;
@@ -403,11 +404,48 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
processSourceSets(externalProject, ideModule, new SourceSetsProcessor() {
@Override
public void process(@NotNull DataNode<GradleSourceSetData> dataNode, @NotNull ExternalSourceSet sourceSet) {
Map<ExternalDependencyId, ExternalDependency> dependencyMap = ContainerUtil.newLinkedHashMap();
for (ExternalDependency dependency : sourceSet.getDependencies()) {
ExternalDependency d = dependencyMap.get(dependency.getId());
if (d != null) {
DependencyScope prevScope = d.getScope() == null ? DependencyScope.COMPILE : DependencyScope.valueOf(d.getScope());
Map<ExternalDependencyId, ExternalDependency> dependencyMap = ContainerUtil.newHashMap();
Queue<ExternalDependency> queue = ContainerUtil.newLinkedList(sourceSet.getDependencies());
while (!queue.isEmpty()) {
final ExternalDependency dependency = queue.remove();
ExternalDependency seenDependency = dependencyMap.get(dependency.getId());
if (seenDependency != null) {
if (dependency instanceof ExternalLibraryDependency) {
if (seenDependency instanceof ExternalLibraryDependency &&
!FileUtil.filesEqual(((ExternalLibraryDependency)seenDependency).getFile(),
((ExternalLibraryDependency)dependency).getFile())) {
DefaultExternalMultiLibraryDependency mergedDependency = new DefaultExternalMultiLibraryDependency();
mergedDependency.setName(dependency.getId().getName());
mergedDependency.setGroup(dependency.getId().getGroup());
mergedDependency.setVersion(dependency.getId().getVersion());
mergedDependency.setPackaging(dependency.getId().getPackaging());
mergedDependency.setClassifier(dependency.getId().getClassifier());
mergedDependency.setScope(dependency.getScope());
mergedDependency.setClasspathOrder(dependency.getClasspathOrder());
mergedDependency.getDependencies().addAll(dependency.getDependencies());
mergedDependency.getFiles().addAll(ContainerUtil.packNullables(
((ExternalLibraryDependency)seenDependency).getFile(), ((ExternalLibraryDependency)dependency).getFile()));
mergedDependency.getSources().addAll((ContainerUtil.packNullables(
((ExternalLibraryDependency)seenDependency).getSource(), ((ExternalLibraryDependency)dependency).getSource())));
mergedDependency.getJavadoc().addAll((ContainerUtil.packNullables(
((ExternalLibraryDependency)seenDependency).getJavadoc(), ((ExternalLibraryDependency)dependency).getJavadoc())));
dependencyMap.put(dependency.getId(), mergedDependency);
continue;
}
else if (seenDependency instanceof DefaultExternalMultiLibraryDependency) {
DefaultExternalMultiLibraryDependency mergedDependency = (DefaultExternalMultiLibraryDependency)seenDependency;
mergedDependency.getFiles().addAll(ContainerUtil.packNullables(((ExternalLibraryDependency)dependency).getFile()));
mergedDependency.getSources().addAll(ContainerUtil.packNullables(((ExternalLibraryDependency)dependency).getSource()));
mergedDependency.getJavadoc().addAll(ContainerUtil.packNullables(((ExternalLibraryDependency)dependency).getJavadoc()));
continue;
}
}
DependencyScope prevScope =
seenDependency.getScope() == null ? DependencyScope.COMPILE : DependencyScope.valueOf(seenDependency.getScope());
DependencyScope currentScope =
dependency.getScope() == null ? DependencyScope.COMPILE : DependencyScope.valueOf(dependency.getScope());
@@ -415,12 +453,11 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
if (prevScope.isForProductionRuntime() && currentScope.isForProductionRuntime()) continue;
}
dependencyMap.put(dependency.getId(), dependency);
dependencyMap.put(new DefaultExternalDependencyId(dependency.getId()), dependency);
queue.addAll(dependency.getDependencies());
}
for (ExternalDependency dependency : dependencyMap.values()) {
buildSourceSetDependency(sourceSetMap, dataNode, dependency, ideProject);
}
buildSourceSetDependency(sourceSetMap, dependencyMap, dataNode, sourceSet.getDependencies(), ideProject);
}
});
@@ -928,125 +965,120 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
}
private static void buildSourceSetDependency(@NotNull Map<String, Pair<DataNode<GradleSourceSetData>, ExternalSourceSet>> sourceSetMap,
@NotNull DataNode<? extends ModuleData> ownerModule,
@NotNull ExternalDependency dependency,
@NotNull DataNode<ProjectData> ideProject)
throws IllegalStateException {
@NotNull Map<ExternalDependencyId, ExternalDependency> mergedDependencyMap,
@NotNull DataNode<? extends ExternalEntityData> ownerDataNode,
@NotNull Collection<ExternalDependency> dependencies,
@NotNull DataNode<ProjectData> ideProject) throws IllegalStateException {
DependencyScope dependencyScope = getDependencyScope(dependency.getScope());
if (dependency instanceof ExternalProjectDependency) {
String moduleId = getModuleId((ExternalProjectDependency)dependency);
Pair<DataNode<GradleSourceSetData>, ExternalSourceSet> projectPair = sourceSetMap.get(moduleId);
ModuleDependencyData moduleDependencyData = new ModuleDependencyData(ownerModule.getData(), projectPair.first.getData());
moduleDependencyData.setScope(dependencyScope);
if ("test".equals(projectPair.second.getName())) {
moduleDependencyData.setProductionOnTestDependency(true);
}
moduleDependencyData.setOrder(dependency.getClasspathOrder());
moduleDependencyData.setExported(dependency.getExported());
DataNode<ModuleDependencyData> ideModuleDependencyNode = ownerModule.createChild(ProjectKeys.MODULE_DEPENDENCY, moduleDependencyData);
for (ExternalDependency externalDependency : dependency.getDependencies()) {
buildTransitiveDependency(sourceSetMap, ideModuleDependencyNode, externalDependency, ideProject);
}
Map<ExternalDependencyId, ExternalDependency> dependencyMap = ContainerUtil.newLinkedHashMap();
for (ExternalDependency dependency : dependencies) {
dependencyMap.put(dependency.getId(), dependency);
}
if (dependency instanceof ExternalLibraryDependency) {
final LibraryLevel level = LibraryLevel.PROJECT;
String libraryName = dependency.getId().getPresentableName();
final LibraryData library = new LibraryData(GradleConstants.SYSTEM_ID, libraryName);
LibraryDependencyData libraryDependencyData = new LibraryDependencyData(ownerModule.getData(), library, level);
libraryDependencyData.setScope(dependencyScope);
libraryDependencyData.setOrder(dependency.getClasspathOrder());
libraryDependencyData.setExported(dependency.getExported());
library.addPath(LibraryPathType.BINARY, ((ExternalLibraryDependency)dependency).getFile().getAbsolutePath());
File sourcePath = ((ExternalLibraryDependency)dependency).getSource();
for (ExternalDependency dependency : dependencyMap.values()) {
final ExternalDependency mergedDependency = ContainerUtil.getOrElse(mergedDependencyMap, dependency.getId(), dependency);
DependencyScope dependencyScope = getDependencyScope(mergedDependency.getScope());
if (sourcePath != null) {
library.addPath(LibraryPathType.SOURCE, sourcePath.getAbsolutePath());
ModuleData ownerModule = null;
if (ownerDataNode.getData() instanceof ModuleData) {
ownerModule = (ModuleData)ownerDataNode.getData();
}
DataNode<LibraryDependencyData> libraryDependencyDataNode =
ownerModule.createChild(ProjectKeys.LIBRARY_DEPENDENCY, libraryDependencyData);
linkProjectLibrary(ideProject, library);
for (ExternalDependency externalDependency : dependency.getDependencies()) {
buildTransitiveDependency(sourceSetMap, libraryDependencyDataNode, externalDependency, ideProject);
}
}
if (dependency instanceof FileCollectionDependency) {
final LibraryLevel level = LibraryLevel.MODULE;
String libraryName = "";
final LibraryData library = new LibraryData(GradleConstants.SYSTEM_ID, libraryName);
LibraryDependencyData libraryDependencyData = new LibraryDependencyData(ownerModule.getData(), library, level);
libraryDependencyData.setScope(dependencyScope);
libraryDependencyData.setOrder(dependency.getClasspathOrder());
libraryDependencyData.setExported(dependency.getExported());
for (File file : ((FileCollectionDependency)dependency).getFiles()) {
library.addPath(LibraryPathType.BINARY, file.getAbsolutePath());
else if (ownerDataNode.getData() instanceof DependencyData) {
ownerModule = ((DependencyData)ownerDataNode.getData()).getOwnerModule();
}
ownerModule.createChild(ProjectKeys.LIBRARY_DEPENDENCY, libraryDependencyData);
}
if (dependency instanceof UnresolvedExternalDependency) {
final LibraryLevel level = LibraryLevel.PROJECT;
String libraryName = dependency.getId().getPresentableName();
final LibraryData library = new LibraryData(GradleConstants.SYSTEM_ID, libraryName, true);
LibraryDependencyData libraryDependencyData = new LibraryDependencyData(ownerModule.getData(), library, level);
libraryDependencyData.setScope(dependencyScope);
final String failureMessage = ((UnresolvedExternalDependency)dependency).getFailureMessage();
if (failureMessage != null) {
library.addPath(LibraryPathType.BINARY, failureMessage);
}
ownerModule.createChild(ProjectKeys.LIBRARY_DEPENDENCY, libraryDependencyData);
linkProjectLibrary(ideProject, library);
}
}
assert ownerModule != null;
private static void buildTransitiveDependency(@NotNull Map<String, Pair<DataNode<GradleSourceSetData>, ExternalSourceSet>> sourceSetMap,
@NotNull DataNode<? extends DependencyData> ownerModule,
@NotNull ExternalDependency dependency,
@NotNull DataNode<ProjectData> ideProject)
throws IllegalStateException {
DependencyScope dependencyScope = getDependencyScope(dependency.getScope());
if (dependency instanceof ExternalProjectDependency) {
String moduleId = getModuleId((ExternalProjectDependency)dependency);
Pair<DataNode<GradleSourceSetData>, ExternalSourceSet> projectPair = sourceSetMap.get(moduleId);
ModuleDependencyData moduleDependencyData =
new ModuleDependencyData(ownerModule.getData().getOwnerModule(), projectPair.first.getData());
moduleDependencyData.setScope(dependencyScope);
if ("test".equals(projectPair.second.getName())) {
moduleDependencyData.setProductionOnTestDependency(true);
if (mergedDependency instanceof ExternalProjectDependency) {
String moduleId = getModuleId((ExternalProjectDependency)mergedDependency);
Pair<DataNode<GradleSourceSetData>, ExternalSourceSet> projectPair = sourceSetMap.get(moduleId);
ModuleDependencyData moduleDependencyData = new ModuleDependencyData(ownerModule, projectPair.first.getData());
moduleDependencyData.setScope(dependencyScope);
if ("test".equals(projectPair.second.getName())) {
moduleDependencyData.setProductionOnTestDependency(true);
}
moduleDependencyData.setOrder(mergedDependency.getClasspathOrder());
moduleDependencyData.setExported(mergedDependency.getExported());
DataNode<ModuleDependencyData> ideModuleDependencyNode =
ownerDataNode.createChild(ProjectKeys.MODULE_DEPENDENCY, moduleDependencyData);
buildSourceSetDependency(sourceSetMap, mergedDependencyMap, ideModuleDependencyNode, dependency.getDependencies(), ideProject);
}
moduleDependencyData.setOrder(dependency.getClasspathOrder());
moduleDependencyData.setExported(dependency.getExported());
DataNode<ModuleDependencyData> ideModuleDependencyNode = ownerModule.createChild(ProjectKeys.MODULE_DEPENDENCY, moduleDependencyData);
for (ExternalDependency externalDependency : dependency.getDependencies()) {
buildTransitiveDependency(sourceSetMap, ideModuleDependencyNode, externalDependency, ideProject);
}
}
if (dependency instanceof ExternalLibraryDependency) {
final LibraryLevel level = LibraryLevel.PROJECT;
String libraryName = dependency.getId().getPresentableName();
final LibraryData library = new LibraryData(GradleConstants.SYSTEM_ID, libraryName);
LibraryDependencyData libraryDependencyData = new LibraryDependencyData(ownerModule.getData().getOwnerModule(), library, level);
if (mergedDependency instanceof ExternalLibraryDependency) {
final LibraryLevel level = LibraryLevel.PROJECT;
String libraryName = mergedDependency.getId().getPresentableName();
final LibraryData library = new LibraryData(GradleConstants.SYSTEM_ID, libraryName);
LibraryDependencyData libraryDependencyData = new LibraryDependencyData(ownerModule, library, level);
libraryDependencyData.setScope(dependencyScope);
libraryDependencyData.setOrder(mergedDependency.getClasspathOrder());
libraryDependencyData.setExported(mergedDependency.getExported());
libraryDependencyData.setScope(dependencyScope);
libraryDependencyData.setOrder(dependency.getClasspathOrder());
libraryDependencyData.setExported(dependency.getExported());
library.addPath(LibraryPathType.BINARY, ((ExternalLibraryDependency)dependency).getFile().getAbsolutePath());
File sourcePath = ((ExternalLibraryDependency)dependency).getSource();
if (sourcePath != null) {
library.addPath(LibraryPathType.SOURCE, sourcePath.getAbsolutePath());
}
DataNode<LibraryDependencyData> libraryDependencyDataNode =
ownerModule.createChild(ProjectKeys.LIBRARY_DEPENDENCY, libraryDependencyData);
library.addPath(LibraryPathType.BINARY, ((ExternalLibraryDependency)mergedDependency).getFile().getAbsolutePath());
File sourcePath = ((ExternalLibraryDependency)mergedDependency).getSource();
if (sourcePath != null) {
library.addPath(LibraryPathType.SOURCE, sourcePath.getAbsolutePath());
}
File javaDocPath = ((ExternalLibraryDependency)mergedDependency).getJavadoc();
if (javaDocPath != null) {
library.addPath(LibraryPathType.DOC, javaDocPath.getAbsolutePath());
}
DataNode<LibraryDependencyData> libraryDependencyDataNode =
ownerDataNode.createChild(ProjectKeys.LIBRARY_DEPENDENCY, libraryDependencyData);
linkProjectLibrary(ideProject, library);
for (ExternalDependency externalDependency : dependency.getDependencies()) {
buildTransitiveDependency(sourceSetMap, libraryDependencyDataNode, externalDependency, ideProject);
linkProjectLibrary(ideProject, library);
buildSourceSetDependency(sourceSetMap, mergedDependencyMap, libraryDependencyDataNode, dependency.getDependencies(), ideProject);
}
if (mergedDependency instanceof ExternalMultiLibraryDependency) {
final LibraryLevel level = LibraryLevel.MODULE;
String libraryName = mergedDependency.getId().getPresentableName();
final LibraryData library = new LibraryData(GradleConstants.SYSTEM_ID, libraryName);
LibraryDependencyData libraryDependencyData = new LibraryDependencyData(ownerModule, library, level);
libraryDependencyData.setScope(dependencyScope);
libraryDependencyData.setOrder(mergedDependency.getClasspathOrder());
libraryDependencyData.setExported(mergedDependency.getExported());
for (File file : ((ExternalMultiLibraryDependency)mergedDependency).getFiles()) {
library.addPath(LibraryPathType.BINARY, file.getAbsolutePath());
}
for (File file : ((ExternalMultiLibraryDependency)mergedDependency).getSources()) {
library.addPath(LibraryPathType.SOURCE, file.getAbsolutePath());
}
for (File file : ((ExternalMultiLibraryDependency)mergedDependency).getJavadoc()) {
library.addPath(LibraryPathType.DOC, file.getAbsolutePath());
}
DataNode<LibraryDependencyData> libraryDependencyDataNode =
ownerDataNode.createChild(ProjectKeys.LIBRARY_DEPENDENCY, libraryDependencyData);
buildSourceSetDependency(sourceSetMap, mergedDependencyMap, libraryDependencyDataNode, dependency.getDependencies(), ideProject);
}
if (mergedDependency instanceof FileCollectionDependency) {
final LibraryLevel level = LibraryLevel.MODULE;
String libraryName = "";
final LibraryData library = new LibraryData(GradleConstants.SYSTEM_ID, libraryName);
LibraryDependencyData libraryDependencyData = new LibraryDependencyData(ownerModule, library, level);
libraryDependencyData.setScope(dependencyScope);
libraryDependencyData.setOrder(mergedDependency.getClasspathOrder());
libraryDependencyData.setExported(mergedDependency.getExported());
for (File file : ((FileCollectionDependency)mergedDependency).getFiles()) {
library.addPath(LibraryPathType.BINARY, file.getAbsolutePath());
}
ownerDataNode.createChild(ProjectKeys.LIBRARY_DEPENDENCY, libraryDependencyData);
}
if (mergedDependency instanceof UnresolvedExternalDependency) {
final LibraryLevel level = LibraryLevel.PROJECT;
String libraryName = mergedDependency.getId().getPresentableName();
final LibraryData library = new LibraryData(GradleConstants.SYSTEM_ID, libraryName, true);
LibraryDependencyData libraryDependencyData = new LibraryDependencyData(ownerModule, library, level);
libraryDependencyData.setScope(dependencyScope);
final String failureMessage = ((UnresolvedExternalDependency)mergedDependency).getFailureMessage();
if (failureMessage != null) {
library.addPath(LibraryPathType.BINARY, failureMessage);
}
ownerDataNode.createChild(ProjectKeys.LIBRARY_DEPENDENCY, libraryDependencyData);
linkProjectLibrary(ideProject, library);
}
}
}
@@ -368,6 +368,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
final LibraryData libraryData = libraryDependencyData.getTarget();
final Set<String> libraryPaths = libraryData.getPaths(LibraryPathType.BINARY);
if (libraryPaths.isEmpty()) continue;
if(StringUtil.isNotEmpty(libraryData.getExternalName())) continue;
final LinkedList<String> unprocessedPaths = ContainerUtil.newLinkedList(libraryPaths);
while (!unprocessedPaths.isEmpty()) {
@@ -0,0 +1,52 @@
/*
* Copyright 2000-2015 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 org.jetbrains.plugins.gradle.model;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.Collection;
import java.util.List;
/**
* @author Vladislav.Soroka
* @since 7/14/2014
*/
public interface ExternalMultiLibraryDependency extends ExternalDependency {
/**
* Returns the binary files for this dependency.
*
* @return binary file
*/
@NotNull
Collection<File> getFiles();
/**
* Returns the source directories/archives for this dependency.
*
* @return The source files.
*/
@NotNull
Collection<File> getSources();
/**
* Returns the Javadoc directories/archives for this dependency.
*
* @return The Javadoc files.
*/
@NotNull
Collection<File> getJavadoc();
}
@@ -0,0 +1,82 @@
/*
* Copyright 2000-2015 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 org.jetbrains.plugins.gradle.model;
import com.google.common.base.Objects;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.Collection;
import java.util.LinkedHashSet;
/**
* @author Vladislav.Soroka
* @since 12/24/2014
*/
public class DefaultExternalMultiLibraryDependency extends AbstractExternalDependency implements ExternalMultiLibraryDependency {
private static final long serialVersionUID = 1L;
private Collection<File> files = new LinkedHashSet<File>();
private Collection<File> sources = new LinkedHashSet<File>();
private Collection<File> javadocs = new LinkedHashSet<File>();
public DefaultExternalMultiLibraryDependency() {
}
public DefaultExternalMultiLibraryDependency(ExternalMultiLibraryDependency dependency) {
super(dependency);
files = dependency.getFiles();
sources = dependency.getSources();
javadocs = dependency.getJavadoc();
}
@NotNull
@Override
public Collection<File> getFiles() {
return files;
}
@NotNull
@Override
public Collection<File> getSources() {
return sources;
}
@NotNull
@Override
public Collection<File> getJavadoc() {
return javadocs;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof DefaultExternalMultiLibraryDependency)) return false;
if (!super.equals(o)) return false;
DefaultExternalMultiLibraryDependency that = (DefaultExternalMultiLibraryDependency)o;
return Objects.equal(files, that.files);
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), files);
}
@Override
public String toString() {
return "library '" + files + '\'';
}
}
@@ -226,9 +226,6 @@ class DependencyResolverImpl implements DependencyResolver {
runtimeClasspathFiles -= sourceSet.output.files
compileClasspathFiles -= sourceSet.output.files
mapFileDependencies(runtimeClasspathFiles, runtimeScope, result)
mapFileDependencies(compileClasspathFiles, compileScope, result)
Multimap<String, File> resolvedDependenciesMap = ArrayListMultimap.create()
Project rootProject = myProject.rootProject
@@ -293,6 +290,28 @@ class DependencyResolverImpl implements DependencyResolver {
runtimeClasspathFiles.removeAll(resolvedDependenciesMap.get(compileScope))
runtimeClasspathFiles.removeAll(resolvedDependenciesMap.get(providedScope))
Collection<ExternalDependency> fileDependencies = new ArrayList<>()
mapFileDependencies(runtimeClasspathFiles, runtimeScope, fileDependencies)
mapFileDependencies(compileClasspathFiles, compileScope, fileDependencies)
fileDependencies.each {
def dependency = it
def scope = dependency.scope
order = -1;
if (dependency instanceof ExternalLibraryDependency) {
def classpathOrderMap = scope == compileScope ? compileClasspathOrder :
scope == runtimeScope ? runtimeClasspathOrder : null
if (classpathOrderMap) {
def fileOrder = classpathOrderMap.get(dependency.file)
order = fileOrder != null ? fileOrder : -1
}
}
if (dependency instanceof AbstractExternalDependency) {
dependency.classpathOrder = order
}
}
result.addAll(fileDependencies)
if (!compileClasspathFiles.isEmpty()) {
final compileClasspathFilesDependency = new DefaultFileCollectionDependency(compileClasspathFiles)
compileClasspathFilesDependency.scope = compileScope
@@ -388,15 +407,27 @@ class DependencyResolverImpl implements DependencyResolver {
@Nullable
ExternalLibraryDependency resolveLibraryByPath(File file, String scope) {
File modules2Dir = new File(myProject.gradle.gradleUserHomeDir, "caches/modules-2/files-2.1");
def modules2Path = modules2Dir.canonicalPath
return resolveLibraryByPath(file, modules2Path, scope)
return resolveLibraryByPath(file, modules2Dir, scope)
}
@Nullable
static ExternalLibraryDependency resolveLibraryByPath(File file, String modules2Path, String scope) {
static ExternalLibraryDependency resolveLibraryByPath(File file, File modules2Dir, String scope) {
File sourcesFile = null;
if (file.canonicalPath.startsWith(modules2Path)) {
def parentFile = file.parentFile?.parentFile
def modules2Path = modules2Dir.canonicalPath
def filePath = file.canonicalPath
if (filePath.startsWith(modules2Path)) {
List<File> parents = new ArrayList<>()
File parent = file.parentFile;
while(parent && !parent.name.equals(modules2Dir.name)) {
parents.add(parent)
parent = parent.parentFile
}
def groupDir = parents.get(parents.size() - 1)
def artifactDir = parents.get(parents.size() - 2)
def versionDir = parents.get(parents.size() - 3)
def parentFile = versionDir
if (parentFile != null) {
def hashDirs = parentFile.listFiles()
if (hashDirs != null) {
@@ -414,9 +445,6 @@ class DependencyResolverImpl implements DependencyResolver {
}
}
def versionDir = parentFile
def artifactDir = versionDir.parentFile
def groupDir = artifactDir.parentFile
def packaging = resolvePackagingType(file);
def classifier = resolveClassifier(artifactDir.name, versionDir.name, file);
return new DefaultExternalLibraryDependency(
@@ -438,10 +466,9 @@ class DependencyResolverImpl implements DependencyResolver {
def mapFileDependencies(Set<File> fileDependencies, String scope, Collection<ExternalDependency> dependencies) {
File modules2Dir = new File(myProject.gradle.gradleUserHomeDir, "caches/modules-2/files-2.1");
def modules2Path = modules2Dir.canonicalPath
List toRemove = new ArrayList()
for (File file : fileDependencies) {
def libraryDependency = resolveLibraryByPath(file, modules2Path, scope)
def libraryDependency = resolveLibraryByPath(file, modules2Dir, scope)
if (libraryDependency) {
dependencies.add(libraryDependency)
toRemove.add(file)
@@ -94,13 +94,15 @@ public class RepositoryAttachHandler {
boolean attachJavaDoc = dialog.getAttachJavaDoc();
boolean attachSources = dialog.getAttachSources();
List<MavenRepositoryInfo> repositories = dialog.getRepositories();
NewLibraryConfiguration configuration = resolveAndDownload(project, coord, attachJavaDoc, attachSources, copyTo, repositories);
@Nullable NewLibraryConfiguration configuration =
resolveAndDownload(project, coord, attachJavaDoc, attachSources, copyTo, repositories);
if (configuration == null) {
Messages.showErrorDialog(parentComponent, ProjectBundle.message("maven.downloading.failed", coord), CommonBundle.getErrorTitle());
}
return configuration;
}
@Nullable
public static NewLibraryConfiguration resolveAndDownload(final Project project,
final String coord,
boolean attachJavaDoc,
@@ -108,7 +110,7 @@ public class RepositoryAttachHandler {
@Nullable final String copyTo,
List<MavenRepositoryInfo> repositories) {
RepositoryLibraryProperties libraryProperties = new RepositoryLibraryProperties(coord);
final List<OrderRoot> roots = MavenDependenciesRemoteManager.getInstance(project)
final @Nullable List<OrderRoot> roots = MavenDependenciesRemoteManager.getInstance(project)
.downloadDependenciesModal(libraryProperties, attachSources, attachJavaDoc, copyTo);
if (roots == null || roots.size() == 0) {
return null;
@@ -126,13 +128,15 @@ public class RepositoryAttachHandler {
};
}
public static List<OrderRoot> resolveAndDownloadImpl(final Project project,
final String coord,
boolean attachJavaDoc,
boolean attachSources,
@Nullable final String copyTo,
List<MavenRepositoryInfo> repositories,
ProgressIndicator indicator) {
public static
@NotNull
List<OrderRoot> resolveAndDownloadImpl(final Project project,
final String coord,
boolean attachJavaDoc,
boolean attachSources,
@Nullable final String copyTo,
List<MavenRepositoryInfo> repositories,
ProgressIndicator indicator) {
final SmartList<MavenExtraArtifactType> extraTypes = new SmartList<MavenExtraArtifactType>();
if (attachSources) extraTypes.add(MavenExtraArtifactType.SOURCES);
if (attachJavaDoc) extraTypes.add(MavenExtraArtifactType.DOCS);
@@ -49,7 +49,9 @@ public class MavenDependenciesRemoteManager
schedule(this, new Argument(libraryProperties, downloadSources, downloadJavaDocs, copyTo), resultProcessor, false);
}
public List<OrderRoot> downloadDependencies(
public
@Nullable
List<OrderRoot> downloadDependencies(
RepositoryLibraryProperties libraryProperties,
boolean downloadSources,
boolean downloadJavaDocs,
@@ -57,6 +59,7 @@ public class MavenDependenciesRemoteManager
return getSynchronously(this, new Argument(libraryProperties, downloadSources, downloadJavaDocs, copyTo));
}
@Nullable
public List<OrderRoot> downloadDependenciesModal(
final RepositoryLibraryProperties libraryProperties,
final boolean downloadSources,
@@ -68,6 +71,7 @@ public class MavenDependenciesRemoteManager
}
@Override
@NotNull
public List<OrderRoot> execute(@NotNull Argument arg, ProgressIndicator indicator) {
String coordinates = arg.libraryProperties.getGroupId() + ":" +
arg.libraryProperties.getArtifactId() + ":" +
@@ -77,6 +77,7 @@ public abstract class MavenRemoteManager<Result, Argument, RemoteTask extends Ma
return future;
}
@Nullable
protected Result getSynchronously(@NotNull RemoteTask task, @NotNull Argument argument) {
try {
return schedule(task, argument).get();
@@ -90,6 +91,7 @@ public abstract class MavenRemoteManager<Result, Argument, RemoteTask extends Ma
return null;
}
@Nullable
protected Result getSynchronouslyWithModal(@NotNull final RemoteTask task, @NotNull final Argument argument, String title) {
final Ref<Result> result = Ref.create();
new Task.Modal(myProject, title, false) {
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface MavenRemoteTask<Result, Argument> {
@NotNull
Result execute(@NotNull Argument arg, ProgressIndicator indicator);
String getName(@NotNull Argument arg);
@@ -18,6 +18,7 @@ package org.jetbrains.idea.maven.utils.library.remote;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.dom.MavenVersionComparable;
import org.jetbrains.idea.maven.model.MavenRemoteRepository;
import org.jetbrains.idea.maven.model.MavenRepositoryInfo;
@@ -49,10 +50,12 @@ public class MavenVersionsRemoteManager
schedule(this, RepositoryLibraryDescription.findDescription(groupId, artifactId), resultProcessor, false);
}
@Nullable
public List<String> getMavenArtifactVersions(String groupId, String artifactId) {
return getSynchronously(this, RepositoryLibraryDescription.findDescription(groupId, artifactId));
}
@NotNull
@Override
public List<String> execute(@NotNull RepositoryLibraryDescription repositoryLibraryDescription, ProgressIndicator indicator) {
MavenEmbeddersManager manager = MavenProjectsManager.getInstance(myProject).getEmbeddersManager();
@@ -40,6 +40,8 @@ for arg in sys.argv:
argv.append(arg)
sys.argv = argv
cwd = os.getcwd()
main()
if run_cov:
os.chdir(cwd)
main(["xml", "-o", coverage_file + ".xml", "--ignore-errors"])
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -18,12 +18,14 @@ package com.intellij.spellchecker.compress;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import java.util.Arrays;
public final class Alphabet {
private final char[] letters;
private int lastIndexUsed;
private static final int MAX_INDEX = UnitBitSet.MAX_UNIT_VALUE;
public char getLetter(int position) {
char getLetter(int position) {
return letters[position];
}
@@ -40,7 +42,7 @@ public final class Alphabet {
@param forceAdd - if set to true - letter will be added to the alphabet if not present yet
@return index of the letter or -1 if letter was not found and could not be added (due to forceAdd property value)
*/
public int getNextIndex(int startFrom, char letter, boolean forceAdd) {
private int getNextIndex(int startFrom, char letter, boolean forceAdd) {
for (int i = startFrom; i <= lastIndexUsed; i++) {
if (i == letters.length) return -1;
if (letters[i] != 0 && letters[i] == letter) {
@@ -53,7 +55,7 @@ public final class Alphabet {
return add(letter);
}
public int getLastIndexUsed() {
int getLastIndexUsed() {
return lastIndexUsed;
}
@@ -69,7 +71,7 @@ public final class Alphabet {
this(MAX_INDEX);
}
Alphabet(int maxIndex) {
private Alphabet(int maxIndex) {
assert maxIndex <= MAX_INDEX : "alphabet is too long";
letters = new char[maxIndex];
}
@@ -83,4 +85,9 @@ public final class Alphabet {
add(alphabet.charAt(i));
}
}
@Override
public String toString() {
return "Letters[" + lastIndexUsed + "]: '" + Arrays.toString(Arrays.copyOf(letters, lastIndexUsed))+"'";
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -19,25 +19,25 @@ import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
public class UnitBitSet {
public static final int MAX_CHARS_IN_WORD = 64;
public static final int MAX_UNIT_VALUE = 255;
class UnitBitSet {
static final int MAX_CHARS_IN_WORD = 64;
static final int MAX_UNIT_VALUE = 255;
final byte[] b;
private final Alphabet alpha;
public UnitBitSet(@NotNull byte[] indices, @NotNull Alphabet alphabet) {
UnitBitSet(@NotNull byte[] indices, @NotNull Alphabet alphabet) {
b = indices;
alpha = alphabet;
}
public int getUnitValue(int number) {
int getUnitValue(int number) {
final int r = b[number] & 0xFF;
assert r >= 0 && r <= MAX_UNIT_VALUE : "invalid unit value";
return r;
}
public void setUnitValue(int number, int value) {
void setUnitValue(int number, int value) {
assert value >= 0 : "unit value is negative" + value;
assert value <= MAX_UNIT_VALUE : "unit value is too big";
b[number] = (byte)value;
@@ -45,8 +45,7 @@ public class UnitBitSet {
@Override
public boolean equals(Object obj) {
if (!(obj instanceof UnitBitSet)) return false;
return Arrays.equals(b, ((UnitBitSet)obj).b);
return obj instanceof UnitBitSet && Arrays.equals(b, ((UnitBitSet)obj).b);
}
@Override
@@ -61,7 +60,7 @@ public class UnitBitSet {
@NotNull
public byte[] pack() {
int meaningfulBits = 32 - Integer.numberOfLeadingZeros(alpha.getLastIndexUsed());
assert meaningfulBits <= 8 && meaningfulBits >= 1 : meaningfulBits + ": "+alpha.getLastIndexUsed();
assert meaningfulBits <= 8 && meaningfulBits >= 1 : meaningfulBits + ": "+alpha;
byte[] result = new byte[(b.length * meaningfulBits + 7) / 8];
int byteNumber = 0;
@@ -87,7 +86,7 @@ public class UnitBitSet {
@NotNull
public static String decode(@NotNull byte[] packed, @NotNull Alphabet alphabet) {
int meaningfulBits = 32 - Integer.numberOfLeadingZeros(alphabet.getLastIndexUsed());
assert meaningfulBits <= 8;
assert meaningfulBits <= 8 : alphabet;
StringBuilder result = new StringBuilder(packed.length * 8 / meaningfulBits);
@@ -105,7 +104,7 @@ public class UnitBitSet {
curByte >>>= meaningfulBits;
bitOffset += meaningfulBits;
assert bitOffset <= 8;
assert bitOffset <= 8 : alphabet;
if (bitOffset + meaningfulBits > 8) {
if (++byteIndex == packed.length) break;
int leftOverBits = 8 - bitOffset;
@@ -116,9 +115,9 @@ public class UnitBitSet {
return result.toString();
}
public static int getFirstLetterIndex(byte firstPackedByte, @NotNull Alphabet alphabet) {
static int getFirstLetterIndex(byte firstPackedByte, @NotNull Alphabet alphabet) {
int meaningfulBits = 32 - Integer.numberOfLeadingZeros(alphabet.getLastIndexUsed());
assert meaningfulBits <= 8;
assert meaningfulBits <= 8 : alphabet;
int index = firstPackedByte & ((1 << meaningfulBits) - 1);
return index;
@@ -303,9 +303,44 @@ public class GenerateXmlTagAction extends SimpleCodeInsightAction {
}
}
private static boolean isInsideTagBody(@NotNull Editor editor, @NotNull PsiFile file) {
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
while (element != null && !(element.getParent() instanceof XmlTag)) {
element = element.getParent();
}
if (element == null) {
return false;
}
if (element.getNode().getElementType() == XmlTokenType.XML_START_TAG_START) {
return true;
} else {
PsiElement left = element.getPrevSibling();
while (left != null && left.getNode().getElementType() != XmlTokenType.XML_TAG_END) {
left = left.getPrevSibling();
}
if (left == null) {
return false;
}
PsiElement right = element.getNextSibling();
while (right != null && right.getNode().getElementType() != XmlTokenType.XML_END_TAG_START) {
right = right.getNextSibling();
}
if (right == null) {
return false;
}
return true;
}
}
@Override
protected boolean isValidForFile(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
if (!(file instanceof XmlFile)) return false;
if (!isInsideTagBody(editor, file)) {
return false;
}
XmlTag contextTag = getContextTag(editor, file);
return contextTag != null && contextTag.getDescriptor() != null;
}
@@ -70,6 +70,10 @@ public class GenerateXmlTagTest extends LightPlatformCodeInsightFixtureTestCase
doTest("initParam.xml", "context-param");
}
public void testInTagName() {
doTest("try_to_generate_in_tag_name.xml", "context-param");
}
private void doTest(String file, String tagName) {
GenerateXmlTagAction.TEST_THREAD_LOCAL.set(tagName);
CodeInsightTestUtil.doActionTest(new GenerateXmlTagAction(), file, myFixture);
@@ -0,0 +1,7 @@
<html>
<body>
<div<caret>>
</div>
</body>
</html>
@@ -0,0 +1,7 @@
<html>
<body>
<div>
</div>
</body>
</html>