Merge remote-tracking branch 'origin/master'

This commit is contained in:
Sergey Malenkov
2015-02-13 21:59:17 +03:00
50 changed files with 535 additions and 201 deletions
+22 -40
View File
@@ -125,7 +125,7 @@ IDE_BIN_HOME=`dirname "$SCRIPT_LOCATION"`
# Collect JVM options and properties.
# ---------------------------------------------------------------------
if [ -n "$@@product_uc@@_PROPERTIES" ]; then
IDE_PROPERTIES_PROPERTY="-Didea.properties.file=\"$@@product_uc@@_PROPERTIES\""
IDE_PROPERTIES_PROPERTY="-Didea.properties.file=$@@product_uc@@_PROPERTIES"
fi
MAIN_CLASS_NAME="$@@product_uc@@_MAIN_CLASS_NAME"
@@ -133,41 +133,18 @@ if [ -z "$MAIN_CLASS_NAME" ]; then
MAIN_CLASS_NAME="com.intellij.idea.Main"
fi
VM_OPTIONS_FILES_0=$IDE_BIN_HOME/@@vm_options@@$BITS.vmoptions
VM_OPTIONS_FILES_1=$HOME/.@@system_selector@@/@@vm_options@@$BITS.vmoptions
VM_OPTIONS_FILES_2=$@@product_uc@@_VM_OPTIONS
VM_OPTIONS=""
VM_OPTIONS_FILES_USED=""
if [ -r "$VM_OPTIONS_FILES_0" ]; then
VM_OPTIONS_DATA=`"$CAT" "$VM_OPTIONS_FILES_0" | "$GREP" -v "^#.*" | "$TR" '\n' ' '`
VM_OPTIONS="$VM_OPTIONS $VM_OPTIONS_DATA"
if [ -n "$VM_OPTIONS_FILES_USED" ]; then
VM_OPTIONS_FILES_USED="$VM_OPTIONS_FILES_USED,"
for vm_opts_file in "$@@product_uc@@_VM_OPTIONS" "$HOME/.@@system_selector@@/@@vm_options@@$BITS.vmoptions" "$IDE_BIN_HOME/@@vm_options@@$BITS.vmoptions"; do
if [ -r "$vm_opts_file" ]; then
VM_OPTIONS_DATA=`"$CAT" "$vm_opts_file" | "$GREP" -v "^#.*" | "$TR" '\n' ' '`
VM_OPTIONS="$VM_OPTIONS $VM_OPTIONS_DATA"
if [ -n "$VM_OPTIONS_FILES_USED" ]; then
VM_OPTIONS_FILES_USED="$VM_OPTIONS_FILES_USED,"
fi
VM_OPTIONS_FILES_USED="$VM_OPTIONS_FILES_USED$vm_opts_file"
fi
VM_OPTIONS_FILES_USED="$VM_OPTIONS_FILES_USED$VM_OPTIONS_FILES_0"
fi
if [ -r "$VM_OPTIONS_FILES_1" ]; then
VM_OPTIONS_DATA=`"$CAT" "$VM_OPTIONS_FILES_1" | "$GREP" -v "^#.*" | "$TR" '\n' ' '`
VM_OPTIONS="$VM_OPTIONS $VM_OPTIONS_DATA"
if [ -n "$VM_OPTIONS_FILES_USED" ]; then
VM_OPTIONS_FILES_USED="$VM_OPTIONS_FILES_USED,"
fi
VM_OPTIONS_FILES_USED="$VM_OPTIONS_FILES_USED$VM_OPTIONS_FILES_1"
fi
if [ -r "$VM_OPTIONS_FILES_2" ]; then
VM_OPTIONS_DATA=`"$CAT" "$VM_OPTIONS_FILES_2" | "$GREP" -v "^#.*" | "$TR" '\n' ' '`
VM_OPTIONS="$VM_OPTIONS $VM_OPTIONS_DATA"
if [ -n "$VM_OPTIONS_FILES_USED" ]; then
VM_OPTIONS_FILES_USED="$VM_OPTIONS_FILES_USED,"
fi
VM_OPTIONS_FILES_USED="$VM_OPTIONS_FILES_USED$VM_OPTIONS_FILES_2"
fi
VM_OPTIONS="$VM_OPTIONS -Djb.vmOptionsFile=\"$VM_OPTIONS_FILES_USED\""
done
IS_EAP="@@isEap@@"
if [ "$IS_EAP" = "true" ]; then
@@ -178,23 +155,28 @@ if [ "$IS_EAP" = "true" ]; then
fi
fi
COMMON_JVM_ARGS="-XX:ErrorFile=$HOME/java_error_in_@@product_uc@@_%p.log \"-Xbootclasspath/a:$IDE_HOME/lib/boot.jar\" -Didea.paths.selector=@@system_selector@@ $IDE_PROPERTIES_PROPERTY"
IDE_JVM_ARGS="@@ide_jvm_args@@"
ALL_JVM_ARGS="$VM_OPTIONS $COMMON_JVM_ARGS $IDE_JVM_ARGS $AGENT $REQUIRED_JVM_ARGS"
@@class_path@@
if [ -n "$@@product_uc@@_CLASSPATH" ]; then
CLASSPATH="$CLASSPATH:$@@product_uc@@_CLASSPATH"
fi
export CLASSPATH
LD_LIBRARY_PATH="$IDE_BIN_HOME:$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH
# ---------------------------------------------------------------------
# Run the IDE.
# ---------------------------------------------------------------------
while true ; do
eval "$JDK/bin/java" $ALL_JVM_ARGS -Djb.restart.code=88 $MAIN_CLASS_NAME "$@"
LD_LIBRARY_PATH="$IDE_BIN_HOME:$LD_LIBRARY_PATH" "$JDK/bin/java" \
$AGENT \
"-Xbootclasspath/a:$IDE_HOME/lib/boot.jar" \
-classpath "$CLASSPATH" \
$VM_OPTIONS "-Djb.vmOptionsFile=$VM_OPTIONS_FILES_USED" \
"-XX:ErrorFile=$HOME/java_error_in_@@product_uc@@_%p.log" \
-Djb.restart.code=88 -Didea.paths.selector=@@system_selector@@ \
$IDE_PROPERTIES_PROPERTY \
$IDE_JVM_ARGS \
$REQUIRED_JVM_ARGS \
$MAIN_CLASS_NAME \
"$@"
test $? -ne 88 && break
done
@@ -27,6 +27,7 @@ import com.intellij.debugger.engine.events.DebuggerCommandImpl;
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.settings.ToStringBasedRenderer;
import com.intellij.debugger.ui.impl.DebuggerTreeRenderer;
import com.intellij.debugger.ui.impl.watch.*;
import com.intellij.debugger.ui.tree.*;
@@ -260,7 +261,8 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
renderer.renderStringValue(myValue, "\"\\", XValueNode.MAX_VALUE_LENGTH);
return;
}
else if (myValueDescriptor.getLastRenderer() instanceof ToStringRenderer) {
else if (myValueDescriptor.getLastRenderer() instanceof ToStringRenderer ||
myValueDescriptor.getLastRenderer() instanceof ToStringBasedRenderer) {
value = StringUtil.wrapWithDoubleQuote(truncateToMaxLength(myValue));
}
else if (myValueDescriptor.getLastRenderer() instanceof CompoundReferenceRenderer) {
@@ -45,7 +45,7 @@ public class LambdaHighlightingUtil {
if (signatures.size() == 1) {
return null;
}
return "Multiple non-overriding abstract methods found";
return "Multiple non-overriding abstract methods found in interface " + HighlightUtil.formatClass(psiClass);
}
@Nullable
@@ -25,6 +25,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PsiJavaElementPattern;
import com.intellij.psi.*;
import com.intellij.psi.filters.ClassFilter;
@@ -40,6 +41,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.List;
import static com.intellij.patterns.PsiJavaPatterns.psiClass;
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
/**
@@ -50,6 +52,8 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
private static final PsiJavaElementPattern.Capture<PsiElement> IN_TYPE_PARAMETER =
psiElement().afterLeaf(PsiKeyword.EXTENDS, PsiKeyword.SUPER, "&").withParent(
psiElement(PsiReferenceList.class).withParent(PsiTypeParameter.class));
private static final ElementPattern<PsiElement> IN_EXTENDS_IMPLEMENTS =
psiElement().inside(psiElement(PsiReferenceList.class).withParent(psiClass()));
@Override
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull final CompletionResultSet _result) {
@@ -86,6 +90,7 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
final PsiElement insertedElement = parameters.getPosition();
final ElementFilter filter =
IN_EXTENDS_IMPLEMENTS.accepts(insertedElement) ? new ExcludeDeclaredFilter(new ClassFilter(PsiClass.class)) :
IN_TYPE_PARAMETER.accepts(insertedElement) ? new ExcludeDeclaredFilter(new ClassFilter(PsiTypeParameter.class)) :
JavaCompletionContributor.ANNOTATION_NAME.accepts(insertedElement) ? new AnnotationTypeFilter() :
TrueFilter.INSTANCE;
@@ -39,9 +39,7 @@ public class AfterSemicolonEnterProcessor implements EnterProcessor {
psiElement instanceof PsiAssertStatement ||
psiElement instanceof PsiField ||
psiElement instanceof PsiImportStatementBase ||
psiElement instanceof PsiMethod && (((PsiMethod) psiElement).getContainingClass().isInterface() ||
((PsiMethod) psiElement).hasModifierProperty(PsiModifier.ABSTRACT) ||
((PsiMethod) psiElement).hasModifierProperty(PsiModifier.NATIVE))) {
psiElement instanceof PsiMethod && !MissingMethodBodyFixer.shouldHaveBody((PsiMethod)psiElement)) {
int errorOffset = getErrorElementOffset(psiElement);
int elementEndOffset = psiElement.getTextRange().getEndOffset();
if (psiElement instanceof PsiEnumConstant) {
@@ -21,6 +21,8 @@ import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import static com.intellij.psi.PsiModifier.*;
/**
* Created by IntelliJ IDEA.
* User: max
@@ -34,8 +36,7 @@ public class MissingMethodBodyFixer implements Fixer {
if (!(psiElement instanceof PsiMethod)) return;
PsiMethod method = (PsiMethod) psiElement;
final PsiClass containingClass = method.getContainingClass();
if (containingClass == null || containingClass.isInterface()
|| method.hasModifierProperty(PsiModifier.ABSTRACT) || method.hasModifierProperty(PsiModifier.NATIVE)) return;
if (!shouldHaveBody(method)) return;
final PsiCodeBlock body = method.getBody();
final Document doc = editor.getDocument();
@@ -62,4 +63,12 @@ public class MissingMethodBodyFixer implements Fixer {
}
doc.insertString(endOffset, "{\n}");
}
static boolean shouldHaveBody(PsiMethod method) {
PsiClass containingClass = method.getContainingClass();
if (containingClass == null) return false;
if (containingClass.isInterface() && !method.hasModifierProperty(DEFAULT)) return false;
if (method.hasModifierProperty(ABSTRACT)) return false;
return !method.hasModifierProperty(NATIVE);
}
}
@@ -102,8 +102,7 @@ public class SemicolonFixer implements Fixer {
!(psiElement instanceof PsiAssertStatement) &&
!(psiElement instanceof PsiPackageStatement) &&
(!(psiElement instanceof PsiField) || psiElement instanceof PsiEnumConstant) &&
(!(psiElement instanceof PsiMethod) || (!((PsiMethod)psiElement).getContainingClass().isInterface() &&
!((PsiMethod)psiElement).hasModifierProperty(PsiModifier.ABSTRACT)))) {
(!(psiElement instanceof PsiMethod) || ((PsiMethod)psiElement).getBody() != null || MissingMethodBodyFixer.shouldHaveBody((PsiMethod)psiElement))) {
return false;
}
String text = psiElement.getText();
@@ -165,16 +165,20 @@ public class InferenceSession {
7) A conditional expression (15.25) whose second or third operand is not pertinent to applicability.
*/
public static boolean isPertinentToApplicability(PsiExpression expr, PsiMethod method) {
return isPertinentToApplicability(expr, method, null);
}
private static boolean isPertinentToApplicability(PsiExpression expr, PsiMethod method, PsiType expectedReturnType) {
if (expr instanceof PsiLambdaExpression && ((PsiLambdaExpression)expr).hasFormalParameterTypes() ||
expr instanceof PsiMethodReferenceExpression && ((PsiMethodReferenceExpression)expr).isExact()) {
if (method != null && method.getTypeParameters().length > 0) {
final PsiElement parent = PsiUtil.skipParenthesizedExprUp(expr.getParent());
PsiType paramType = null;
if (parent instanceof PsiExpressionList) {
final PsiElement gParent = parent.getParent();
if (gParent instanceof PsiCallExpression && ((PsiCallExpression)gParent).getTypeArgumentList().getTypeParameterElements().length == 0) {
final int idx = LambdaUtil.getLambdaIdx(((PsiExpressionList)parent), expr);
final PsiParameter[] parameters = method.getParameterList().getParameters();
PsiType paramType;
if (idx > parameters.length - 1) {
final PsiType lastParamType = parameters[parameters.length - 1].getType();
paramType = parameters[parameters.length - 1].isVarArgs() ? ((PsiEllipsisType)lastParamType).getComponentType() : lastParamType;
@@ -182,20 +186,24 @@ public class InferenceSession {
else {
paramType = parameters[idx].getType();
}
final PsiClass psiClass = PsiUtil.resolveClassInType(paramType); //accept ellipsis here
if (psiClass instanceof PsiTypeParameter && ((PsiTypeParameter)psiClass).getOwner() == method) return false;
if (isTypeParameterType(method, paramType)) return false;
}
}
else if (expectedReturnType != null && parent instanceof PsiLambdaExpression) {
if (isTypeParameterType(method, expectedReturnType)) return false;
paramType = expectedReturnType;
}
if (expr instanceof PsiLambdaExpression) {
for (PsiExpression expression : LambdaUtil.getReturnExpressions((PsiLambdaExpression)expr)) {
if (!isPertinentToApplicability(expression, method, LambdaUtil.getFunctionalInterfaceReturnType(paramType))) return false;
}
return true;
}
}
}
if (expr instanceof PsiLambdaExpression) {
if (!((PsiLambdaExpression)expr).hasFormalParameterTypes()) {
return false;
}
for (PsiExpression expression : LambdaUtil.getReturnExpressions((PsiLambdaExpression)expr)) {
if (!isPertinentToApplicability(expression, method)) return false;
}
return true;
return ((PsiLambdaExpression)expr).hasFormalParameterTypes();
}
if (expr instanceof PsiMethodReferenceExpression) {
return ((PsiMethodReferenceExpression)expr).isExact();
@@ -212,6 +220,12 @@ public class InferenceSession {
return true;
}
private static boolean isTypeParameterType(PsiMethod method, PsiType paramType) {
final PsiClass psiClass = PsiUtil.resolveClassInType(paramType); //accept ellipsis here
if (psiClass instanceof PsiTypeParameter && ((PsiTypeParameter)psiClass).getOwner() == method) return true;
return false;
}
private static PsiType getParameterType(PsiParameter[] parameters, int i, @Nullable PsiSubstitutor substitutor, boolean varargs) {
if (substitutor == null) return null;
PsiType parameterType = substitutor.substitute(parameters[i < parameters.length ? i : parameters.length - 1].getType());
@@ -294,7 +308,7 @@ public class InferenceSession {
if (calledMethod != null && PsiPolyExpressionUtil.isMethodCallPolyExpression(arg, calledMethod)) {
collectAdditionalConstraints(additionalConstraints, (PsiCallExpression)arg);
}
} else if (arg instanceof PsiLambdaExpression) {
} else if (arg instanceof PsiLambdaExpression && !isProperType(retrieveNonPrimitiveEqualsBounds(myInferenceVariables).substitute(parameterType))) {
collectLambdaReturnExpression(additionalConstraints, (PsiLambdaExpression)arg, parameterType);
}
}
@@ -22,9 +22,6 @@ public class LambdaExpressionCompatibilityConstraint implements ConstraintFormul
@Override
public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
if (session.getInferenceVariable(myT) != null) {
return true;
}
if (!LambdaUtil.isFunctionalType(myT)) {
return false;
}
@@ -602,7 +602,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
@NotNull PsiMethod method2) {
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && method1.getTypeParameters().length > 0 && myArgumentsList instanceof PsiExpressionList) {
final PsiElement parent = myArgumentsList.getParent();
if (parent instanceof PsiCallExpression && ((PsiCallExpression)parent).getTypeArguments().length == 0) {
if (parent instanceof PsiCallExpression) {
return InferenceSession.isMoreSpecific(method2, method1, ((PsiExpressionList)myArgumentsList).getExpressions(), myArgumentsList, varargsPosition);
}
}
@@ -0,0 +1,3 @@
public interface Foo {
default void foo(<caret>)
}
@@ -0,0 +1,5 @@
public interface Foo {
default void foo() {
<caret>
}
}
@@ -0,0 +1,2 @@
public class Fooxxxx extends Foox<caret>x
public class Fooxxxx2 {}
@@ -0,0 +1,15 @@
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class Test {
private List<Map<String, String>> foo(Stream<Map.Entry<String, List<String>>> stream) {
return then(v -> stream.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().toString())));
}
private <V> List<V> then(Function<Void, V> f) {
return null;
}
}
@@ -1,4 +1,4 @@
<error descr="Multiple non-overriding abstract methods found">@FunctionalInterface</error>
<error descr="Multiple non-overriding abstract methods found in interface Test">@FunctionalInterface</error>
interface Test {
void foo();
void bar();
@@ -36,7 +36,7 @@ class Test2 {
}
{
F f = <error descr="Multiple non-overriding abstract methods found">() -> g()</error>;
F f = <error descr="Multiple non-overriding abstract methods found in interface Test2.F">() -> g()</error>;
}
void g() {}
@@ -8,7 +8,7 @@ public class NotAFIT {
}
void bar() {
foo(<error descr="Multiple non-overriding abstract methods found">() ->{}</error>);
foo(<error descr="Multiple non-overriding abstract methods found in interface NotAFIT.First.A">() ->{}</error>);
}
}
@@ -25,7 +25,7 @@ public class NotAFIT {
}
void bar() {
foo(<error descr="Multiple non-overriding abstract methods found">()->{}</error>);
foo(<error descr="Multiple non-overriding abstract methods found in interface NotAFIT.WithInheritance.B">()->{}</error>);
}
}
@@ -0,0 +1,13 @@
class Test<T> {
Test(T arg) {}
Test(String arg) {}
static <X> Test<X> m(X arg) {return null;}
static <X> Test<X> m(String arg) {return null;}
{
m("");
Test.<String>m("");
new Test<>("");
new Test<String><error descr="Cannot resolve constructor 'Test(java.lang.String)'">("")</error>;
}
}
@@ -9,3 +9,13 @@ class Test {
return null;
}
}
class Test1 {
{
Supplier<Runnable> x = foo(() -> <error descr="Multiple non-overriding abstract methods found in interface java.util.List">() -> null</error>);
}
static <T> Supplier<T> foo(Supplier<java.util.List<T>> delegate) {
return null;
}
}
@@ -60,10 +60,14 @@ public abstract class ClsGenericsHighlightingTest extends UsefulTestCase {
@Override
protected void tearDown() throws Exception {
super.tearDown();
myFixture.tearDown();
myFixture = null;
myModule = null;
try {
myFixture.tearDown();
}
finally {
myFixture = null;
myModule = null;
super.tearDown();
}
}
protected void doTest() {
@@ -269,7 +269,9 @@ public class CompleteStatementTest extends EditorActionTestCase {
public void testCompleteMethodCallAtReturn() throws Exception { doTest(); }
public void testGenericMethodBody() throws Exception { doTest(); }
public void testDefaultMethodBody() { doTest(); }
public void testArrayInitializerRBracket() throws Exception { doTest(); }
public void testReturnInLambda() { doTest(); }
@@ -843,6 +843,11 @@ public class ListUtils {
assertStringItems 'Inner'
}
public void testNoThisClassInExtends() throws Throwable {
configure()
assertStringItems 'Fooxxxx2'
}
public void testPrimitiveTypesInForLoop() throws Throwable { doPrimitiveTypeTest() }
public void testPrimitiveTypesInForLoop2() throws Throwable { doPrimitiveTypeTest() }
public void testPrimitiveTypesInForLoop3() throws Throwable { doPrimitiveTypeTest() }
@@ -52,7 +52,7 @@ public class FunctionalInterfaceTest extends LightDaemonAnalyzerTestCase {
}
public void testClone() throws Exception {
doTestFunctionalInterface("Multiple non-overriding abstract methods found");
doTestFunctionalInterface("Multiple non-overriding abstract methods found in interface Foo");
}
public void testTwoMethodsSameSignature() throws Exception {
@@ -64,11 +64,11 @@ public class FunctionalInterfaceTest extends LightDaemonAnalyzerTestCase {
}
public void testTwoMethodsNoSubSignature() throws Exception {
doTestFunctionalInterface("Multiple non-overriding abstract methods found");
doTestFunctionalInterface("Multiple non-overriding abstract methods found in interface Foo");
}
public void testTwoMethodsNoSubSignature1() throws Exception {
doTestFunctionalInterface("Multiple non-overriding abstract methods found");
doTestFunctionalInterface("Multiple non-overriding abstract methods found in interface Foo");
}
public void testTwoMethodsSameSubstSignature() throws Exception {
@@ -122,6 +122,10 @@ public class MostSpecificResolutionTest extends LightDaemonAnalyzerTestCase {
doTest(false);
}
public void testInferSpecificForGenericMethodWhenCallProvidesExplicitTypeArguments() throws Exception {
doTest(false);
}
private void doTest() {
doTest(true);
}
@@ -28,6 +28,10 @@ public class NewInferenceCollectingAdditionalConstraintsTest extends LightDaemon
doTest();
}
public void testStopCollectingAdditionalConstraintsWhenLambdaReturnTypeIsProper() throws Exception {
doTest();
}
private void doTest() {
doTest(true);
}
@@ -30,13 +30,13 @@ public class JavaParametersTest extends ModuleRootManagerTestCase {
public void testLibrary() throws Exception {
ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary());
assertClasspath(myModule, JavaParameters.JDK_AND_CLASSES_AND_TESTS,
getRtJar(), getJDomJar());
getRtJarJdk17(), getJDomJar());
assertClasspath(myModule, JavaParameters.CLASSES_ONLY,
getJDomJar());
assertClasspath(myModule, JavaParameters.CLASSES_AND_TESTS,
getJDomJar());
assertClasspath(myProject, JavaParameters.JDK_AND_CLASSES_AND_TESTS,
getRtJar(), getJDomJar());
getRtJarJdk17(), getJDomJar());
}
public void testModuleSourcesAndOutput() throws Exception {
@@ -50,7 +50,7 @@ public class JavaParametersTest extends ModuleRootManagerTestCase {
assertClasspath(myModule, JavaParameters.CLASSES_AND_TESTS,
testOutput, output);
assertClasspath(myModule, JavaParameters.JDK_AND_CLASSES_AND_TESTS,
getRtJar(), testOutput, output);
getRtJarJdk17(), testOutput, output);
}
public void testLibraryScope() throws Exception {
@@ -59,20 +59,7 @@ public class IndexTest extends JavaCodeInsightFixtureTestCase {
}
public void testUpdate() throws StorageException, IOException {
final File storageFile = FileUtil.createTempFile("indextest", "storage");
final File metaIndexFile = FileUtil.createTempFile("indextest_inputs", "storage");
final MapIndexStorage indexStorage = new MapIndexStorage(storageFile, new EnumeratorStringDescriptor(), new EnumeratorStringDescriptor(), 16 * 1024);
final StringIndex index = new StringIndex(indexStorage, new Factory<PersistentHashMap<Integer, Collection<String>>>() {
@Override
public PersistentHashMap<Integer, Collection<String>> create() {
try {
return createMetaIndex(metaIndexFile);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
});
StringIndex index = createIndex(new EnumeratorStringDescriptor())
try {
// build index
@@ -119,6 +106,44 @@ public class IndexTest extends JavaCodeInsightFixtureTestCase {
}
}
public void testUpdateWithCustomEqualityPolicy() {
def index = createIndex(new CaseInsensitiveEnumeratorStringDescriptor())
try {
index.update("a.java", "x", null)
assertDataEquals(index.getFilesByWord("x"), "a.java")
index.flush() //todo: this should not be required but the following line will fail without it
assertDataEquals(index.getFilesByWord("X"), "a.java")
index.update("b.java", "y", null)
assertDataEquals(index.getFilesByWord("y"), "b.java")
index.update("c.java", "Y", null)
index.flush() //todo: this should not be required but the following line will fail without it
assertDataEquals(index.getFilesByWord("y"), "b.java", "c.java")
}
finally {
index.dispose()
}
}
private static StringIndex createIndex(EnumeratorStringDescriptor keyDescriptor) {
final File storageFile = FileUtil.createTempFile("indextest", "storage");
final File metaIndexFile = FileUtil.createTempFile("indextest_inputs", "storage");
final MapIndexStorage indexStorage = new MapIndexStorage(storageFile, keyDescriptor, new EnumeratorStringDescriptor(), 16 * 1024);
final StringIndex index = new StringIndex(indexStorage, new Factory<PersistentHashMap<Integer, Collection<String>>>() {
@Override
public PersistentHashMap<Integer, Collection<String>> create() {
try {
return createMetaIndex(metaIndexFile);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
});
index
}
private static PersistentHashMap<Integer, Collection<String>> createMetaIndex(File metaIndexFile) throws IOException {
return new PersistentHashMap<Integer, Collection<String>>(metaIndexFile, new EnumeratorIntegerDescriptor(), new DataExternalizer<Collection<String>>() {
@Override
@@ -142,7 +167,7 @@ public class IndexTest extends JavaCodeInsightFixtureTestCase {
}
private static <T> void assertDataEquals(List<T> actual, T... expected) {
assertTrue(new HashSet<T>(Arrays.asList(expected)).equals(new HashSet<T>(actual)));
assertSameElements(actual, expected);
}
public void testCollectedPsiWithChangedDocument() throws IOException {
@@ -48,14 +48,18 @@ public class StringIndex {
}
public void update(final String path, @Nullable String content, @Nullable String oldContent) throws StorageException {
myIndex.update(path.hashCode(), toInput(path, content)).compute();
myIndex.update(Math.abs(path.hashCode()), toInput(path, content)).compute();
}
public void flush() throws StorageException {
myIndex.flush();
}
public void dispose() {
myIndex.dispose();
}
@Nullable
@Nullable
private PathContentPair toInput(@NotNull String path, @Nullable String content) {
return content != null ? new PathContentPair(path, content) : null;
}
@@ -9,9 +9,11 @@ import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.ModuleTestCase;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.util.PathsList;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
@@ -25,7 +27,20 @@ public abstract class ModuleRootManagerTestCase extends ModuleTestCase {
@Override
protected Sdk getTestProjectJdk() {
final Sdk jdk = super.getTestProjectJdk();
return getMockJdk17WithRtJarOnly();
}
@NotNull
protected static Sdk getMockJdk17WithRtJarOnly() {
return retainRtJarOnly(IdeaTestUtil.getMockJdk17());
}
protected Sdk getMockJdk18WithRtJarOnly() {
return retainRtJarOnly(IdeaTestUtil.getMockJdk18());
}
@NotNull
private static Sdk retainRtJarOnly(Sdk jdk) {
final SdkModificator modificator = jdk.getSdkModificator();
VirtualFile rtJar = null;
for (VirtualFile root : modificator.getRoots(OrderRootType.CLASSES)) {
@@ -41,8 +56,12 @@ public abstract class ModuleRootManagerTestCase extends ModuleTestCase {
return jdk;
}
protected VirtualFile getRtJar() {
return getTestProjectJdk().getRootProvider().getFiles(OrderRootType.CLASSES)[0];
protected VirtualFile getRtJarJdk17() {
return getMockJdk17WithRtJarOnly().getRootProvider().getFiles(OrderRootType.CLASSES)[0];
}
protected VirtualFile getRtJarJdk18() {
return getMockJdk18WithRtJarOnly().getRootProvider().getFiles(OrderRootType.CLASSES)[0];
}
protected VirtualFile getJDomJar() {
@@ -11,7 +11,7 @@ import com.intellij.util.PathsList;
public class OrderEntriesTest extends ModuleRootManagerTestCase {
public void testLibrary() throws Exception {
ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary());
assertOrderFiles(OrderRootType.CLASSES, getRtJar(), getJDomJar());
assertOrderFiles(OrderRootType.CLASSES, getRtJarJdk17(), getJDomJar());
assertOrderFiles(OrderRootType.SOURCES, getJDomSources());
}
@@ -19,14 +19,14 @@ public class OrderEntriesTest extends ModuleRootManagerTestCase {
final VirtualFile srcRoot = addSourceRoot(myModule, false);
final VirtualFile testRoot = addSourceRoot(myModule, true);
assertOrderFiles(OrderRootType.CLASSES, getRtJar());
assertOrderFiles(OrderRootType.CLASSES, getRtJarJdk17());
assertOrderFiles(OrderRootType.SOURCES, srcRoot, testRoot);
}
public void testLibraryScope() throws Exception {
ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary(), DependencyScope.TEST, false);
assertOrderFiles(OrderRootType.CLASSES, getRtJar(), getJDomJar());
assertOrderFiles(OrderRootType.CLASSES, getRtJarJdk17(), getJDomJar());
assertOrderFiles(OrderRootType.SOURCES, getJDomSources());
}
@@ -37,7 +37,7 @@ public class OrderEntriesTest extends ModuleRootManagerTestCase {
ModuleRootModificationUtil.addDependency(dep, createJDomLibrary(), DependencyScope.COMPILE, true);
ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false);
assertOrderFiles(OrderRootType.CLASSES, getRtJar(), getJDomJar());
assertOrderFiles(OrderRootType.CLASSES, getRtJarJdk17(), getJDomJar());
assertOrderFiles(OrderRootType.SOURCES, srcRoot, testRoot, getJDomSources());
}
@@ -46,7 +46,7 @@ public class OrderEntriesTest extends ModuleRootManagerTestCase {
ModuleRootModificationUtil.addDependency(dep, createJDomLibrary(), DependencyScope.COMPILE, true);
ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.TEST, true);
assertOrderFiles(OrderRootType.CLASSES, getRtJar(), getJDomJar());
assertOrderFiles(OrderRootType.CLASSES, getRtJarJdk17(), getJDomJar());
assertOrderFiles(OrderRootType.SOURCES, getJDomSources());
}
@@ -55,7 +55,7 @@ public class OrderEntriesTest extends ModuleRootManagerTestCase {
ModuleRootModificationUtil.addDependency(dep, createJDomLibrary(), DependencyScope.COMPILE, false);
ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false);
assertOrderFiles(OrderRootType.CLASSES, getRtJar());
assertOrderFiles(OrderRootType.CLASSES, getRtJarJdk17());
assertOrderFiles(OrderRootType.SOURCES);
}
@@ -20,10 +20,10 @@ public class OrderEnumeratorTest extends ModuleRootManagerTestCase {
public void testLibrary() throws Exception {
ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary());
assertClassRoots(orderEntries(myModule), getRtJar(), getJDomJar());
assertClassRoots(orderEntries(myModule), getRtJarJdk17(), getJDomJar());
assertClassRoots(orderEntries(myModule).withoutSdk(), getJDomJar());
assertClassRoots(orderEntries(myModule).withoutSdk().productionOnly().runtimeOnly(), getJDomJar());
assertClassRoots(orderEntries(myModule).withoutLibraries(), getRtJar());
assertClassRoots(orderEntries(myModule).withoutLibraries(), getRtJarJdk17());
assertSourceRoots(orderEntries(myModule), getJDomSources());
}
@@ -119,7 +119,7 @@ public class OrderEnumeratorTest extends ModuleRootManagerTestCase {
public void testCaching() throws Exception {
final VirtualFile[] roots = orderEntries(myModule).classes().usingCache().getRoots();
assertOrderedEquals(roots, getRtJar());
assertOrderedEquals(roots, getRtJarJdk17());
assertEquals(roots, orderEntries(myModule).classes().usingCache().getRoots());
final VirtualFile[] rootsWithoutSdk = orderEntries(myModule).withoutSdk().classes().usingCache().getRoots();
assertEmpty(rootsWithoutSdk);
@@ -128,13 +128,13 @@ public class OrderEnumeratorTest extends ModuleRootManagerTestCase {
ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary());
assertRoots(orderEntries(myModule).classes().usingCache().getPathsList(), getRtJar(), getJDomJar());
assertRoots(orderEntries(myModule).classes().usingCache().getPathsList(), getRtJarJdk17(), getJDomJar());
assertRoots(orderEntries(myModule).withoutSdk().classes().usingCache().getPathsList(), getJDomJar());
}
public void testCachingUrls() throws Exception {
final String[] urls = orderEntries(myModule).classes().usingCache().getUrls();
assertOrderedEquals(urls, getRtJar().getUrl());
assertOrderedEquals(urls, getRtJarJdk17().getUrl());
assertSame(urls, orderEntries(myModule).classes().usingCache().getUrls());
final String[] sourceUrls = orderEntries(myModule).sources().usingCache().getUrls();
@@ -143,7 +143,7 @@ public class OrderEnumeratorTest extends ModuleRootManagerTestCase {
assertSame(sourceUrls, orderEntries(myModule).sources().usingCache().getUrls());
ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary());
assertOrderedEquals(orderEntries(myModule).classes().usingCache().getUrls(), getRtJar().getUrl(), getJDomJar().getUrl());
assertOrderedEquals(orderEntries(myModule).classes().usingCache().getUrls(), getRtJarJdk17().getUrl(), getJDomJar().getUrl());
assertOrderedEquals(orderEntries(myModule).sources().usingCache().getUrls(), getJDomSources().getUrl());
}
@@ -173,6 +173,15 @@ public class OrderEnumeratorTest extends ModuleRootManagerTestCase {
srcRoot, testRoot, getJDomSources());
}
public void testDoNotAddJdkRootFromModuleDependency() {
final Module dep = createModule("dep");
ModuleRootModificationUtil.addDependency(myModule, dep);
ModuleRootModificationUtil.setModuleSdk(dep, getMockJdk17WithRtJarOnly());
ModuleRootModificationUtil.setModuleSdk(myModule, getMockJdk18WithRtJarOnly());
assertClassRoots(orderEntries(dep), getRtJarJdk17());
assertClassRoots(orderEntries(myModule).recursively(), getRtJarJdk18());
}
private static void assertClassRoots(final OrderEnumerator enumerator, VirtualFile... files) {
assertEnumeratorRoots(enumerator.classes(), files);
}
@@ -16,10 +16,9 @@
package org.jetbrains.jps.builders.java.dependencyView;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.util.io.CaseInsensitiveEnumeratorStringDescriptor;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorStringDescriptor;
import org.jetbrains.annotations.NotNull;
import java.io.*;
@@ -38,7 +37,7 @@ public class ObjectObjectPersistentMultiMapletTest extends UsefulTestCase {
public void testReplaceWithEqualButNotSameKey() throws IOException {
File file = FileUtil.createTempFile(getTestDirectoryName(), null);
ObjectObjectPersistentMultiMaplet<String, IntValueStreamable> maplet =
new ObjectObjectPersistentMultiMaplet<String, IntValueStreamable>(file, new CaseInsensitiveStringDescriptor(),
new ObjectObjectPersistentMultiMaplet<String, IntValueStreamable>(file, new CaseInsensitiveEnumeratorStringDescriptor(),
new IntValueExternalizer(),
COLLECTION_FACTORY);
maplet.put("a", new IntValueStreamable(1));
@@ -47,18 +46,6 @@ public class ObjectObjectPersistentMultiMapletTest extends UsefulTestCase {
assertEquals(2, assertOneElement(maplet.get("a")).value);
}
private static class CaseInsensitiveStringDescriptor extends EnumeratorStringDescriptor {
@Override
public int getHashCode(String value) {
return StringUtil.stringHashCodeInsensitive(value);
}
@Override
public boolean isEqual(String val1, String val2) {
return val1.equalsIgnoreCase(val2);
}
}
private static class IntValueStreamable implements Streamable {
public int value;
@@ -126,50 +126,43 @@ public class DiffLineSeparatorRenderer implements LineMarkerRenderer, LineSepara
int shiftX,
int shiftY,
int lineHeight) {
Graphics gg = g.create(0, 0, x2 - x1, lineHeight);
gg.translate(shiftX, shiftY);
try {
int halfHeight = lineHeight / 2;
int halfHeight = lineHeight / 2;
int count = ((x2 - x1) / X_STEP + 3);
int count = ((x2 - x1) / X_STEP + 3);
int[] xPoints1 = new int[count];
int[] yPoints1 = new int[count];
int[] xPoints2 = new int[count];
int[] yPoints2 = new int[count];
int[] xPoints1 = new int[count];
int[] yPoints1 = new int[count];
int[] xPoints2 = new int[count];
int[] yPoints2 = new int[count];
int shift = Math.max(x1 - shiftX / X_STEP, 0);
for (int index = 0; index < count; index++) {
int absIndex = index + shift;
int shift = Math.max(x1 - shiftX / X_STEP, 0);
for (int index = 0; index < count; index++) {
int absIndex = index + shift;
int xPos = absIndex * X_STEP + shiftX;
int yPos1;
int yPos2;
int xPos = absIndex * X_STEP + shiftX;
int yPos1;
int yPos2;
if (absIndex == 0) {
yPos1 = halfHeight + shiftY - Y_STEP;
yPos2 = halfHeight + shiftY + Y_STEP;
}
else if (absIndex % 2 == 0) {
yPos1 = halfHeight + shiftY - Y_STEP_2;
yPos2 = halfHeight + shiftY + Y_STEP + Y_STEP_2;
}
else {
yPos1 = halfHeight + shiftY - Y_STEP - Y_STEP_2;
yPos2 = halfHeight + shiftY + Y_STEP_2;
}
xPoints1[index] = xPos;
yPoints1[index] = yPos1;
xPoints2[index] = xPos;
yPoints2[index] = yPos2;
if (absIndex == 0) {
yPos1 = halfHeight + shiftY - Y_STEP;
yPos2 = halfHeight + shiftY + Y_STEP;
}
else if (absIndex % 2 == 0) {
yPos1 = halfHeight + shiftY - Y_STEP_2;
yPos2 = halfHeight + shiftY + Y_STEP + Y_STEP_2;
}
else {
yPos1 = halfHeight + shiftY - Y_STEP - Y_STEP_2;
yPos2 = halfHeight + shiftY + Y_STEP_2;
}
paintLine(g, xPoints1, yPoints1, xPoints2, yPoints2);
}
finally {
gg.dispose();
xPoints1[index] = xPos;
yPoints1[index] = yPos1;
xPoints2[index] = xPos;
yPoints2[index] = yPos2;
}
paintLine(g, xPoints1, yPoints1, xPoints2, yPoints2);
}
private static void paintLine(@NotNull Graphics g,
@@ -380,6 +380,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
}
private void paintCaretRowBackground(final Graphics g, final int x, final int width) {
if (!myEditor.getSettings().isCaretRowShown()) return;
final VisualPosition visCaret = myEditor.getCaretModel().getVisualPosition();
Color caretRowColor = myEditor.getColorsScheme().getColor(EditorColors.CARET_ROW_COLOR);
if (caretRowColor != null) {
@@ -203,7 +203,7 @@ abstract class OrderEnumeratorBase extends OrderEnumerator implements OrderEnume
for (OrderEntry entry : rootModel.getOrderEntries()) {
if (myCondition != null && !myCondition.value(entry)) continue;
if (myWithoutJdk && entry instanceof JdkOrderEntry) continue;
if (entry instanceof JdkOrderEntry && (myWithoutJdk || !firstLevel)) continue;
if (myWithoutLibraries && entry instanceof LibraryOrderEntry) continue;
if (myWithoutDepModules) {
if (!myRecursively && entry instanceof ModuleOrderEntry) continue;
@@ -0,0 +1,33 @@
/*
* 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.util.io;
import com.intellij.openapi.util.text.StringUtil;
/**
* @author nik
*/
public class CaseInsensitiveEnumeratorStringDescriptor extends EnumeratorStringDescriptor {
@Override
public int getHashCode(String value) {
return StringUtil.stringHashCodeInsensitive(value);
}
@Override
public boolean isEqual(String val1, String val2) {
return val1.equalsIgnoreCase(val2);
}
}
@@ -24,6 +24,10 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.io.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
@@ -66,6 +70,84 @@ public class FileUtilRt {
private static String ourCanonicalTempPathCache = null;
protected static final boolean NIO_FILE_API_AVAILABLE;
// todo: replace reflection with normal code after migration to JDK 1.8
private static Method ourFilesDeleteIfExistsMethod;
private static Method ourFilesWalkMethod;
private static Method ourFileToPathMethod;
private static Object ourDeletionVisitor;
private static Class ourNoSuchFileExceptionClass;
static {
boolean initSuccess = false;
try {
final Class<?> pathClass = Class.forName("java.nio.file.Path");
final Class<?> visitorClass = Class.forName("java.nio.file.FileVisitor");
final Class<?> filesClass = Class.forName("java.nio.file.Files");
ourNoSuchFileExceptionClass = Class.forName("java.nio.file.NoSuchFileException");
ourFileToPathMethod = Class.forName("java.io.File").getMethod("toPath");
ourFilesWalkMethod = filesClass.getMethod("walkFileTree", pathClass, visitorClass);
ourFilesDeleteIfExistsMethod = filesClass.getMethod("deleteIfExists", pathClass);
final Class<?> fileVisitResultClass = Class.forName("java.nio.file.FileVisitResult");
final Object Result_Continue = fileVisitResultClass.getDeclaredField("CONTINUE").get(null);
final Object Result_Terminate = fileVisitResultClass.getDeclaredField("TERMINATE").get(null);
ourDeletionVisitor = Proxy.newProxyInstance(FileUtilRt.class.getClassLoader(), new Class[]{visitorClass}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (args.length == 2) {
final Object second = args[1];
if (second instanceof Throwable) {
throw (Throwable)second;
}
final String methodName = method.getName();
if ("visitFile".equals(methodName) || "postVisitDirectory".equals(methodName)) {
if (!performDelete(args[0])) {
return Result_Terminate;
}
}
}
return Result_Continue;
}
private boolean performDelete(@NotNull final Object fileObject) {
Boolean result = doIOOperation(new RepeatableIOOperation<Boolean, RuntimeException>() {
public Boolean execute(boolean lastAttempt) {
try {
//Files.deleteIfExists(file);
ourFilesDeleteIfExistsMethod.invoke(null, fileObject);
return Boolean.TRUE;
}
catch (InvocationTargetException e) {
if (!(e.getCause() instanceof IOException)) {
return Boolean.FALSE;
}
}
catch (IllegalAccessException e) {
return Boolean.FALSE;
}
return lastAttempt? Boolean.FALSE : null;
}
});
return Boolean.TRUE.equals(result);
}
});
initSuccess = true;
LOG.info("Using NIO-based file deletion");
}
catch (Throwable ignored) {
LOG.info("Was not able to detect NIO API");
ourFileToPathMethod = null;
ourFilesWalkMethod = null;
ourFilesDeleteIfExistsMethod = null;
ourDeletionVisitor = null;
ourNoSuchFileExceptionClass = null;
}
NIO_FILE_API_AVAILABLE = initSuccess;
}
@NotNull
public static String getExtension(@NotNull String fileName) {
int index = fileName.lastIndexOf('.');
@@ -538,10 +620,51 @@ public class FileUtilRt {
* @return true if the file did not exist or was successfully deleted
*/
public static boolean delete(@NotNull File file) {
if (NIO_FILE_API_AVAILABLE) {
return deleteRecursivelyNIO(file);
}
return deleteRecursively(file);
}
protected static boolean deleteRecursivelyNIO(File file) {
try {
/*
Files.walkFileTree(file.toPath(), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.deleteIfExists(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.deleteIfExists(dir);
return FileVisitResult.CONTINUE;
}
});
*/
final Object pathObject = ourFileToPathMethod.invoke(file);
ourFilesWalkMethod.invoke(null, pathObject, ourDeletionVisitor);
}
catch (InvocationTargetException e) {
final Throwable cause = e.getCause();
if (cause == null || !ourNoSuchFileExceptionClass.isInstance(cause)) {
LOG.info(e);
return false;
}
}
catch (Exception e) {
LOG.info(e);
return false;
}
return true;
}
private static boolean deleteRecursively(@NotNull File file) {
File[] files = file.listFiles();
if (files != null) {
for (File child : files) {
if (!delete(child)) return false;
if (!deleteRecursively(child)) return false;
}
}
@@ -421,6 +421,13 @@ public class FileUtil extends FileUtilRt {
}
public static boolean delete(@NotNull File file) {
if (NIO_FILE_API_AVAILABLE) {
return deleteRecursivelyNIO(file);
}
return deleteRecursively(file);
}
private static boolean deleteRecursively(@NotNull File file) {
FileAttributes attributes = FileSystemUtil.getAttributes(file);
if (attributes == null) return true;
@@ -428,7 +435,7 @@ public class FileUtil extends FileUtilRt {
File[] files = file.listFiles();
if (files != null) {
for (File child : files) {
if (!delete(child)) return false;
if (!deleteRecursively(child)) return false;
}
}
}
@@ -32,7 +32,6 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vcs.AbstractVcsHelper;
import com.intellij.openapi.vcs.CodeSmellDetector;
@@ -109,8 +108,6 @@ public class CodeSmellDetectorImpl extends CodeSmellDetector {
@Override
public List<CodeSmellInfo> findCodeSmells(final List<VirtualFile> filesToCheck) throws ProcessCanceledException {
final List<CodeSmellInfo> result = new ArrayList<CodeSmellInfo>();
final PsiManager manager = PsiManager.getInstance(myProject);
final FileDocumentManager fileManager = FileDocumentManager.getInstance();
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
if (ApplicationManager.getApplication().isWriteAccessAllowed()) throw new RuntimeException("Must not run under write action");
@@ -126,19 +123,7 @@ public class CodeSmellDetectorImpl extends CodeSmellDetector {
progress.setText(VcsBundle.message("searching.for.code.smells.processing.file.progress.text", file.getPresentableUrl()));
progress.setFraction((double)i / (double)filesToCheck.size());
final PsiFile psiFile = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
@Override
public PsiFile compute() {
return manager.findFile(file);
}
});
if (psiFile != null) {
final Document document = fileManager.getDocument(file);
if (document != null) {
final List<CodeSmellInfo> codeSmells = findCodeSmells(psiFile, progress, document);
result.addAll(codeSmells);
}
}
result.addAll(findCodeSmells(file, progress));
}
}
catch (ProcessCanceledException e) {
@@ -158,7 +143,7 @@ public class CodeSmellDetectorImpl extends CodeSmellDetector {
}
@NotNull
private List<CodeSmellInfo> findCodeSmells(@NotNull final PsiFile psiFile, @NotNull final ProgressIndicator progress, @NotNull final Document document) {
private List<CodeSmellInfo> findCodeSmells(@NotNull final VirtualFile file, @NotNull final ProgressIndicator progress) {
final List<CodeSmellInfo> result = new ArrayList<CodeSmellInfo>();
final DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(myProject);
@@ -173,13 +158,19 @@ public class CodeSmellDetectorImpl extends CodeSmellDetector {
ProgressManager.getInstance().runProcess(new Runnable() {
@Override
public void run() {
List<HighlightInfo> infos = ApplicationManager.getApplication().runReadAction(new Computable<List<HighlightInfo>>() {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public List<HighlightInfo> compute() {
return codeAnalyzer.runMainPasses(psiFile, document, daemonIndicator);
public void run() {
final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file);
if (psiFile != null) {
final Document document = FileDocumentManager.getInstance().getDocument(file);
if (document != null) {
List<HighlightInfo> infos = codeAnalyzer.runMainPasses(psiFile, document, daemonIndicator);
collectErrorsAndWarnings(infos, result, document);
}
}
}
});
collectErrorsAndWarnings(infos, result, document);
}
}, daemonIndicator);
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.VolatileNotNullLazyValue;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.scope.NameHint;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.search.GlobalSearchScope;
@@ -33,6 +34,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGd
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl;
import org.jetbrains.plugins.groovy.lang.psi.util.GdkMethodUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
/**
@@ -57,7 +59,9 @@ public class GdkMethodHolder {
for (PsiMethod m : categoryClass.getMethods()) {
final PsiParameter[] params = m.getParameterList().getParameters();
if (params.length == 0) continue;
if (PsiUtil.isDGMMethod(m) && (PsiImplUtil.isDeprecatedByAnnotation(m) || PsiImplUtil.isDeprecatedByDocTag(m))) {
continue;
}
byName.putValue(m.getName(), m);
}
this.myOriginalMethodByType = new VolatileNotNullLazyValue<MultiMap<String, PsiMethod>>() {
@@ -21,6 +21,7 @@ import com.intellij.execution.Location;
import com.intellij.execution.RunManagerEx;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
@@ -70,8 +71,11 @@ public class GantScriptType extends GroovyRunnableScriptType {
@Override
public boolean isConfigurationByLocation(@NotNull GroovyScriptRunConfiguration existing, @NotNull Location place) {
final String params = existing.getScriptParameters();
final String s = getTargetName(place);
return s != null && params != null && (params.startsWith(s + " ") || params.equals(s));
final String targetName = getTargetName(place);
if (targetName == null) {
return StringUtil.isEmpty(params);
}
return params != null && (params.startsWith(targetName + " ") || params.equals(targetName));
}
@Nullable
@@ -24,6 +24,7 @@ import com.intellij.openapi.vfs.JarFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor
import static org.jetbrains.plugins.groovy.config.GroovyFacetUtil.getBundledGroovyJar
import static org.jetbrains.plugins.groovy.util.TestUtils.*
/**
@@ -33,6 +34,7 @@ class GroovyLightProjectDescriptor extends DefaultLightProjectDescriptor {
public static final GroovyLightProjectDescriptor GROOVY_2_1 = new GroovyLightProjectDescriptor(mockGroovy2_1LibraryName)
public static final GroovyLightProjectDescriptor GROOVY_2_2 = new GroovyLightProjectDescriptor(mockGroovy2_2LibraryName)
public static final GroovyLightProjectDescriptor GROOVY_2_3 = new GroovyLightProjectDescriptor(mockGroovy2_3LibraryName)
public static final GroovyLightProjectDescriptor GROOVY_2_3_9 = new GroovyLightProjectDescriptor(getBundledGroovyJar() as String)
private final String myLibPath
@@ -0,0 +1,59 @@
/*
* 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.groovy.lang.resolve
import com.intellij.testFramework.LightProjectDescriptor
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod
import static org.jetbrains.plugins.groovy.GroovyLightProjectDescriptor.GROOVY_2_1
import static org.jetbrains.plugins.groovy.GroovyLightProjectDescriptor.GROOVY_2_3_9
abstract class AbstractResolveDGMMethodTest extends GroovyResolveTestCase {
final String basePath = "resolve/dgm"
abstract Map<String, String> getData()
void testIsNumber() {
def resolved = resolveByText('"1.2.3".isN<caret>umber()')
def method = resolved as GrGdkMethod
assertEquals(getData()[getTestName(true)], method.staticMethod.containingClass.qualifiedName)
}
void testCollectionSort() {
def resolved = resolveByText('[].so<caret>rt()', GrGdkMethod)
def parameterList = resolved.staticMethod.parameterList.parameters
assertSize(1, parameterList)
def qualifierParam = parameterList[0]
assertEquals(getData()[getTestName(true)], qualifierParam.type.canonicalText)
}
static class ResolveDGMMethod21Test extends AbstractResolveDGMMethodTest {
LightProjectDescriptor projectDescriptor = GROOVY_2_1
Map<String, String> data = [
isNumber : "org.codehaus.groovy.runtime.StringGroovyMethods",
collectionSort: "java.util.Collection<T>"
]
}
static class ResolveDGMMethod239Test extends AbstractResolveDGMMethodTest {
LightProjectDescriptor projectDescriptor = GROOVY_2_3_9
Map<String, String> data = [
isNumber : "org.codehaus.groovy.runtime.StringGroovyMethods",
collectionSort: "java.lang.Iterable<T>"
]
}
}
@@ -1,5 +1,5 @@
java.lang.String a = "foo";
if (org.codehaus.groovy.runtime.DefaultGroovyMethods.asBoolean(a)){
if (org.codehaus.groovy.runtime.StringGroovyMethods.asBoolean(a)){
print(a);
}
else {
@@ -3,4 +3,4 @@ print(new Bar().getBar());
Bar bar = new Bar();
print((bar == null ? null : bar.getFoo()));
java.io.File file = new java.io.File("");
print(org.codehaus.groovy.runtime.DefaultGroovyMethods.getText(file));
print(org.codehaus.groovy.runtime.ResourceGroovyMethods.getText(file));
@@ -1,4 +1,4 @@
java.util.regex.Pattern pattern = org.codehaus.groovy.runtime.DefaultGroovyMethods.bitwiseNegate("fdhsjk");
java.util.regex.Pattern pattern = org.codehaus.groovy.runtime.StringGroovyMethods.bitwiseNegate("fdhsjk");
java.util.regex.Matcher matcher = pattern.matcher("fdg");
matcher.matches();
print(java.util.regex.Pattern.matches("sdf", 2));
@@ -1,3 +1,3 @@
java.lang.Integer[] arr = new java.lang.Integer[]{1, 2, 3};
print(new java.lang.Integer[]{1, 2, 3});
print(org.codehaus.groovy.runtime.DefaultGroovyMethods.asType("dg", java.lang.Object.class));
print(org.codehaus.groovy.runtime.StringGroovyMethods.asType("dg", java.lang.Object.class));
@@ -1,13 +1,13 @@
java.lang.String[] commands = new java.lang.String[]{"abc"};
for(java.lang.String command : commands){
if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase("abc", command)) {
if (org.codehaus.groovy.runtime.StringGroovyMethods.isCase("abc", command)) {
print(1);
return 4;
}
else if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase("start", command)) {
else if (org.codehaus.groovy.runtime.StringGroovyMethods.isCase("start", command)) {
return 4;
}
else if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase("next", command)) {
else if (org.codehaus.groovy.runtime.StringGroovyMethods.isCase("next", command)) {
continue;
}
else {
@@ -1,7 +1,7 @@
java.lang.String x = "5";
if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase("0", x)||org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase("1", x)) {
if (org.codehaus.groovy.runtime.StringGroovyMethods.isCase("0", x)||org.codehaus.groovy.runtime.StringGroovyMethods.isCase("1", x)) {
print(2);
}
else if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase("2", x)) {
else if (org.codehaus.groovy.runtime.StringGroovyMethods.isCase("2", x)) {
print(4);
}
@@ -42,14 +42,14 @@ final MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
long start = java.lang.System.currentTimeMillis();
org.codehaus.groovy.runtime.DefaultGroovyMethods.eachByte(f, MB, new groovy.lang.Closure<java.lang.Object>(this, this) {
org.codehaus.groovy.runtime.ResourceGroovyMethods.eachByte(f, MB, new groovy.lang.Closure<java.lang.Object>(this, this) {
public void doCall(java.lang.Byte[] buf, int bytesRead) {
messageDigest.update(buf, 0, bytesRead);
}
});
java.lang.String sha1Hex = org.codehaus.groovy.runtime.DefaultGroovyMethods.padLeft(new BigInteger(1, messageDigest.digest()).toString(16), 40, "0");
java.lang.String sha1Hex = org.codehaus.groovy.runtime.StringGroovyMethods.padLeft(new BigInteger(1, messageDigest.digest()).toString(16), 40, "0");
long delta = java.lang.System.currentTimeMillis() - start;
println(sha1Hex + " took " + java.lang.String.valueOf(delta) + " ms to calculate");