Merge remote-tracking branch 'origin/master'

This commit is contained in:
Roman Shevchenko
2015-04-10 20:00:10 +02:00
28 changed files with 1294 additions and 65 deletions
@@ -0,0 +1,537 @@
/*
* Copyright 2000-2013 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.psi;
import com.intellij.lang.FileASTNode;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.impl.source.JavaLightStubBuilder;
import com.intellij.psi.stubs.StubElement;
import com.intellij.testFramework.LightIdeaTestCase;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.util.ThrowableRunnable;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.security.SecureRandom;
public class Test {
private static final StubBuilder NEW_BUILDER = new JavaLightStubBuilder();
@Override
public void setUp() throws Exception {
super.setUp();
doTest("@interface A { int i() default 42; }\n class C { void m(int p) throws E { } }", null); // warm up
LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.HIGHEST);
}
public void testEmpty() {
doTest("/**/",
"PsiJavaFileStub []\n" +
" IMPORT_LIST:PsiImportListStub\n");
}
public void testFileHeader() {
doTest("package p;\n" +
"import a/*comment to skip*/.b;\n" +
"import static c.d.*;\n" +
"import static java.util.Arrays.sort;",
"PsiJavaFileStub [p]\n" +
" IMPORT_LIST:PsiImportListStub\n" +
" IMPORT_STATEMENT:PsiImportStatementStub[a.b]\n" +
" IMPORT_STATIC_STATEMENT:PsiImportStatementStub[static c.d.*]\n" +
" IMPORT_STATIC_STATEMENT:PsiImportStatementStub[static java.util.Arrays.sort]\n");
}
public void testClassDeclaration() {
doTest("package p;" +
"class A implements I, J<I> { }\n" +
"class B<K, V extends X> extends a/*skip*/.A { class I { } }\n" +
"@java.lang.Deprecated interface I { }\n" +
"/** @deprecated just don't use */ @interface N { }",
"PsiJavaFileStub [p]\n" +
" IMPORT_LIST:PsiImportListStub\n" +
" CLASS:PsiClassStub[name=A fqn=p.A]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:I, J<I>]\n" +
" CLASS:PsiClassStub[name=B fqn=p.B]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" TYPE_PARAMETER:PsiTypeParameter[K]\n" +
" EXTENDS_BOUND_LIST:PsiRefListStub[EXTENDS_BOUNDS_LIST:]\n" +
" TYPE_PARAMETER:PsiTypeParameter[V]\n" +
" EXTENDS_BOUND_LIST:PsiRefListStub[EXTENDS_BOUNDS_LIST:X]\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:a/*skip*/.A]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
" CLASS:PsiClassStub[name=I fqn=p.B.I]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
" CLASS:PsiClassStub[interface deprecatedA name=I fqn=p.I]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=5120]\n" +
" ANNOTATION:PsiAnnotationStub[@java.lang.Deprecated]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
" CLASS:PsiClassStub[interface annotation deprecated name=N fqn=p.N]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=5120]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n");
}
public void testMethods() {
doTest("public @interface Anno {\n" +
" int i() default 42;\n" +
" public static String s();\n" +
"}\n" +
"private class C {\n" +
" public C() throws Exception { }\n" +
" public abstract void m(final int i, int[] a1, int a2[], int[] a3[]);\n" +
" private static int v2a(int... v) [] { return v; }\n" +
"}\n" +
"interface I {\n" +
" void m1();\n" +
" default void m2() { }\n" +
"}",
"PsiJavaFileStub []\n" +
" IMPORT_LIST:PsiImportListStub\n" +
" CLASS:PsiClassStub[interface annotation name=Anno fqn=Anno]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=1025]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
" ANNOTATION_METHOD:PsiMethodStub[annotation i:int default=42]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=1025]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n" +
" ANNOTATION_METHOD:PsiMethodStub[annotation s:String]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=1033]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n" +
" CLASS:PsiClassStub[name=C fqn=C]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=2]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
" METHOD:PsiMethodStub[cons C:null]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=1]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:Exception]\n" +
" METHOD:PsiMethodStub[m:void]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=1025]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" PARAMETER:PsiParameterStub[i:int]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4112]\n" +
" PARAMETER:PsiParameterStub[a1:int[]]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" PARAMETER:PsiParameterStub[a2:int[]]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" PARAMETER:PsiParameterStub[a3:int[][]]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n" +
" METHOD:PsiMethodStub[varargs v2a:int[]]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=10]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" PARAMETER:PsiParameterStub[v:int...]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n" +
" CLASS:PsiClassStub[interface name=I fqn=I]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=5120]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
" METHOD:PsiMethodStub[m1:void]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=1025]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n" +
" METHOD:PsiMethodStub[m2:void]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=513]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n");
}
public void testFields() {
doTest("static class C {\n" +
" strictfp float f;\n" +
" int j[] = {0}, k;\n" +
" static String s = \"-\";\n" +
"}\n" +
"public class D {\n" +
" private volatile boolean b;\n" +
" public final double x;\n" +
"}",
"PsiJavaFileStub []\n" +
" IMPORT_LIST:PsiImportListStub\n" +
" CLASS:PsiClassStub[name=C fqn=C]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4104]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
" FIELD:PsiFieldStub[f:float]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=6144]\n" +
" FIELD:PsiFieldStub[j:int[]={0}]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" FIELD:PsiFieldStub[k:int]\n" +
" FIELD:PsiFieldStub[s:String=\"-\"]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4104]\n" +
" CLASS:PsiClassStub[name=D fqn=D]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=1]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
" FIELD:PsiFieldStub[b:boolean]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=66]\n" +
" FIELD:PsiFieldStub[x:double]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=17]\n");
}
public void testAnonymousClasses() {
doTest("class C { {\n" +
" new O.P() { };\n" +
" X.new Y() { };\n" +
" f(p -> new R() { });\n" +
"} }",
"PsiJavaFileStub []\n" +
" IMPORT_LIST:PsiImportListStub\n" +
" CLASS:PsiClassStub[name=C fqn=C]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
" CLASS_INITIALIZER:PsiClassInitializerStub\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" ANONYMOUS_CLASS:PsiClassStub[anonymous name=null fqn=null baseref=O.P]\n" +
" ANONYMOUS_CLASS:PsiClassStub[anonymous name=null fqn=null baseref=Y inqualifnew]\n" +
" ANONYMOUS_CLASS:PsiClassStub[anonymous name=null fqn=null baseref=R]\n");
}
public void testEnums() {
doTest("enum E {\n" +
" E1() { };\n" +
" abstract void m();\n" +
"}\n" +
"public enum U { U1, U2 }",
"PsiJavaFileStub []\n" +
" IMPORT_LIST:PsiImportListStub\n" +
" CLASS:PsiClassStub[enum name=E fqn=E]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=5120]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
" ENUM_CONSTANT:PsiFieldStub[enumconst E1:E]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=25]\n" +
" ENUM_CONSTANT_INITIALIZER:PsiClassStub[anonymous enumInit name=null fqn=null baseref=E]\n" +
" METHOD:PsiMethodStub[m:void]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=5120]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n" +
" CLASS:PsiClassStub[enum name=U fqn=U]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=17]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
" ENUM_CONSTANT:PsiFieldStub[enumconst U1:U]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=25]\n" +
" ENUM_CONSTANT:PsiFieldStub[enumconst U2:U]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=25]\n");
}
public void testLocalVariables() {
doTest("class C {\n" +
" void m() {\n" +
" int local = 0;\n" +
" Object r = new Runnable() {\n" +
" public void run() { }\n" +
" };\n" +
" for (int loop = 0; loop < 10; loop++) ;\n" +
" try (Resource r = new Resource()) { }\n" +
" try (Resource r = new Resource() {\n" +
" @Override public void close() { }\n" +
" }) { }\n" +
" }\n" +
"}",
"PsiJavaFileStub []\n" +
" IMPORT_LIST:PsiImportListStub\n" +
" CLASS:PsiClassStub[name=C fqn=C]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
" METHOD:PsiMethodStub[m:void]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n" +
" ANONYMOUS_CLASS:PsiClassStub[anonymous name=null fqn=null baseref=Runnable]\n" +
" METHOD:PsiMethodStub[run:void]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=1]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n" +
" ANONYMOUS_CLASS:PsiClassStub[anonymous name=null fqn=null baseref=Resource]\n" +
" METHOD:PsiMethodStub[close:void]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=1]\n" +
" ANNOTATION:PsiAnnotationStub[@Override]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n");
}
public void testNonListParameters() {
doTest("class C {\n" +
" {\n" +
" for (int i : arr) ;\n" +
" for (String s : new Iterable<String>() {\n" +
" @Override public Iterator<String> iterator() { return null; }\n" +
" }) ;\n" +
" try { }\n" +
" catch (Throwable t) { }\n" +
" catch (E1|E2 e) { }\n" +
" }\n" +
"}",
"PsiJavaFileStub []\n" +
" IMPORT_LIST:PsiImportListStub\n" +
" CLASS:PsiClassStub[name=C fqn=C]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
" CLASS_INITIALIZER:PsiClassInitializerStub\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" ANONYMOUS_CLASS:PsiClassStub[anonymous name=null fqn=null baseref=Iterable<String>]\n" +
" METHOD:PsiMethodStub[iterator:Iterator<String>]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=1]\n" +
" ANNOTATION:PsiAnnotationStub[@Override]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n");
}
public void testAnnotations() {
doTest("@Deprecated\n" +
"@SuppressWarnings(\"UnusedDeclaration\")\n" +
"class Foo { }",
"PsiJavaFileStub []\n" +
" IMPORT_LIST:PsiImportListStub\n" +
" CLASS:PsiClassStub[deprecatedA name=Foo fqn=Foo]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" ANNOTATION:PsiAnnotationStub[@Deprecated]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@SuppressWarnings(\"UnusedDeclaration\")]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" NAME_VALUE_PAIR:PsiNameValuePairStubImpl\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n");
}
public void testTypeAnnotations() {
doTest("import j.u.@A C;\n" +
"import @A j.u.D;\n" +
"\n" +
"class C<@A T extends @A C> implements @A I<@A T> {\n" +
" @TA T<@A T1, @A ? extends @A T2> f;\n" +
" @TA T m(/*@A C this,*/ @TA int p) throws @A E {\n" +
" o.<@A1 C>m();\n" +
" new <T> @A2 C();\n" +
" C.@A3 B v = (@A4 C)v.new @A5 C();\n" +
" m(@A6 C::m);\n" +
" @A7 T @A8[] @A9[] a = new @A7 T @A8[0] @A9[0];\n" +
" }\n" +
" int @A [] v() @A [] { }\n" +
"}",
"PsiJavaFileStub []\n" +
" IMPORT_LIST:PsiImportListStub\n" +
" IMPORT_STATEMENT:PsiImportStatementStub[j.u.C]\n" +
" IMPORT_STATEMENT:PsiImportStatementStub[j.u.D]\n" +
" CLASS:PsiClassStub[name=C fqn=C]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" TYPE_PARAMETER:PsiTypeParameter[T]\n" +
" ANNOTATION:PsiAnnotationStub[@A]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" EXTENDS_BOUND_LIST:PsiRefListStub[EXTENDS_BOUNDS_LIST:@A C]\n" +
" ANNOTATION:PsiAnnotationStub[@A]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:@A I<@A T>]\n" +
" ANNOTATION:PsiAnnotationStub[@A]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" FIELD:PsiFieldStub[f:T<@A T1, @A ? extends @A T2>]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" ANNOTATION:PsiAnnotationStub[@TA]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" METHOD:PsiMethodStub[m:T]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" ANNOTATION:PsiAnnotationStub[@TA]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" PARAMETER:PsiParameterStub[p:int]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" ANNOTATION:PsiAnnotationStub[@TA]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:@A E]\n" +
" ANNOTATION:PsiAnnotationStub[@A]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A1]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A2]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A3]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A4]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A5]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A6]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A7]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A8]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A9]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A7]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A8]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" ANNOTATION:PsiAnnotationStub[@A9]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" METHOD:PsiMethodStub[v:int[][]]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" ANNOTATION:PsiAnnotationStub[@A]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" ANNOTATION:PsiAnnotationStub[@A]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n");
}
public void testSOEProof() {
final StringBuilder sb = new StringBuilder();
final SecureRandom random = new SecureRandom();
sb.append("class SOE_test {\n BigInteger BIG = new BigInteger(\n");
int i;
for (i = 0; i < 100000; i++) {
sb.append(" \"").append(Math.abs(random.nextInt())).append("\" +\n");
}
sb.append(" \"\");\n}");
final PsiJavaFile file = (PsiJavaFile)createLightFile("SOE_test.java", sb.toString());
long t = System.currentTimeMillis();
final StubElement tree = NEW_BUILDER.buildStubTree(file);
t = System.currentTimeMillis() - t;
assertEquals("PsiJavaFileStub []\n" +
" IMPORT_LIST:PsiImportListStub\n" +
" CLASS:PsiClassStub[name=SOE_test fqn=SOE_test]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
" FIELD:PsiFieldStub[BIG:BigInteger=;INITIALIZER_NOT_STORED;]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n",
DebugUtil.stubTreeToString(tree));
System.out.println("SOE depth=" + i + ", time=" + t + "ms");
}
public void testPerformance() throws Exception {
final String path = PathManagerEx.getTestDataPath() + "/psi/stub/StubPerformanceTest.java";
String text = FileUtil.loadFile(new File(path));
final PsiJavaFile file = (PsiJavaFile)createLightFile("test.java", text);
PlatformTestUtil.startPerformanceTest("Source file size: " + text.length(), 2000, new ThrowableRunnable() {
@Override
public void run() throws Exception {
NEW_BUILDER.buildStubTree(file);
}
}).cpuBound().assertTiming();
}
private static void doTest(@NonNls final String source, @NonNls @Nullable final String tree) {
final PsiJavaFile file = (PsiJavaFile)createLightFile("test.java", source);
final FileASTNode fileNode = file.getNode();
assertNotNull(fileNode);
assertFalse(fileNode.isParsed());
long t1 = System.nanoTime();
final StubElement lighterTree = NEW_BUILDER.buildStubTree(file);
t1 = Math.max((System.nanoTime() - t1)/1000, 1);
assertFalse(fileNode.isParsed());
file.getNode().getChildren(null); // force switch to AST
long t2 = System.nanoTime();
final StubElement lighterTree2 = NEW_BUILDER.buildStubTree(file); // build over AST
t2 = Math.max((System.nanoTime() - t2)/1000, 1);
file.accept(new PsiRecursiveElementWalkingVisitor() {
@Override
public void visitElement(PsiElement element) {
assert !(element instanceof PsiErrorElement) : element;
super.visitElement(element);
}
});
final String lightStr = DebugUtil.stubTreeToString(lighterTree);
final String lightStr2 = DebugUtil.stubTreeToString(lighterTree2);
if (tree != null) {
System.out.println("light=" + t1 + "mks, heavy=" + t2 + "mks");
if (!tree.isEmpty()) {
assertEquals("light tree differs", tree, lightStr);
assertEquals("light tree (2nd) differs", tree, lightStr2);
}
}
}
}
@@ -0,0 +1,301 @@
import java.util.Arrays;
import java.util.List;
public final class TimeContentItemHelper {
public static List<TimePeriods> TIME_PERIOD_1_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_PERIOD1_1,
TimePeriods.TIME_PERIOD1_2,
TimePeriods.TIME_PERIOD1_3,
TimePeriods.TIME_PERIOD1_4,
TimePeriods.TIME_PERIOD1_5,
TimePeriods.TIME_PERIOD1_6
);
public static List<TimePeriods> TIME_PERIOD_2_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_PERIOD2_1,
TimePeriods.TIME_PERIOD2_2,
TimePeriods.TIME_PERIOD2_3,
TimePeriods.TIME_PERIOD2_4,
TimePeriods.TIME_PERIOD2_5,
TimePeriods.TIME_PERIOD2_6
);
public static List<TimePeriods> TIME_PERIOD_3_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_PERIOD3_1,
TimePeriods.TIME_PERIOD3_2,
TimePeriods.TIME_PERIOD3_3,
TimePeriods.TIME_PERIOD3_4,
TimePeriods.TIME_PERIOD3_5,
TimePeriods.TIME_PERIOD3_6
);
public static List<TimePeriods> TIME_PERIOD_4_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_PERIOD4_1,
TimePeriods.TIME_PERIOD4_2,
TimePeriods.TIME_PERIOD4_3,
TimePeriods.TIME_PERIOD4_4,
TimePeriods.TIME_PERIOD4_5,
TimePeriods.TIME_PERIOD4_6
);
public static List<TimePeriods> TIME_PERIOD_5_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_PERIOD5_1,
TimePeriods.TIME_PERIOD5_2,
TimePeriods.TIME_PERIOD5_3,
TimePeriods.TIME_PERIOD5_4,
TimePeriods.TIME_PERIOD5_5,
TimePeriods.TIME_PERIOD5_6
);
public static List<TimePeriods> TIME_PERIOD_6_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_PERIOD6_1,
TimePeriods.TIME_PERIOD6_2,
TimePeriods.TIME_PERIOD6_3,
TimePeriods.TIME_PERIOD6_4,
TimePeriods.TIME_PERIOD6_5,
TimePeriods.TIME_PERIOD6_6
);
public static List<List<TimePeriods>> TIME_PERIOD_CONTENT_ITEM_KEY_MATRIX = Arrays.asList(
TIME_PERIOD_1_CONTENT_ITEM_KEYS,
TIME_PERIOD_2_CONTENT_ITEM_KEYS,
TIME_PERIOD_3_CONTENT_ITEM_KEYS,
TIME_PERIOD_4_CONTENT_ITEM_KEYS,
TIME_PERIOD_5_CONTENT_ITEM_KEYS,
TIME_PERIOD_6_CONTENT_ITEM_KEYS
);
public static List<TimePeriods> TIME_AVERAGE_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_AVERAGE1,
TimePeriods.TIME_AVERAGE2,
TimePeriods.TIME_AVERAGE3,
TimePeriods.TIME_AVERAGE4,
TimePeriods.TIME_AVERAGE5,
TimePeriods.TIME_AVERAGE6
);
public static List<TimePeriods> TIME_ROOM_DESCRIPTION_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_AVERAGE_DESCRIPTION1,
TimePeriods.TIME_AVERAGE_DESCRIPTION2,
TimePeriods.TIME_AVERAGE_DESCRIPTION3,
TimePeriods.TIME_AVERAGE_DESCRIPTION4,
TimePeriods.TIME_AVERAGE_DESCRIPTION5,
TimePeriods.TIME_AVERAGE_DESCRIPTION6
);
public static List<TimePeriods> TIME_1_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_AVERAGE_PRICE1_1,
TimePeriods.TIME_AVERAGE_PRICE1_2,
TimePeriods.TIME_AVERAGE_PRICE1_3,
TimePeriods.TIME_AVERAGE_PRICE1_4,
TimePeriods.TIME_AVERAGE_PRICE1_5,
TimePeriods.TIME_AVERAGE_PRICE1_6
);
public static List<TimePeriods> TIME_2_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_AVERAGE_PRICE2_1,
TimePeriods.TIME_AVERAGE_PRICE2_2,
TimePeriods.TIME_AVERAGE_PRICE2_3,
TimePeriods.TIME_AVERAGE_PRICE2_4,
TimePeriods.TIME_AVERAGE_PRICE2_5,
TimePeriods.TIME_AVERAGE_PRICE2_6
);
public static List<TimePeriods> TIME_3_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_AVERAGE_PRICE3_1,
TimePeriods.TIME_AVERAGE_PRICE3_2,
TimePeriods.TIME_AVERAGE_PRICE3_3,
TimePeriods.TIME_AVERAGE_PRICE3_4,
TimePeriods.TIME_AVERAGE_PRICE3_5,
TimePeriods.TIME_AVERAGE_PRICE3_6
);
public static List<TimePeriods> TIME_4_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_AVERAGE_PRICE4_1,
TimePeriods.TIME_AVERAGE_PRICE4_2,
TimePeriods.TIME_AVERAGE_PRICE4_3,
TimePeriods.TIME_AVERAGE_PRICE4_4,
TimePeriods.TIME_AVERAGE_PRICE4_5,
TimePeriods.TIME_AVERAGE_PRICE4_6
);
public static List<TimePeriods> TIME_5_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_AVERAGE_PRICE5_1,
TimePeriods.TIME_AVERAGE_PRICE5_2,
TimePeriods.TIME_AVERAGE_PRICE5_3,
TimePeriods.TIME_AVERAGE_PRICE5_4,
TimePeriods.TIME_AVERAGE_PRICE5_5,
TimePeriods.TIME_AVERAGE_PRICE5_6
);
public static List<TimePeriods> TIME_6_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_AVERAGE_PRICE6_1,
TimePeriods.TIME_AVERAGE_PRICE6_2,
TimePeriods.TIME_AVERAGE_PRICE6_3,
TimePeriods.TIME_AVERAGE_PRICE6_4,
TimePeriods.TIME_AVERAGE_PRICE6_5,
TimePeriods.TIME_AVERAGE_PRICE6_6
);
public static List<List<TimePeriods>> TIME_CONTENT_ITEM_KEY_MATRIX = Arrays.asList(
TIME_1_CONTENT_ITEM_KEYS,
TIME_2_CONTENT_ITEM_KEYS,
TIME_3_CONTENT_ITEM_KEYS,
TIME_4_CONTENT_ITEM_KEYS,
TIME_5_CONTENT_ITEM_KEYS,
TIME_6_CONTENT_ITEM_KEYS
);
public static List<TimePeriods> TIME_NOTE_LABELS_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_NOTE_LABEL_1,
TimePeriods.TIME_NOTE_LABEL_2,
TimePeriods.TIME_NOTE_LABEL_3,
TimePeriods.TIME_NOTE_LABEL_4,
TimePeriods.TIME_NOTE_LABEL_5,
TimePeriods.TIME_NOTE_LABEL_6,
TimePeriods.TIME_NOTE_LABEL_7,
TimePeriods.TIME_NOTE_LABEL_8,
TimePeriods.TIME_NOTE_LABEL_9,
TimePeriods.TIME_NOTE_LABEL_10
);
public static List<TimePeriods> TIME_NOTES_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIME_NOTE_1,
TimePeriods.TIME_NOTE_2,
TimePeriods.TIME_NOTE_3,
TimePeriods.TIME_NOTE_4,
TimePeriods.TIME_NOTE_5,
TimePeriods.TIME_NOTE_6,
TimePeriods.TIME_NOTE_7,
TimePeriods.TIME_NOTE_8,
TimePeriods.TIME_NOTE_9,
TimePeriods.TIME_NOTE_10
);
public static List<TimePeriods> TIME_CONTENT_ITEM_KEYS = Arrays.asList(
TimePeriods.TIMES_ENABLED,
TimePeriods.TIMES_COUNT_OF_TIMES,
TimePeriods.TIMES_COUNT_OF_TIME_PERIODS,
TimePeriods.TIMES_COUNT_OF_AVERAGES,
TimePeriods.TIME_NAME1,
TimePeriods.TIME_NAME2,
TimePeriods.TIME_NAME3,
TimePeriods.TIME_NAME4,
TimePeriods.TIME_NAME5,
TimePeriods.TIME_NAME6,
TimePeriods.TIME_PERIOD1_1,
TimePeriods.TIME_PERIOD1_2,
TimePeriods.TIME_PERIOD1_3,
TimePeriods.TIME_PERIOD1_4,
TimePeriods.TIME_PERIOD1_5,
TimePeriods.TIME_PERIOD1_6,
TimePeriods.TIME_PERIOD2_1,
TimePeriods.TIME_PERIOD2_2,
TimePeriods.TIME_PERIOD2_3,
TimePeriods.TIME_PERIOD2_4,
TimePeriods.TIME_PERIOD2_5,
TimePeriods.TIME_PERIOD2_6,
TimePeriods.TIME_PERIOD3_1,
TimePeriods.TIME_PERIOD3_2,
TimePeriods.TIME_PERIOD3_3,
TimePeriods.TIME_PERIOD3_4,
TimePeriods.TIME_PERIOD3_5,
TimePeriods.TIME_PERIOD3_6,
TimePeriods.TIME_PERIOD4_1,
TimePeriods.TIME_PERIOD4_2,
TimePeriods.TIME_PERIOD4_3,
TimePeriods.TIME_PERIOD4_4,
TimePeriods.TIME_PERIOD4_5,
TimePeriods.TIME_PERIOD4_6,
TimePeriods.TIME_PERIOD5_1,
TimePeriods.TIME_PERIOD5_2,
TimePeriods.TIME_PERIOD5_3,
TimePeriods.TIME_PERIOD5_4,
TimePeriods.TIME_PERIOD5_5,
TimePeriods.TIME_PERIOD5_6,
TimePeriods.TIME_PERIOD6_1,
TimePeriods.TIME_PERIOD6_2,
TimePeriods.TIME_PERIOD6_3,
TimePeriods.TIME_PERIOD6_4,
TimePeriods.TIME_PERIOD6_5,
TimePeriods.TIME_PERIOD6_6,
TimePeriods.TIME_AVERAGE1,
TimePeriods.TIME_AVERAGE2,
TimePeriods.TIME_AVERAGE3,
TimePeriods.TIME_AVERAGE4,
TimePeriods.TIME_AVERAGE5,
TimePeriods.TIME_AVERAGE6,
TimePeriods.TIME_AVERAGE_PRICE1_1,
TimePeriods.TIME_AVERAGE_PRICE1_2,
TimePeriods.TIME_AVERAGE_PRICE1_3,
TimePeriods.TIME_AVERAGE_PRICE1_4,
TimePeriods.TIME_AVERAGE_PRICE1_5,
TimePeriods.TIME_AVERAGE_PRICE1_6,
TimePeriods.TIME_AVERAGE_PRICE2_1,
TimePeriods.TIME_AVERAGE_PRICE2_2,
TimePeriods.TIME_AVERAGE_PRICE2_3,
TimePeriods.TIME_AVERAGE_PRICE2_4,
TimePeriods.TIME_AVERAGE_PRICE2_5,
TimePeriods.TIME_AVERAGE_PRICE2_6,
TimePeriods.TIME_AVERAGE_PRICE3_1,
TimePeriods.TIME_AVERAGE_PRICE3_2,
TimePeriods.TIME_AVERAGE_PRICE3_3,
TimePeriods.TIME_AVERAGE_PRICE3_4,
TimePeriods.TIME_AVERAGE_PRICE3_5,
TimePeriods.TIME_AVERAGE_PRICE3_6,
TimePeriods.TIME_AVERAGE_PRICE4_1,
TimePeriods.TIME_AVERAGE_PRICE4_2,
TimePeriods.TIME_AVERAGE_PRICE4_3,
TimePeriods.TIME_AVERAGE_PRICE4_4,
TimePeriods.TIME_AVERAGE_PRICE4_5,
TimePeriods.TIME_AVERAGE_PRICE4_6,
TimePeriods.TIME_AVERAGE_PRICE5_1,
TimePeriods.TIME_AVERAGE_PRICE5_2,
TimePeriods.TIME_AVERAGE_PRICE5_3,
TimePeriods.TIME_AVERAGE_PRICE5_4,
TimePeriods.TIME_AVERAGE_PRICE5_5,
TimePeriods.TIME_AVERAGE_PRICE5_6,
TimePeriods.TIME_AVERAGE_PRICE6_1,
TimePeriods.TIME_AVERAGE_PRICE6_2,
TimePeriods.TIME_AVERAGE_PRICE6_3,
TimePeriods.TIME_AVERAGE_PRICE6_4,
TimePeriods.TIME_AVERAGE_PRICE6_5,
TimePeriods.TIME_AVERAGE_PRICE6_6,
TimePeriods.TIME_AVERAGE_DESCRIPTION1,
TimePeriods.TIME_AVERAGE_DESCRIPTION2,
TimePeriods.TIME_AVERAGE_DESCRIPTION3,
TimePeriods.TIME_AVERAGE_DESCRIPTION4,
TimePeriods.TIME_AVERAGE_DESCRIPTION5,
TimePeriods.TIME_AVERAGE_DESCRIPTION6,
TimePeriods.TIME_NOTE_LABEL_1,
TimePeriods.TIME_NOTE_LABEL_2,
TimePeriods.TIME_NOTE_LABEL_3,
TimePeriods.TIME_NOTE_LABEL_4,
TimePeriods.TIME_NOTE_LABEL_5,
TimePeriods.TIME_NOTE_LABEL_6,
TimePeriods.TIME_NOTE_LABEL_7,
TimePeriods.TIME_NOTE_LABEL_8,
TimePeriods.TIME_NOTE_LABEL_9,
TimePeriods.TIME_NOTE_LABEL_10,
TimePeriods.TIME_NOTE_1,
TimePeriods.TIME_NOTE_2,
TimePeriods.TIME_NOTE_3,
TimePeriods.TIME_NOTE_4,
TimePeriods.TIME_NOTE_5,
TimePeriods.TIME_NOTE_6,
TimePeriods.TIME_NOTE_7,
TimePeriods.TIME_NOTE_8,
TimePeriods.TIME_NOTE_9,
TimePeriods.TIME_NOTE_10
);
public static boolean check(TimePeriods key) {
int keyI = key.getIntValue();
if (keyI < 0) {
return false;
} else {
return true;
}
}
}
@@ -36,4 +36,15 @@ public class JavaAutoDetectIndentTest extends AbstractIndentAutoDetectionTest {
public void testNotIndentedComment() {
doTestIndentSize(3);
}
public void testContinuationIndents_DoNotCount() {
doTestIndentSize(4);
//actual indent is 2, and 4 is the default value
//todo: do not count brackets in string literals
}
public void testContinuationIndents_InMethodParameters_DoNotCount() {
doTestIndentSize(4);
}
}
@@ -52,6 +52,9 @@ public abstract class DiffContentFactory {
@NotNull
public abstract DocumentContent create(@Nullable Project project, @NotNull Document document);
@NotNull
public abstract DocumentContent create(@Nullable Project project, @NotNull Document document, @Nullable FileType fileType);
@NotNull
public abstract DocumentContent create(@Nullable Project project, @NotNull Document document, @Nullable VirtualFile file);
@@ -47,7 +47,7 @@ public class DiffContentFactoryImpl extends DiffContentFactory {
@NotNull
public static DiffContentFactoryImpl getInstanceImpl() {
return (DiffContentFactoryImpl)ServiceManager.getService(DiffContentFactory.class);
return (DiffContentFactoryImpl)DiffContentFactory.getInstance();
}
@Override
@@ -77,7 +77,14 @@ public class DiffContentFactoryImpl extends DiffContentFactory {
@Override
@NotNull
public DocumentContent create(@Nullable Project project, @NotNull Document document) {
return create(project, document, (FileType)null);
}
@Override
@NotNull
public DocumentContent create(@Nullable Project project, @NotNull Document document, @Nullable FileType fileType) {
VirtualFile file = FileDocumentManager.getInstance().getFile(document);
if (file == null) return new DocumentContentImpl(document, fileType, null, null, null);
return create(project, document, file);
}
@@ -16,5 +16,10 @@
package com.intellij.diff;
public abstract class DiffContextEx extends DiffContext {
/*
* Reopen current DiffRequest.
* perform the same procedure as on switching between DiffRequests or between DiffViewers.
* this can be used, if some change in request or settings was made, and we need to reopen DiffViewer to apply them.
*/
public abstract void reloadDiffRequest();
}
@@ -17,9 +17,12 @@ package com.intellij.diff.actions;
import com.intellij.diff.DiffContentFactory;
import com.intellij.diff.DiffRequestFactory;
import com.intellij.diff.contents.DiffContent;
import com.intellij.diff.contents.DocumentContent;
import com.intellij.diff.requests.ContentDiffRequest;
import com.intellij.diff.requests.DiffRequest;
import com.intellij.diff.requests.SimpleDiffRequest;
import com.intellij.diff.tools.util.DiffDataKeys;
import com.intellij.diff.util.DiffUserDataKeys;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
@@ -28,6 +31,8 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.UnknownFileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
@@ -49,6 +54,22 @@ public class CompareClipboardWithSelectionAction extends BaseShowDiffAction {
return null;
}
@Nullable
private static FileType getEditorFileType(@NotNull AnActionEvent e) {
DiffContent content = e.getData(DiffDataKeys.CURRENT_CONTENT);
if (content != null && content.getContentType() != null) return content.getContentType();
DiffRequest request = e.getData(DiffDataKeys.DIFF_REQUEST);
if (request != null && request instanceof ContentDiffRequest) {
for (DiffContent diffContent : ((ContentDiffRequest)request).getContents()) {
FileType type = diffContent.getContentType();
if (type != null && type != UnknownFileType.INSTANCE) return type;
}
}
return null;
}
@Override
protected boolean isAvailable(@NotNull AnActionEvent e) {
Editor editor = getEditor(e);
@@ -60,9 +81,10 @@ public class CompareClipboardWithSelectionAction extends BaseShowDiffAction {
protected DiffRequest getDiffRequest(@NotNull AnActionEvent e) {
Project project = e.getRequiredData(CommonDataKeys.PROJECT);
Editor editor = getEditor(e);
FileType editorFileType = getEditorFileType(e);
assert editor != null;
DocumentContent content2 = createContent(project, editor);
DocumentContent content2 = createContent(project, editor, editorFileType);
DocumentContent content1 = DiffContentFactory.getInstance().createClipboardContent(content2);
String title1 = DiffBundle.message("diff.content.clipboard.content.title");
@@ -78,8 +100,8 @@ public class CompareClipboardWithSelectionAction extends BaseShowDiffAction {
}
@NotNull
private static DocumentContent createContent(@NotNull Project project, @NotNull Editor editor) {
DocumentContent content = DiffContentFactory.getInstance().create(project, editor.getDocument());
private static DocumentContent createContent(@NotNull Project project, @NotNull Editor editor, @Nullable FileType type) {
DocumentContent content = DiffContentFactory.getInstance().create(project, editor.getDocument(), type);
SelectionModel selectionModel = editor.getSelectionModel();
if (selectionModel.hasSelection()) {
@@ -15,18 +15,23 @@
*/
package com.intellij.diff.actions.impl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.actionSystem.ShortcutSet;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.project.DumbAware;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class FocusOppositePaneAction extends AnAction implements DumbAware {
protected final boolean myScrollToPosition;
public FocusOppositePaneAction() {
this(false);
}
public FocusOppositePaneAction(boolean scrollToPosition) {
myScrollToPosition = scrollToPosition;
setEnabledInModalContext(true);
}
@@ -35,8 +40,8 @@ public class FocusOppositePaneAction extends AnAction implements DumbAware {
throw new UnsupportedOperationException();
}
public void setupAction(@NotNull JComponent component, @NotNull Disposable disposable) {
ShortcutSet shortcutSet = CustomShortcutSet.fromString("control TAB"); // TODO: allow to change shortcut
registerCustomShortcutSet(shortcutSet, component, disposable);
public void setupAction(@NotNull JComponent component) {
String action = myScrollToPosition ? "Diff.FocusOppositePaneAndScroll" : "Diff.FocusOppositePane";
EmptyAction.setupAction(this, action, component);
}
}
@@ -11,7 +11,6 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.LineSeparator;
import org.jetbrains.annotations.NotNull;
@@ -21,22 +20,22 @@ import java.nio.charset.Charset;
public class FileAwareDocumentContent extends DocumentContentImpl {
@Nullable private final Project myProject;
@Nullable private final VirtualFile myLocalFile;
@Nullable private final VirtualFile myHighlightFile;
public FileAwareDocumentContent(@Nullable Project project,
@NotNull Document document,
@Nullable FileType fileType,
@Nullable VirtualFile localFile,
@Nullable VirtualFile highlightFile,
@Nullable LineSeparator separator,
@Nullable Charset charset) {
super(document, fileType, localFile, separator, charset);
super(document, fileType, highlightFile, separator, charset);
myProject = project;
myLocalFile = localFile;
myHighlightFile = highlightFile;
}
public OpenFileDescriptor getOpenFileDescriptor(int offset) {
if (myProject == null || myLocalFile == null) return null;
return new OpenFileDescriptor(myProject, myLocalFile, offset);
if (myProject == null || myHighlightFile == null) return null;
return new OpenFileDescriptor(myProject, myHighlightFile, offset);
}
@NotNull
@@ -45,8 +44,8 @@ public class FileAwareDocumentContent extends DocumentContentImpl {
}
@NotNull
public static FileAwareDocumentContent create(@Nullable Project project, @NotNull String content, @NotNull VirtualFile file) {
return new Builder(project).init(file).create(content).build();
public static FileAwareDocumentContent create(@Nullable Project project, @NotNull String content, @NotNull VirtualFile highlightFile) {
return new Builder(project).init(highlightFile).create(content).build();
}
@NotNull
@@ -55,15 +54,15 @@ public class FileAwareDocumentContent extends DocumentContentImpl {
}
@NotNull
public static FileAwareDocumentContent create(@Nullable Project project, @NotNull byte[] content, @NotNull VirtualFile file) {
return new Builder(project).init(file).create(content).build();
public static FileAwareDocumentContent create(@Nullable Project project, @NotNull byte[] content, @NotNull VirtualFile highlightFile) {
return new Builder(project).init(highlightFile).create(content).build();
}
private static class Builder {
private final Project myProject;
private Document myDocument;
private FileType myFileType;
private VirtualFile myLocalFile;
private VirtualFile myHighlightFile;
private LineSeparator mySeparator;
private Charset myCharset;
@@ -77,17 +76,18 @@ public class FileAwareDocumentContent extends DocumentContentImpl {
@NotNull
private Builder init(@NotNull FilePath path) {
myLocalFile = LocalFileSystem.getInstance().findFileByPath(path.getPath());
myFileType = myLocalFile != null ? myLocalFile.getFileType() : path.getFileType();
myCharset = myLocalFile != null ? myLocalFile.getCharset() : path.getCharset(myProject);
path.refresh();
myHighlightFile = path.getVirtualFile();
myFileType = path.getFileType();
myCharset = path.getCharset(myProject);
return this;
}
@NotNull
private Builder init(@NotNull VirtualFile file) {
myLocalFile = file;
myFileType = file.getFileType();
myCharset = file.getCharset();
private Builder init(@NotNull VirtualFile highlightFile) {
myHighlightFile = highlightFile;
myFileType = highlightFile.getFileType();
myCharset = highlightFile.getCharset();
return this;
}
@@ -111,7 +111,7 @@ public class FileAwareDocumentContent extends DocumentContentImpl {
@NotNull
public FileAwareDocumentContent build() {
if (FileTypes.UNKNOWN.equals(myFileType)) myFileType = PlainTextFileType.INSTANCE;
return new FileAwareDocumentContent(myProject, myDocument, myFileType, myLocalFile, mySeparator, myCharset);
return new FileAwareDocumentContent(myProject, myDocument, myFileType, myHighlightFile, mySeparator, myCharset);
}
}
}
@@ -108,7 +108,7 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
myStatusPanel = new MyStatusPanel();
new MyFocusOppositePaneAction().setupAction(myPanel, this);
new MyFocusOppositePaneAction().setupAction(myPanel);
installEditorListeners();
@@ -819,12 +819,12 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
return getTextSettings().isEnableSyncScroll();
}
public int transfer(@NotNull Side side, int line) {
public int transfer(@NotNull Side baseSide, int line) {
if (myDiffChanges.isEmpty()) {
return line;
}
return super.transfer(side, line);
return super.transfer(baseSide, line);
}
@Override
@@ -29,8 +29,8 @@ public abstract class BaseSyncScrollable implements SyncScrollSupport.SyncScroll
*/
protected abstract void processHelper(@NotNull ScrollHelper helper);
public int transfer(@NotNull Side side, int line) {
ScrollHelper helper = new ScrollHelper(side, line);
public int transfer(@NotNull Side baseSide, int line) {
ScrollHelper helper = new ScrollHelper(baseSide, line);
processHelper(helper);
int master1 = helper.getMaster1();
@@ -17,6 +17,7 @@ package com.intellij.diff.tools.util;
import com.intellij.diff.DiffContext;
import com.intellij.diff.FrameDiffTool;
import com.intellij.diff.contents.DiffContent;
import com.intellij.diff.requests.DiffRequest;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.editor.Editor;
@@ -24,6 +25,7 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor;
public interface DiffDataKeys {
DataKey<Editor> CURRENT_EDITOR = DataKey.create("diff_current_editor");
DataKey<DiffContent> CURRENT_CONTENT = DataKey.create("diff_current_content");
DataKey<DiffRequest> DIFF_REQUEST = DataKey.create("diff_request");
DataKey<DiffContext> DIFF_CONTEXT = DataKey.create("diff_context");
@@ -35,7 +35,7 @@ public class SyncScrollSupport {
boolean isSyncScrollEnabled();
@CalledInAwt
int transfer(@NotNull Side side, int line);
int transfer(@NotNull Side baseSide, int line);
}
public static class TwosideSyncScrollSupport {
@@ -73,6 +73,15 @@ public class SyncScrollSupport {
myDuringSyncScroll = false;
}
}
@NotNull
public SyncScrollable getScrollable() {
return myScrollable;
}
public boolean isDuringSyncScroll() {
return myDuringSyncScroll;
}
}
public static class ThreesideSyncScrollSupport {
@@ -26,7 +26,6 @@ import com.intellij.diff.util.DiffUtil;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.actions.EditorActionUtil;
import com.intellij.openapi.editor.event.EditorMouseEvent;
import com.intellij.openapi.editor.ex.EditorEx;
@@ -114,7 +113,7 @@ public abstract class TextDiffViewerBase extends ListenerDiffViewerBase {
@NotNull
protected List<AnAction> createEditorPopupActions() {
return ContainerUtil.list(
ActionManager.getInstance().getAction("CompareClipboardWithSelection") // TODO: pass FileType to DataContext for highlighting
ActionManager.getInstance().getAction("CompareClipboardWithSelection")
);
}
@@ -262,6 +262,11 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
return myCurrentSide.select(myEditors);
}
@NotNull
public DocumentContent getCurrentContent() {
return myCurrentSide.select(myActualContents);
}
@NotNull
@Override
protected List<? extends EditorEx> getEditors() {
@@ -306,10 +311,8 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
protected OpenFileDescriptor getOpenFileDescriptor() {
EditorEx editor = getCurrentEditor();
DocumentContent content = getCurrentSide().select(myActualContents);
int offset = editor.getCaretModel().getOffset();
return content.getOpenFileDescriptor(offset);
return getCurrentContent().getOpenFileDescriptor(offset);
}
public static boolean canShowRequest(@NotNull DiffContext context, @NotNull DiffRequest request) {
@@ -392,6 +395,9 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
if (DiffDataKeys.CURRENT_EDITOR.is(dataId)) {
return getCurrentEditor();
}
else if (DiffDataKeys.CURRENT_CONTENT.is(dataId)) {
return getCurrentContent();
}
return super.getData(dataId);
}
@@ -109,7 +109,8 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
myPanel = new TwosideTextDiffPanel(this, myContentPanel, this, context);
new MyFocusOppositePaneAction().setupAction(myPanel, this);
new MyFocusOppositePaneAction(true).setupAction(myPanel);
new MyFocusOppositePaneAction(false).setupAction(myPanel);
myEditorSettingsAction = new MySetEditorSettingsAction();
myEditorSettingsAction.applyDefaults();
@@ -301,6 +302,12 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
return getCurrentSide().isLeft() ? myEditor1 : myEditor2;
}
@NotNull
public DocumentContent getCurrentContent() {
//noinspection ConstantConditions
return getCurrentSide().isLeft() ? myActualContent1 : myActualContent2;
}
@Nullable
protected EditorEx getEditor1() {
return myEditor1;
@@ -315,6 +322,14 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
// Abstract
//
@CalledInAwt
@NotNull
protected LogicalPosition transferPosition(@NotNull Side baseSide, @NotNull LogicalPosition position) {
if (mySyncScrollListener == null) return position;
int line = mySyncScrollListener.getScrollable().transfer(baseSide, position.line);
return new LogicalPosition(line, position.column);
}
@CalledInAwt
protected void scrollToLine(@NotNull Side side, int line) {
Editor editor = side.select(myEditor1, myEditor2);
@@ -350,11 +365,8 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
protected OpenFileDescriptor getOpenFileDescriptor() {
EditorEx editor = getCurrentEditor();
DocumentContent content = getCurrentSide().select(myActualContent1, myActualContent2);
assert content != null;
int offset = editor.getCaretModel().getOffset();
return content.getOpenFileDescriptor(offset);
return getCurrentContent().getOpenFileDescriptor(offset);
}
public static boolean canShowRequest(@NotNull DiffContext context, @NotNull DiffRequest request) {
@@ -388,10 +400,21 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
//
private class MyFocusOppositePaneAction extends FocusOppositePaneAction {
public MyFocusOppositePaneAction(boolean scrollToPosition) {
super(scrollToPosition);
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
if (myEditor1 == null || myEditor2 == null) return;
if (myScrollToPosition) {
EditorEx currentEditor = myCurrentSide.select(myEditor1, myEditor2);
EditorEx targetEditor = myCurrentSide.other().select(myEditor1, myEditor2);
LogicalPosition position = transferPosition(myCurrentSide, currentEditor.getCaretModel().getLogicalPosition());
targetEditor.getCaretModel().moveToLogicalPosition(position);
}
myCurrentSide = myCurrentSide.other();
myPanel.requestFocus();
getCurrentEditor().getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
@@ -423,6 +446,9 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
if (DiffDataKeys.CURRENT_EDITOR.is(dataId)) {
return getCurrentEditor();
}
else if (DiffDataKeys.CURRENT_CONTENT.is(dataId)) {
return getCurrentContent();
}
return super.getData(dataId);
}
@@ -203,10 +203,7 @@ public class DiffUtil {
if (editor == null) return;
editor.getCaretModel().removeSecondaryCarets();
editor.getCaretModel().moveToLogicalPosition(position);
ScrollingModel scrollingModel = editor.getScrollingModel();
scrollingModel.disableAnimation();
scrollingModel.scrollToCaret(ScrollType.CENTER);
scrollingModel.enableAnimation();
scrollToCaret(editor);
}
public static void scrollToLineAnimated(@Nullable final Editor editor, int line) {
@@ -0,0 +1,117 @@
/*
* 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.psi.codeStyle.autodetect;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Stack;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
class ContinuationIndentDetector {
private Stack<Bracket> myOpenedBrackets = ContainerUtil.newStack();
private final CharSequence myText;
private final int myLength;
private boolean myIncorrectBracketsOrder = false;
public ContinuationIndentDetector(@NotNull CharSequence text) {
myText = text;
myLength = text.length();
}
public void feedLineStartingAt(int startOffset) {
if (myIncorrectBracketsOrder) return;
int lineEndOffset = CharArrayUtil.indexOf(myText, "\n", startOffset, myLength);
if (lineEndOffset < 0) lineEndOffset = myLength;
for (int i = startOffset; i < lineEndOffset; i++) {
Bracket bracket = Bracket.forChar(myText.charAt(i));
if (bracket == null) continue;
processBracket(bracket);
}
}
private void processBracket(@NotNull Bracket bracket) {
if (bracket.isOpening()) {
myOpenedBrackets.add(bracket);
}
else {
if (!myOpenedBrackets.isEmpty() && bracket.isClosing(myOpenedBrackets.peek())) {
myOpenedBrackets.pop();
}
else {
myIncorrectBracketsOrder = true;
}
}
}
public boolean isContinuationIndent() {
if (myIncorrectBracketsOrder || myOpenedBrackets.isEmpty()) {
return false;
}
return myOpenedBrackets.peek() == Bracket.LPARENTH;
}
private enum Bracket {
LBRACE('{') {
@Override
boolean isOpening() {
return true;
}
},
LPARENTH('(') {
@Override
boolean isOpening() {
return true;
}
},
RBRACE('}') {
@Override
public boolean isClosing(Bracket bracket) {
return bracket == LBRACE;
}
},
RPARENTH(')') {
@Override
public boolean isClosing(Bracket bracket) {
return bracket == LPARENTH;
}
};
private final char myChar;
Bracket(char c) {
myChar = c;
}
public boolean isClosing(Bracket bracket) {
return false;
}
boolean isOpening() {
return false;
}
static Bracket forChar(char c) {
for (Bracket bracket : Bracket.values()) {
if (bracket.myChar == c) return bracket;
}
return null;
}
}
}
@@ -21,6 +21,7 @@ public class LineIndentInfo {
public static final LineIndentInfo EMPTY_LINE = new LineIndentInfo(LineType.EMPTY_LINE, -1);
public static final LineIndentInfo LINE_WITH_COMMENT = new LineIndentInfo(LineType.LINE_WITH_COMMENT, -1);
public static final LineIndentInfo LINE_WITH_TABS = new LineIndentInfo(LineType.LINE_WITH_TABS, -1);
public static final LineIndentInfo LINE_WITH_CONTINUATION_INDENT = new LineIndentInfo(LineType.LINE_WITH_CONTINUATION_INDENT, -1);
private final int myIndentSize;
private final LineType myType;
@@ -51,6 +52,7 @@ public class LineIndentInfo {
EMPTY_LINE,
LINE_WITH_COMMENT,
LINE_WITH_TABS,
LINE_WITH_WHITESPACE_INDENT
LINE_WITH_WHITESPACE_INDENT,
LINE_WITH_CONTINUATION_INDENT
}
}
@@ -31,10 +31,12 @@ public class LineIndentInfoBuilder {
private final CharSequence myText;
private final int myLength;
private final Commenter myCommenter;
private ContinuationIndentDetector myContinuationIndentDetector;
public LineIndentInfoBuilder(@NotNull CharSequence text, @Nullable Language language) {
myText = text;
myLength = text.length();
myContinuationIndentDetector = new ContinuationIndentDetector(text);
myCommenter = language != null ? LanguageCommenters.INSTANCE.forLanguage(language) : null;
}
@@ -68,11 +70,14 @@ public class LineIndentInfoBuilder {
return LineIndentInfo.LINE_WITH_COMMENT;
}
else if (CharArrayUtil.indexOf(myText, "\t", lineStartOffset, textStartOffset) > 0) {
myContinuationIndentDetector.feedLineStartingAt(lineStartOffset);
return LineIndentInfo.LINE_WITH_TABS;
}
else {
int indentSize = textStartOffset - lineStartOffset;
return LineIndentInfo.newWhiteSpaceIndent(indentSize);
boolean isContinuationIndent = myContinuationIndentDetector.isContinuationIndent();
myContinuationIndentDetector.feedLineStartingAt(lineStartOffset);
return isContinuationIndent ? LineIndentInfo.LINE_WITH_CONTINUATION_INDENT
: LineIndentInfo.newWhiteSpaceIndent(textStartOffset - lineStartOffset);
}
}
@@ -0,0 +1,162 @@
/*
* 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.psi.codeStyle.autodetect;
import com.intellij.util.containers.ContainerUtil;
import junit.framework.TestCase;
import java.util.List;
import java.util.Set;
public class ContinuationIndentDetectorTest extends TestCase {
private ContinuationIndentDetector myContinuationIndentDetector;
private List<Integer> myLineStartOffsets;
public void configure(String text) {
myContinuationIndentDetector = new ContinuationIndentDetector(text);
myLineStartOffsets = calculateLineStartOffsets(text);
}
public void testContinuationIndentInsideParenth() {
configure(
"test(\n" +
" \"aaaaa\" + \n" +
" \"bbbbb\");\n" +
"int a = 2;"
);
doCheckLinesWithContinuationIndents(1, 2);
}
public void testNoContinuationIndent_OnLineStartingWithRightParenth() {
configure(
"test(\n" +
" \"aaaaa\" + \n" +
" \"bbbbb\"\n" +
");"
);
doCheckLinesWithContinuationIndents(1, 2, 3);
}
public void testNoContinuationIndents_BetweenBraces() {
configure(
"import java.lang.Override;\n" +
"import java.lang.Runnable;\n" +
"\n" +
"class T {\n" +
" \n" +
" void test() {\n" +
" int a;\n" +
" int b;\n" +
" Runnable runnable = new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" System.out.println(\"AAA!\");\n" +
" }\n" +
" }\n" +
" }\n" +
" \n" +
"}"
);
doCheckLinesWithContinuationIndents();
}
public void testMixedBraces() {
configure(
"import java.lang.Runnable;\n" +
"\n" +
"class R {\n" +
"\n" +
"\n" +
" void test() {\n" +
" kuu(new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" }\n" +
" },\n" +
" new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" }\n" +
" }\n" +
" );\n" +
" }\n" +
"\n" +
" void kuu(Runnable a, Runnable b) {\n" +
" }\n" +
"}"
);
doCheckLinesWithContinuationIndents(11, 16);
}
public void testClosingBracesAtLineStart() {
configure("class Test {\n" +
" public static void main(String[] args) {\n" +
" tree.put(\"Web Development\", Pair.create(PlatformImplIcons.WebDevelopment, Arrays.asList(\n" +
" \"HTML:HtmlTools\",\n" +
" \"com.intellij.css\",\n" +
" \"JavaScript:JavaScript,JSIntentionPowerPack\",\n" +
" \"com.jetbrains.restClient\"\n" +
" )));\n" +
" }\n" +
"}");
doCheckLinesWithContinuationIndents(3, 4, 5, 6, 7);
}
public void testInsideParenth() {
configure("@State(\n" +
" name = \"AndroidRemoteDataBaseManager\",\n" +
" storages = {\n" +
" @Storage(\n" +
" file = StoragePathMacros.APP_CONFIG + \"/androidRemoteDatabases.xml\"\n" +
" )}\n" +
")\n" +
"class T {}");
doCheckLinesWithContinuationIndents(1, 2, 4, 5, 6);
}
private void doCheckLinesWithContinuationIndents(Integer... linesWithContinuationIndents) {
Set<Integer> continuationLines = ContainerUtil.newHashSet(linesWithContinuationIndents);
for (int currentLine = 0; currentLine < myLineStartOffsets.size(); currentLine++) {
Integer lineStartOffset = myLineStartOffsets.get(currentLine);
boolean isContinuation = myContinuationIndentDetector.isContinuationIndent();
if (continuationLines.contains(currentLine)) {
assertTrue("Line " + currentLine + " should start with continuation indent", isContinuation);
}
else {
assertTrue("Line " + currentLine + " should not start with continuation indent" ,!isContinuation);
}
myContinuationIndentDetector.feedLineStartingAt(lineStartOffset);
}
}
private List<Integer> calculateLineStartOffsets(String text) {
List<Integer> lineStartOffsets = ContainerUtil.newArrayList();
lineStartOffsets.add(0);
int lineStart = 0;
int lineFeed;
while ((lineFeed = text.indexOf('\n', lineStart)) > 0) {
lineStart = lineFeed + 1;
lineStartOffsets.add(lineStart);
}
return lineStartOffsets;
}
}
@@ -294,10 +294,8 @@ public class ContentManagerImpl implements ContentManager, PropertyChangeListene
}
int newSize = myContents.size();
ActionCallback result = new ActionCallback();
if (newSize > 0 && trackSelection) {
ActionCallback result = new ActionCallback();
if (indexToSelect > -1) {
final Content toSelect = mySelectionHistory.size() > 0 ? mySelectionHistory.get(0) : myContents.get(indexToSelect);
if (!isSelected(toSelect)) {
@@ -310,12 +308,12 @@ public class ContentManagerImpl implements ContentManager, PropertyChangeListene
}
}
}
return result;
}
else {
mySelection.clear();
return ActionCallback.DONE;
}
return result;
}
finally {
if (ApplicationManager.getApplication().isDispatchThread()) {
@@ -1221,7 +1221,10 @@ action.VcsHistory.ShowAllAffected.description=Show all changes made in the chose
action.AddFrameworkSupport.text=Add Framework Support...
action.Diff.FocusOppositePane.text=Select opposite pane in diff view
action.Diff.FocusOppositePane.text=Select Opposite Diff Pane
action.Diff.FocusOppositePane.description=Select opposite pane in diff view
action.Diff.FocusOppositePaneAndScroll.text=Select Position In Opposite Diff Pane
action.Diff.FocusOppositePaneAndScroll.description=Select the same position in opposite pane in diff view
action.Diff.PrevChange.text=Compare Previous File
action.Diff.NextChange.text=Compare Next File
action.Diff.SelectedChange.text=Choose File To Compare
@@ -547,6 +547,12 @@
<action id="NextDiff">
<keyboard-shortcut first-keystroke="F7"/>
</action>
<action id="Diff.FocusOppositePane">
<keyboard-shortcut first-keystroke="control TAB"/>
</action>
<action id="Diff.FocusOppositePaneAndScroll">
<keyboard-shortcut first-keystroke="control shift TAB"/>
</action>
<action id="Move">
<keyboard-shortcut first-keystroke="F6"/>
</action>
@@ -162,7 +162,9 @@
<action id="CompareFileWithEditor" class="com.intellij.diff.actions.CompareFileWithEditorAction"/>
<action id="CompareClipboardWithSelection" class="com.intellij.diff.actions.CompareClipboardWithSelectionAction"/>
<action id="Diff.FocusOppositePane" class="com.intellij.openapi.diff.actions.FocusOppositePaneAction" use-shortcut-of="NextSplitter"/>
<action id="Diff.FocusOppositePane" class="com.intellij.openapi.diff.actions.FocusOppositePaneAction"/>
<action id="Diff.FocusOppositePaneAndScroll" class="com.intellij.openapi.actionSystem.EmptyAction"/>
<action id="Diff.ShowSettingsPopup" class="com.intellij.openapi.actionSystem.EmptyAction" text="Show Diff Settings Popup..."/>
<action id="Diff.ShowInExternalTool" class="com.intellij.openapi.actionSystem.EmptyAction" icon="AllIcons.General.ExternalToolsSmall"
text="Show Diff in External Tool"/>
@@ -132,6 +132,8 @@ public abstract class KeymapsTestCase extends PlatformTestCase {
{ "shift control U", "ShelveChanges.UnshelveWithDialog", "EditorToggleCase"},
{ "control E", "RecentFiles", "Vcs.ShowMessageHistory"},
{ "control alt Z", "Vcs.RollbackChangedLines", "ChangesView.Revert"},
{ "control TAB", "Switcher", "Diff.FocusOppositePane"},
{ "shift control TAB", "Switcher", "Diff.FocusOppositePaneAndScroll"},
});
put("Mac OS X 10.5+", new String[][] {
{ "F5", "CopyElement", "Console.TableResult.Reload", "UML.ApplyCurrentLayout"},
@@ -43,8 +43,6 @@ import java.util.List;
public abstract class CacheChangeProcessor extends DiffRequestProcessor {
private static final Logger LOG = Logger.getInstance(CacheChangeProcessor.class);
@NotNull private final Project myProject;
@NotNull private final SoftHardCacheMap<Change, Pair<Change, DiffRequest>> myRequestCache =
new SoftHardCacheMap<Change, Pair<Change, DiffRequest>>(5, 5);
@@ -54,12 +52,10 @@ public abstract class CacheChangeProcessor extends DiffRequestProcessor {
public CacheChangeProcessor(@NotNull Project project) {
super(project);
myProject = project;
}
public CacheChangeProcessor(@NotNull Project project, @NotNull String place) {
super(project, place);
myProject = project;
}
//
@@ -133,7 +129,7 @@ public abstract class CacheChangeProcessor extends DiffRequestProcessor {
@NotNull
@CalledInBackground
private DiffRequest loadRequest(@NotNull Change change, @NotNull ProgressIndicator indicator) {
ChangeDiffRequestProducer presentable = ChangeDiffRequestProducer.create(myProject, change);
ChangeDiffRequestProducer presentable = ChangeDiffRequestProducer.create(getProject(), change);
if (presentable == null) return new ErrorDiffRequest("Can't show diff");
try {
return presentable.process(getContext(), indicator);
@@ -162,6 +158,12 @@ public abstract class CacheChangeProcessor extends DiffRequestProcessor {
myRequestCache.clear();
}
@NotNull
@Override
public Project getProject() {
return super.getProject();
}
//
// Navigation
//