From fe2cd906691dca147ebaa76531abe8f79c72d092 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 19 Oct 2011 12:31:39 +0200 Subject: [PATCH 001/128] Navigate to directory fixed --- .../src/com/intellij/psi/impl/file/PsiDirectoryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java index 9eb4ec95632d..06ee55ba0457 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java @@ -557,7 +557,7 @@ public class PsiDirectoryImpl extends PsiElementBase implements PsiDirectory, Qu } public void navigate(boolean requestFocus) { - PsiNavigationSupport.getInstance().navigateToDirectory(this, false); + PsiNavigationSupport.getInstance().navigateToDirectory(this, requestFocus); } protected Icon getElementIcon(final int flags) { From 7f1d792711836b276c21d0a8929724c09cbc22d2 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 19 Oct 2011 13:06:01 +0200 Subject: [PATCH 002/128] loading optimized file manager dynamically from the pre-compiled jar --- build/scripts/layouts.gant | 1 + jps/jps-builders/jps-builders.iml | 9 +++++ .../jps/incremental/java/EmbeddedJavac.java | 18 ++++++--- .../jps/incremental/java/JavaBuilder.java | 28 +++++++++++++- .../jps/server/ClasspathBootstrap.java | 36 +++++++++++++++++- jps/lib/optimizedFileManager.jar | Bin 0 -> 4816 bytes .../ether/dependencyView/Mappings.java | 10 +++-- 7 files changed, 90 insertions(+), 12 deletions(-) create mode 100644 jps/lib/optimizedFileManager.jar diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant index e4ee8c3a45de..6adb59987bee 100644 --- a/build/scripts/layouts.gant +++ b/build/scripts/layouts.gant @@ -153,6 +153,7 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir module("jps-builders") module("jps-model") } + fileset(dir: "$home/jps/lib", includes: "optimizedFileManager.jar") fileset(dir: "$home/lib", includesfile: "${home}/lib/required_for_dist.txt") diff --git a/jps/jps-builders/jps-builders.iml b/jps/jps-builders/jps-builders.iml index 35b220c1453c..23359c21edff 100644 --- a/jps/jps-builders/jps-builders.iml +++ b/jps/jps-builders/jps-builders.iml @@ -18,6 +18,15 @@ + + + + + + + + + diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/EmbeddedJavac.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/EmbeddedJavac.java index 09eb60cba4cf..79201e291db0 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/EmbeddedJavac.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/EmbeddedJavac.java @@ -1,8 +1,10 @@ package org.jetbrains.jps.incremental.java; +import com.intellij.openapi.util.SystemInfo; import org.jetbrains.jps.incremental.CompileContext; import org.jetbrains.jps.incremental.messages.BuildMessage; import org.jetbrains.jps.incremental.messages.CompilerMessage; +import org.jetbrains.jps.server.ClasspathBootstrap; import javax.tools.*; import java.io.File; @@ -66,6 +68,7 @@ public class EmbeddedJavac { } } + //noinspection IOResourceOpenedButNotSafelyClosed final LineOutputWriter out = new LineOutputWriter() { protected void lineAvailable(String line) { outConsumer.outputLineAvailable(line); @@ -121,11 +124,16 @@ public class EmbeddedJavac { } }; StandardJavaFileManager stdManager = null; - try { - stdManager = (StandardJavaFileManager)Class.forName("org.jetbrains.jps.incremental.java.OptimizedFileManager").newInstance(); - } - catch (Throwable e) { - compileContext.processMessage(new CompilerMessage("Javac", BuildMessage.Kind.INFO, "Failed to load JPS optimized file manager for javac: " + e.getMessage())); + final Class optimizedManagerClass = ClasspathBootstrap.getOptimizedFileManagerClass(); + if (optimizedManagerClass != null) { + try { + stdManager = optimizedManagerClass.newInstance(); + } + catch (Throwable e) { + if (SystemInfo.isWindows) { + compileContext.processMessage(new CompilerMessage("Javac", BuildMessage.Kind.INFO, "Failed to load JPS optimized file manager for javac: " + e.getMessage())); + } + } } if (stdManager != null) { myStdManager = stdManager; diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index f477bc64b171..877577d546b2 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -54,6 +54,8 @@ public class JavaBuilder extends Builder{ } }; + //private static final Key DELTA_MAPPINGS_CALLBACK_KEY = Key.create("_dependency_data_"); + private final EmbeddedJavac myJavacCompiler; public JavaBuilder(ExecutorService tasksExecutor) { @@ -61,6 +63,21 @@ public class JavaBuilder extends Builder{ //add here class processors in the sequence they should be executed //myJavacCompiler.addClassProcessor(new EmbeddedJavac.ClassPostProcessor() { // public void process(CompileContext context, OutputFileObject out) { + // final Callbacks.Backend callback = DELTA_MAPPINGS_CALLBACK_KEY.get(context); + // if (callback != null) { + // final String className = out.getClassName(); + // final OutputFileObject.Content content = out.getContent(); + // final File srcFile = out.getSourceFile(); + // if (srcFile != null && content != null) { + // // todo: the callback is not thread-safe? + // final ClassReader reader = new ClassReader(content.getBuffer(), content.getOffset(), content.getLength()); + // //noinspection SynchronizationOnLocalVariableOrMethodParameter + // synchronized (callback) { + // // todo: parse class data out of synchronized block (move it from the 'associate' implementation) + // callback.associate(className, Callbacks.getDefaultLookup(srcFile.getPath()), reader); + // } + // } + // } // } //}); } @@ -164,6 +181,10 @@ public class JavaBuilder extends Builder{ ProjectPaths.KEY.set(context, paths = new ProjectPaths(context.getProject())); } + //final Mappings delta = new Mappings(null); // todo + //final Callbacks.Backend callback = delta.getCallback(); + //DELTA_MAPPINGS_CALLBACK_KEY.set(context, callback); + // todo: consider corresponding setting in CompilerWorkspaceConfiguration final boolean addNotNullAssertions = true; @@ -212,9 +233,14 @@ public class JavaBuilder extends Builder{ return ExitCode.OK; } finally { + //DELTA_MAPPINGS_CALLBACK_KEY.set(context, callback); + outputSink.writePendingData(); - for (File file : outputSink.getSuccessfullyCompiled()) { + final Set successfullyCompiled = outputSink.getSuccessfullyCompiled(); + //delta.compensateRemovedContent(successfullyCompiled); + //globalMappings.integrate(mappings, ); //todo + for (File file : successfullyCompiled) { tsStorage.saveStamp(file); } for (File file : successfulForms) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java index c42d4fd78474..eeda2adecbd3 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java +++ b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java @@ -24,9 +24,11 @@ import com.jgoodies.forms.layout.CellConstraints; import gnu.trove.TIntHash; import net.n3.nanoxml.IXMLBuilder; import org.codehaus.groovy.GroovyException; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.MacroExpander; import org.objectweb.asm.ClassWriter; +import javax.tools.*; import java.io.File; import java.util.ArrayList; import java.util.LinkedHashSet; @@ -38,10 +40,28 @@ import java.util.Set; * Date: 9/12/11 */ public class ClasspathBootstrap { - private ClasspathBootstrap() { + public static final String JPS_RUNTIME_PATH = "rt/jps-incremental"; + + private static class OptimizedFileManagerClassHolder { + static final String CLASS_NAME = "org.jetbrains.jps.incremental.java.OptimizedFileManager"; + static final Class managerClass; + static { + Class aClass = null; + try { + aClass = (Class)Class.forName(CLASS_NAME); + } + catch (Throwable e) { + aClass = null; + } + managerClass = aClass; + } + + private OptimizedFileManagerClassHolder() { + } } - public static final String JPS_RUNTIME_PATH = "rt/jps-incremental"; + private ClasspathBootstrap() { + } public static List getApplicationClasspath() { final Set cp = new LinkedHashSet(); @@ -61,6 +81,13 @@ public class ClasspathBootstrap { cp.add(getResourcePath(NotNullVerifyingInstrumenter.class)); // not-null cp.add(getResourcePath(IXMLBuilder.class)); // nano-xml + final Class optimizedFileManagerClass = getOptimizedFileManagerClass(); + if (optimizedFileManagerClass != null) { + cp.add(getResourcePath(optimizedFileManagerClass)); // optimizedFileManager + } + + //cp.add(getResourcePath(Mappings.class)); // todo: temporary + //final File jpsRuntime = new File(jpsFacadeJar.getParentFile(), JPS_RUNTIME_PATH); //final File[] files = jpsRuntime.listFiles(); //if (files != null) { @@ -85,6 +112,11 @@ public class ClasspathBootstrap { return new ArrayList(cp); } + @Nullable + public static Class getOptimizedFileManagerClass() { + return OptimizedFileManagerClassHolder.managerClass; + } + public static File getResourcePath(Class aClass) { return new File(PathManager.getResourceRoot(aClass, "/" + aClass.getName().replace('.', '/') + ".class")); } diff --git a/jps/lib/optimizedFileManager.jar b/jps/lib/optimizedFileManager.jar new file mode 100644 index 0000000000000000000000000000000000000000..d24ca7ac69b32b5566f0f09fb031b5ad2a5f2016 GIT binary patch literal 4816 zcma)=2UHW=zQzHmB0)r&bVCchcSI>sIv9FSAoLPK2SKGs6OaHxqzNPxkrGNMa#R8l zrAU(|f+D>mNEPv+=lUM&oO9p3d)At7_N@Q@etYjVYu3zXtapa|BFWFzZ3j{Rb@8tg z`HA`>T_ueFZ3W<86&~;a7!vC4^{Jj0OJ3u^!MM=>Hl}lWf~U)GvU?>_$#jlzN$jMD4#bFhT^ld%K6hox$#2a093h z)D?~tck+Vz`xC9gx%VE-bsR%{MNbdlN;Wr^f4iP{ZpHRPb<^Q!OPg`6dv;Ra~kb-m(~G^)8l|~&!D#yESdXa2@Zssv3 zY+tgch8ccfBP4}@VzRy@df5+eT2r^Et_3!)(2ci(6k3^PM;hlgIh!}^lx`UzLmdWh z^RQfbx0&XAfa5N3+n0?OzQx?Ju&;sqKA2iPtK{IhFA$IQEA@Jw*&B@9*yHU<<<{6| zkZ|AExscK|@A_t*W&EfM%p(+oNV9K(&lK_zy7LGu7awg>jgikv3Wf8&=nuUol-4VX zdY-Y6RQn)1v(&H3R=&<17IfE&Drkz&Dab0?(}t!FH14#{$J6rK*KuKZ=u4z0l?>4M zeQPBy+9a#nI-!Nxsm7kC-)DzE*-PB}teZSd@R;#}mh_Z|sv;w!J8lX=|5$^+U$=Wj1j&F{O@65e}_Yh`nu3Gj)-@>1&Pg?{s_10~{vt zE_fAhOPwgG?D9I)mwF{ffjV%Jp|{UW38^PbohzB7YEcJbbvFLyV7}bv2?jcTspO{# zXYY|2JaWw)=-`;mtC6-c=+V}~mLRV=R>Y$M1UrRSaOwj9rx-?@cV9`Rv%`0CNPW)u zVbv2FJ_9QmF>KnRP0AXXn)xG1?4Sy5kMua=E6Ay*^x-$XNR73@a#Qn{aI-`w&Qj0WVGfeQhmp@{{ltu1A_vR`>A~oFSBG zv=K0UplrEFX$IW-ag|Nax{m3!UTf2$!532vmz0K~^1HVT)l|3WF}?F_#SN^{!`%T( zCnD7p^h=rf$Az%u(c+iIKVmOyv*B6oN)_rgV7oN)*8Zwlm1Vt#ESmJ}u6tR}jtzZ?&M$%{x(RRKK0I6d zXwtyS&KwP95IARr1^}TuV@lQ1(&=u(ke2Y-ytQ$|Nn_exp{D}#5bafEnSA^EpKso| zDWbD8QiB4AxqeIB*q5<*%guAstW2L8Uy596a-U%oH~k>S8%!g*A4ln~&tErhXvLZ1 zL@N)AWR{-s=!EE)v!7cRrRi*0xrB}!xu>j*!(H7eKuEhJ;dCL4w2QE7xbq@2jLZc^Ut*D6tx)gx<4~!Uj1?o6qy%E1S9~(-A%qrQbzLh{ps1ycS+1pwNpG>p zP!v>igW-9XvIdJ@0@ez=2xHq~=uVsq0U7BB-hZclx5Kh&X^g9LQIS+|85W9*s(+cN z{Prcf#ZsrENf*W1SVHLwNF&4np%d@+5d1+&eN4hlTYRfdwn6O3dA1Q z9wcBVn(~gqo6X)DN5CmLKvH0|yL%T4oD#R$#O^e#k>{ zJnFrV7=9p@w&$MW?sM!6p?p-4Zqn6dRCb02=)J4RI?Vj~k=anIlU~T-@|Py`8%td)BaGe_ za!;p_B`3u4Zhcm@Bt(b-9K};E-O$24vl9f*L)!#x{}F&?i_S`*jEK8}dQu00XnyvV!J#zAj` zyQ7^{?lT#!Xt5DntcZ_6HxRO&ytX{)`brPMnrrA!0Z6(p))+E;fx|~oq4(0Jd@pSk30>sn2e5~0I3|;|o<$T) zOJ&PFB{yilUtrc?ZnMFy2u;70x6mTvA>{t3q$SVE=NsNed}{$?l7)#$*A~K}mV(#S zOG*|q9_y4~N(iVPncmnt6bCXbuhco4rcrWy;d8aSvjyknp&w&=71whm*P{v|MtW9# z-=K{S_9zrys1z$)3$Ulkx^7FQK*a@U9VIBR*CT&Wll2bgGmsY#4=}{|#6^nf&UT5~ zx|f@X$nEMbQFm1lpSI_wwv0EURv&`dwM7JrD@jrU@Y}`Y+m7O*cVf#rU|v~Z{$-qy z`Aiv|$$GqTrtlNv4&|tI;{VCZu0|7T5cRh%@v4eyX=cSpic?cU%wp zB{c>RpOi&wZk1h@jX4V-wAEDO35+9E?NROVF%dvZH|n~nm{67G#b*Fo`gV3e$5%JY z;6-M(X;A~yEM8Q1AwxGKmMP(*F2<8by2ALo8BS&7 zWrD35yXUm()8ZO6vN}iqD4ZH8?X*_p;OlLB^bXRwh1{EtjWBBi;NcTa_J{a)AL5jjSd;8iiPk6IAas@=k_|i;SF#>_ z*j-Wj1b=oV&8wuk(b1=VFkQiTU)+s5r?bqOSLlWccM8!Dp=0OlmI9Na>-6u*%H%An z;z^@H?$9MNqya9uv%MmdN=9jQSNzfVxMav~a%w5f$7JG46o1uh*HcYu+gRm8qXU#w zrMc1w3VH0j*Z{Z57#=9K@tk{zHGGw;0ChjymFBZCHxyHenzJsJYk;N(5avW$H5aj6 zBGe!5FbRf6+DvU*BvKGaxz4i_&OU+MmVQW0#Q}iEX(~$IrEtRDyC|PN?I4j^PS7;d zGoEYO1!w22z2XQ&MEX~Gfn7J8VT+f0AI7J71d_Fi*!@tO!D|5VUiEM};Il~&F=)!9N7I3e zsLXK`&oepd_kQSL8ZxmsHoJ zJu()c{(|**r&eV9z%?{e+27QeiqHatk5eQ`ZF!dOBTa(>2}2r9^6+;)29}3SSMEe- z@CNbjjKq8s&F%f8fqa!?{VYssUD;wTTY5Q!>+Ql4)7X84{Z+|@%K(+yg)HlZ-V9SE zy|Ss;*(H=3{6ga@C_N;^P+k0U=#*5t;#aEilbfm1Z^$-NG)56$B&cyrpIt>OYP+E7 zJV$EuHOYQ7>PL2MQul01|>WRyEh+i>lg zj>beNIC?AawW6H!vV-?WuXpm=Tb73jO)K69%^(sZ$RS;6@zQ}+9e%(R2%?HMc{}M7 z5^adR7>XD%%@;BCGzPod#NA75I??P#RQ_}U<{bf(Z9fHXXDzp~-^Jpr=SdW(vz%^6UBdMVtgnagX z{TthfeMPJVHyR8-t4U!pY)7sLR$F7Y*m%QJCgog)R}iFoZ#CVkTt~KqVgquz@Oc05 zrbsL$*9i6UR+GtV<>?ZKX6WbKB>z>F#K|5fpSH@~yuz{lSrgfiq^q9Z;}?K#c2kgP zzr4FB>tKqCVmvg&11nOK{h-_5HtmI6mzl7lCbsZqt~R8gvfh?>MYbC5eQaKd4ec|x z7B7(v_WyXK>p&kIhY95z%6PdW!~FOYOium-l3j2v6AyZ^F#qZx^hTV-9ZWVOD3bf- z50oOJVbj-GkCaTE2EDC|Fi%9 zxdKQ|yPo`+|8o7myy3Ke8|F{H-};+#+W+sV#A$!Szxn^nC{8ny?HRxQT*Ghu%{tBa zdy;XQ5&4gd)49fJo?B<;8LboEZ)JFY`_~?x=KVeWIL&MMkGx-5$Z2SN`;6dE=x=R# z68#tGKP4u=p*$zRZ~qBtg(P2;y3>rqgia7ZXmjubKy6474| G-v0oc(@e|& literal 0 HcmV?d00001 diff --git a/jps/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/src/org/jetbrains/ether/dependencyView/Mappings.java index 760aac438542..18fd8108f6d5 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -1,6 +1,6 @@ package org.jetbrains.ether.dependencyView; -import org.codehaus.groovy.transform.DelegateASTTransformation; +import org.jetbrains.annotations.Nullable; import org.jetbrains.ether.Pair; import org.jetbrains.ether.ProjectWrapper; import org.objectweb.asm.ClassReader; @@ -895,14 +895,15 @@ public class Mappings { } public void associate(final String classFileName, final Callbacks.SourceFileNameLookup sourceFileName, final ClassReader cr) { - final StringCache.S classFileNameS = StringCache.get(project.getRelativePath(classFileName)); + final StringCache.S classFileNameS = StringCache.get(project != null? project.getRelativePath(classFileName) : classFileName); final Pair>> result = ClassfileAnalyzer.analyze(classFileNameS, cr); final ClassRepr repr = result.fst; final UsageRepr.Cluster localUsages = result.snd.fst; final Set localAnnotationUsages = result.snd.snd; + final String srcFileName = sourceFileName.get(repr == null ? null : repr.getSourceFileName().value); final StringCache.S sourceFileNameS = - StringCache.get(project.getRelativePath(sourceFileName.get(repr == null ? null : repr.getSourceFileName().value))); + StringCache.get(project != null? project.getRelativePath(srcFileName) : srcFileName); for (UsageRepr.Usage u : localUsages.getUsages()) { updateDependency(sourceFileNameS, u.getOwner()); @@ -957,9 +958,10 @@ public class Mappings { }; } + @Nullable private final ProjectWrapper project; - public Mappings(final ProjectWrapper p) { + public Mappings(@Nullable final ProjectWrapper p) { project = p; } From b08b51ec15eddbf96eceb1945b26331234ab30cd Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Tue, 18 Oct 2011 14:27:29 +0400 Subject: [PATCH 003/128] IDEA-53476 Gradle integration (Maven's level - dependencies, modules, repositories) 1. Implemented gradle home propagation to the default project from the opened one; 2. Added recovery for non-successful gradle home retrieval for particular project (falling back to the default project then); --- .../gradle/config/GradleConfigurable.java | 34 ++++++++++++++++++- .../gradle/util/GradleLibraryManager.java | 9 ++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java index c9d96c09bbc4..c1f9dad8797c 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java @@ -15,9 +15,11 @@ */ package org.jetbrains.plugins.gradle.config; +import com.intellij.ide.util.PropertiesComponent; import com.intellij.ide.util.projectWizard.NamePathComponent; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Alarm; @@ -44,6 +46,17 @@ public class GradleConfigurable implements SearchableConfigurable { @NonNls public static final String HELP_TOPIC = "reference.settingsdialog.project.gradle"; + /** + * There is a possible case that end-user defines gradle home while particular project is open. We want to use that gradle + * home for the default project as well until that is manually changed for the default project. + *

+ * Current constant holds key of the value that defines if gradle home for default project should be tracked from + * the non-default one. + *

+ * This property has a form of 'not-propagate' in order to default to 'propagate'. + */ + @NonNls private static final String NOT_PROPAGATE_GRADLE_HOME_TO_DEFAULT_PROJECT = "gradle.not.propagate.home.to.default.project"; + private final GradleLibraryManager myLibraryManager = GradleLibraryManager.INSTANCE; private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); private final Project myProject; @@ -135,7 +148,23 @@ public class GradleConfigurable implements SearchableConfigurable { @Override public void apply() { useNormalColorForPath(); - GradleSettings.getInstance(myProject).GRADLE_HOME = myGradleHomeComponent.getPath(); + String path = myGradleHomeComponent.getPath(); + GradleSettings.getInstance(myProject).GRADLE_HOME = path; + + // There is a possible case that user defines gradle home for particular open project. We want to apply that value + // to the default project as well if it's still non-defined. + Project defaultProject = ProjectManager.getInstance().getDefaultProject(); + if (defaultProject == myProject) { + PropertiesComponent.getInstance().setValue(NOT_PROPAGATE_GRADLE_HOME_TO_DEFAULT_PROJECT, Boolean.TRUE.toString()); + return; + } + + + if (!StringUtil.isEmpty(path) + && !Boolean.parseBoolean(PropertiesComponent.getInstance().getValue(NOT_PROPAGATE_GRADLE_HOME_TO_DEFAULT_PROJECT))) + { + GradleSettings.getInstance(defaultProject).GRADLE_HOME = path; + } } @Override @@ -143,6 +172,9 @@ public class GradleConfigurable implements SearchableConfigurable { useNormalColorForPath(); myPathManuallyModified = false; String valueToUse = GradleSettings.getInstance(myProject).GRADLE_HOME; + if (StringUtil.isEmpty(valueToUse)) { + valueToUse = GradleSettings.getInstance(ProjectManager.getInstance().getDefaultProject()).GRADLE_HOME; + } if (!StringUtil.isEmpty(valueToUse)) { myGradleHomeSettingType = myLibraryManager.isGradleSdkHome(new File(valueToUse)) ? GradleHomeSettingType.EXPLICIT_CORRECT : diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java index c27bed2df53f..9d2ef6c5d728 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java @@ -76,10 +76,17 @@ public class GradleLibraryManager { * * @return file handle that points to the gradle installation home (if any) */ + @Nullable public File getGradleHome() { ProjectManager projectManager = ProjectManager.getInstance(); Project[] openProjects = projectManager.getOpenProjects(); - return openProjects.length == 1 ? getGradleHome(openProjects[0]) : getGradleHome(projectManager.getDefaultProject()); + if (openProjects.length == 1) { + File result = getGradleHome(openProjects[0]); + if (result != null) { + return result; + } + } + return getGradleHome(projectManager.getDefaultProject()); } /** From a2f4f95a4e71e3de0b4b5c17ba3c44e17da1f769 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Wed, 19 Oct 2011 15:34:02 +0400 Subject: [PATCH 004/128] IDEA-75680 Editor: make 'select whole line on triple click' default behavior --- .../options/editor/EditorOptionsPanel.form | 16 +++++++--- .../options/editor/EditorOptionsPanel.java | 12 +++++--- .../openapi/editor/EditorSettings.java | 5 ++-- .../ex/EditorSettingsExternalizable.java | 16 +++++++--- .../openapi/editor/impl/EditorImpl.java | 4 +-- .../openapi/editor/impl/SettingsImpl.java | 29 +++++++++++-------- .../src/messages/ApplicationBundle.properties | 1 + 7 files changed, 54 insertions(+), 29 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form index 2721f16caa1c..797ffafcb413 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form @@ -23,7 +23,7 @@ - + @@ -34,7 +34,7 @@ - + @@ -44,7 +44,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -62,6 +62,14 @@ + + + + + + + + diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java index f5f26f91487b..b7164f14ab2e 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java @@ -67,7 +67,8 @@ public class EditorOptionsPanel { private JCheckBox myCbVirtualPageAtBottom; private JCheckBox myCbEnableDnD; private JCheckBox myCbEnableWheelFontChange; - private JCheckBox myCbHonorCamelHumpsWhenSelectingByClicking; + private JCheckBox myCbHonorCamelHumpsWhenSelectingByDoubleClick; + private JCheckBox myCbHonorCamelHumpsWhenSelectingByTripleClick; private JPanel myHighlightSettingsPanel; private JRadioButton myRbPreferScrolling; @@ -159,7 +160,8 @@ public class EditorOptionsPanel { // Advanced mouse myCbEnableDnD.setSelected(editorSettings.isDndEnabled()); myCbEnableWheelFontChange.setSelected(editorSettings.isWheelFontChangeEnabled()); - myCbHonorCamelHumpsWhenSelectingByClicking.setSelected(editorSettings.isMouseClickSelectionHonorsCamelWords()); + myCbHonorCamelHumpsWhenSelectingByDoubleClick.setSelected(editorSettings.isMouseClickSelectionHonorsCamelWords(2)); + myCbHonorCamelHumpsWhenSelectingByTripleClick.setSelected(editorSettings.isMouseClickSelectionHonorsCamelWords(3)); myRbPreferMovingCaret.setSelected(editorSettings.isRefrainFromScrolling()); myRbPreferScrolling.setSelected(!editorSettings.isRefrainFromScrolling()); @@ -236,7 +238,8 @@ public class EditorOptionsPanel { editorSettings.setDndEnabled(myCbEnableDnD.isSelected()); editorSettings.setWheelFontChangeEnabled(myCbEnableWheelFontChange.isSelected()); - editorSettings.setMouseClickSelectionHonorsCamelWords(myCbHonorCamelHumpsWhenSelectingByClicking.isSelected()); + editorSettings.setMouseClickSelectionHonorsCamelWords(2, myCbHonorCamelHumpsWhenSelectingByDoubleClick.isSelected()); + editorSettings.setMouseClickSelectionHonorsCamelWords(3, myCbHonorCamelHumpsWhenSelectingByTripleClick.isSelected()); editorSettings.setRefrainFromScrolling(myRbPreferMovingCaret.isSelected()); editorSettings.setVariableInplaceRenameEnabled(myCbRenameLocalVariablesInplace.isSelected()); @@ -342,7 +345,8 @@ public class EditorOptionsPanel { // advanced mouse isModified |= isModified(myCbEnableDnD, editorSettings.isDndEnabled()); isModified |= isModified(myCbEnableWheelFontChange, editorSettings.isWheelFontChangeEnabled()); - isModified |= isModified(myCbHonorCamelHumpsWhenSelectingByClicking, editorSettings.isMouseClickSelectionHonorsCamelWords()); + isModified |= isModified(myCbHonorCamelHumpsWhenSelectingByDoubleClick, editorSettings.isMouseClickSelectionHonorsCamelWords(2)); + isModified |= isModified(myCbHonorCamelHumpsWhenSelectingByTripleClick, editorSettings.isMouseClickSelectionHonorsCamelWords(3)); isModified |= myRbPreferMovingCaret.isSelected() != editorSettings.isRefrainFromScrolling(); diff --git a/platform/platform-api/src/com/intellij/openapi/editor/EditorSettings.java b/platform/platform-api/src/com/intellij/openapi/editor/EditorSettings.java index 580137106bbd..69128fd75c75 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/EditorSettings.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/EditorSettings.java @@ -88,9 +88,8 @@ public interface EditorSettings { boolean isWheelFontChangeEnabled(); void setWheelFontChangeEnabled(boolean val); - boolean isMouseClickSelectionHonorsCamelWords(); - void setMouseClickSelectionHonorsCamelWords(boolean val); - + boolean isMouseClickSelectionHonorsCamelWords(int clicksCount); + void setMouseClickSelectionHonorsCamelWords(int clicksCount, boolean val); boolean isVariableInplaceRenameEnabled(); void setVariableInplaceRenameEnabled(boolean val); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java index 0125d61de1bc..42e7e3ab7553 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java @@ -69,6 +69,7 @@ public class EditorSettingsExternalizable implements NamedJDOMExternalizable, Ex public boolean IS_DND_ENABLED = true; public boolean IS_WHEEL_FONTCHANGE_ENABLED = true; public boolean IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS = true; + public boolean IS_TRIPLE_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS = false; @Deprecated public boolean IS_NATIVE2ASCII_FOR_PROPERTIES_FILES; @Deprecated @@ -457,12 +458,19 @@ public class EditorSettingsExternalizable implements NamedJDOMExternalizable, Ex myOptions.IS_WHEEL_FONTCHANGE_ENABLED = val; } - public boolean isMouseClickSelectionHonorsCamelWords() { - return myOptions.IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS; + public boolean isMouseClickSelectionHonorsCamelWords(int clicksCount) { + switch (clicksCount) { + case 2: return myOptions.IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS; + case 3: return myOptions.IS_TRIPLE_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS; + default: return false; + } } - public void setMouseClickSelectionHonorsCamelWords(boolean val) { - myOptions.IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS = val; + public void setMouseClickSelectionHonorsCamelWords(int clicksCount, boolean val) { + switch (clicksCount) { + case 2: myOptions.IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS = val; break; + case 3: myOptions.IS_TRIPLE_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS = val; + } } public boolean isVariableInplaceRenameEnabled() { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 0ae0e69fbff6..f76448fefa14 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -4920,11 +4920,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi if (!e.isPopupTrigger()) { switch (e.getClickCount()) { case 2: - selectWordAtCaret(mySettings.isMouseClickSelectionHonorsCamelWords() && mySettings.isCamelWords()); + selectWordAtCaret(mySettings.isMouseClickSelectionHonorsCamelWords(2) && mySettings.isCamelWords()); break; case 3: - if (mySettings.isMouseClickSelectionHonorsCamelWords() && mySettings.isCamelWords()) { + if (mySettings.isMouseClickSelectionHonorsCamelWords(3) && mySettings.isCamelWords()) { // We want to differentiate between triple and quadruple clicks when 'select by camel humps' is on. The former // is assumed to select 'hump' while the later points to the whole word. selectWordAtCaret(false); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java index 4b6ba3aad159..9da0dd70002f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java @@ -32,16 +32,14 @@ import com.intellij.openapi.editor.impl.softwrap.SoftWrapAppliancePlaces; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; +import gnu.trove.TIntIntHashMap; import org.jetbrains.annotations.Nullable; public class SettingsImpl implements EditorSettings { + private TIntIntHashMap myHonorCamelHumpsOnClicks; @Nullable private final EditorEx myEditor; private Boolean myIsCamelWords; - public SettingsImpl(@Nullable EditorEx editor) { - myEditor = editor; - } - // This group of settings does not have UI private SoftWrapAppliancePlaces mySoftWrapAppliancePlace = SoftWrapAppliancePlaces.MAIN_EDITOR; private int myAdditionalLinesCount = 5; @@ -72,7 +70,6 @@ public class SettingsImpl implements EditorSettings { private Boolean myIsAdditionalPageAtBottom = null; private Boolean myIsDndEnabled = null; private Boolean myIsWheelFontChangeEnabled = null; - private Boolean myIsMouseClickSelectionHonorsCamelWords = null; private Boolean myIsRenameVariablesInplace = null; private Boolean myIsRefrainFromScrolling = null; private Boolean myUseSoftWraps = null; @@ -80,6 +77,10 @@ public class SettingsImpl implements EditorSettings { private Boolean myUseCustomSoftWrapIndent = null; private Integer myCustomSoftWrapIndent = null; + public SettingsImpl(@Nullable EditorEx editor) { + myEditor = editor; + } + public boolean isRightMarginShown() { return myIsRightMarginShown != null ? myIsRightMarginShown.booleanValue() @@ -373,15 +374,19 @@ public class SettingsImpl implements EditorSettings { public void setWheelFontChangeEnabled(boolean val) { myIsWheelFontChangeEnabled = val ? Boolean.TRUE : Boolean.FALSE; } - - public boolean isMouseClickSelectionHonorsCamelWords() { - return myIsMouseClickSelectionHonorsCamelWords != null - ? myIsMouseClickSelectionHonorsCamelWords.booleanValue() - : EditorSettingsExternalizable.getInstance().isMouseClickSelectionHonorsCamelWords(); + + public boolean isMouseClickSelectionHonorsCamelWords(int clicksCount) { + if (myHonorCamelHumpsOnClicks != null && myHonorCamelHumpsOnClicks.containsKey(clicksCount)) { + return myHonorCamelHumpsOnClicks.get(clicksCount) > 0; + } + return EditorSettingsExternalizable.getInstance().isMouseClickSelectionHonorsCamelWords(clicksCount); } - public void setMouseClickSelectionHonorsCamelWords(boolean val) { - myIsMouseClickSelectionHonorsCamelWords = val ? Boolean.TRUE : Boolean.FALSE; + public void setMouseClickSelectionHonorsCamelWords(int clicksCount, boolean val) { + if (myHonorCamelHumpsOnClicks == null) { + myHonorCamelHumpsOnClicks = new TIntIntHashMap(); + } + myHonorCamelHumpsOnClicks.put(clicksCount, val ? 1 : 0); } public boolean isVariableInplaceRenameEnabled() { diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties index c390eb76a1b5..0e64315cb09d 100644 --- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties +++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties @@ -387,6 +387,7 @@ checkbox.enable.ctrl.mousewheel.changes.font.size=Change font size (Zoom) with C checkbox.enable.ctrl.mousewheel.changes.font.size.macos=Enable Command+MouseWheel changes font size checkbox.enable.drag.n.drop.functionality.in.editor=Enable Drag'n'Drop functionality in editor checkbox.honor.camelhumps.words.settings.on.double.click=Honor "CamelHumps" words settings when selecting on
double click +checkbox.honor.camelhumps.words.settings.on.triple.click=Honor "CamelHumps" words settings when selecting on
triple click group.smart.keys=Smart Keys checkbox.use.camelhumps.words=Use "CamelHumps" words checkbox.insert.pair.quote=Insert pair quote From a0f54e9a5be2b3b4c9827dd8dc950f413db403ae Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 19 Oct 2011 15:44:19 +0400 Subject: [PATCH 005/128] IDEA-75014 Drag and drop no longer works with UNC paths under Windows --- .../com/intellij/openapi/vfs/LocalFileSystemTest.java | 5 +++++ .../intellij/openapi/vfs/impl/local/LocalFileSystemBase.java | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/java/java-tests/testSrc/com/intellij/openapi/vfs/LocalFileSystemTest.java b/java/java-tests/testSrc/com/intellij/openapi/vfs/LocalFileSystemTest.java index cef6c65b073b..6e20027a413c 100644 --- a/java/java-tests/testSrc/com/intellij/openapi/vfs/LocalFileSystemTest.java +++ b/java/java-tests/testSrc/com/intellij/openapi/vfs/LocalFileSystemTest.java @@ -249,6 +249,11 @@ public class LocalFileSystemTest extends IdeaTestCase{ VirtualFile file = LocalFileSystem.getInstance().findFileByPath("wrong_path"); assertNull(file); + if (SystemInfo.isWindows) { + assertNotNull(LocalFileSystem.getInstance().findFileByPath("\\\\unit-133")); + assertNotNull(LocalFileSystem.getInstance().findFileByIoFile(new File("\\\\unit-133"))); + } + if (SystemInfo.isWindows && new File("c:").exists()) { VirtualFile root = LocalFileSystem.getInstance().findFileByPath("c:"); assertNotNull(root); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java index abce1463fbc5..52dcbf65e485 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java @@ -141,7 +141,9 @@ public abstract class LocalFileSystemBase extends LocalFileSystem { } public boolean exists(@NotNull final VirtualFile fileOrDirectory) { - if (StringUtil.isEmpty(fileOrDirectory.getPath())) return true; // fake top dir for Windows + String path = fileOrDirectory.getPath(); + if (fileOrDirectory.getParent() == null && path.startsWith("//")) return true; // Windows UNC root like //unit-333 + if (StringUtil.isEmpty(path)) return true; // fake top dir for Windows return convertToIOFile(fileOrDirectory).exists(); } From 51f41936423136d50846ae579c9e256e558eeee6 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 19 Oct 2011 13:47:21 +0200 Subject: [PATCH 006/128] fix stupid mistake --- ...CastConflictsWithInstanceofInspection.java | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CastConflictsWithInstanceofInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CastConflictsWithInstanceofInspection.java index b578163551a2..190b60d45a30 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CastConflictsWithInstanceofInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CastConflictsWithInstanceofInspection.java @@ -147,24 +147,15 @@ public class CastConflictsWithInstanceofInspection extends BaseInspection { protected final void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement element = descriptor.getPsiElement(); final PsiTypeElement castTypeElement; - final PsiTypeElement instanceofTypeElement; + final PsiReferenceExpression reference; if (element instanceof PsiTypeCastExpression) { final PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression)element; + castTypeElement = typeCastExpression.getCastType(); final PsiExpression operand = typeCastExpression.getOperand(); if (!(operand instanceof PsiReferenceExpression)) { return; } - castTypeElement = typeCastExpression.getCastType(); - if (castTypeElement == null) { - return; - } - final PsiInstanceOfExpression conflictingInstanceof = - InstanceOfUtils.getConflictingInstanceof(castTypeElement.getType(), (PsiReferenceExpression)operand, element); - instanceofTypeElement = conflictingInstanceof.getCheckType(); - if (instanceofTypeElement == null) { - return; - } - castTypeElement.replace(instanceofTypeElement); + reference = (PsiReferenceExpression)operand; } else if (element instanceof PsiMethodCallExpression) { final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)element; final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); @@ -183,15 +174,19 @@ public class CastConflictsWithInstanceofInspection extends BaseInspection { if (!(argument instanceof PsiReferenceExpression)) { return; } - final PsiInstanceOfExpression conflictingInstanceof = - InstanceOfUtils.getConflictingInstanceof(castTypeElement.getType(), (PsiReferenceExpression)argument, element); - instanceofTypeElement = conflictingInstanceof.getCheckType(); - if (instanceofTypeElement == null) { - return; - } + reference = (PsiReferenceExpression)argument; } else { return; } + if (castTypeElement == null) { + return; + } + final PsiInstanceOfExpression conflictingInstanceof = + InstanceOfUtils.getConflictingInstanceof(castTypeElement.getType(), reference, element); + final PsiTypeElement instanceofTypeElement = conflictingInstanceof.getCheckType(); + if (instanceofTypeElement == null) { + return; + } final PsiElement newElement = replace(castTypeElement, instanceofTypeElement); final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project); codeStyleManager.shortenClassReferences(newElement); From 61598ddebe289e9d05ec6806564d9090b31b6326 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Wed, 19 Oct 2011 16:11:08 +0400 Subject: [PATCH 007/128] EA-30400 - IOOBE: TextChangesStorage.substring --- .../openapi/editor/impl/CharArray.java | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java index 0db0eece3abb..9cf426dcdfc9 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java @@ -157,14 +157,21 @@ abstract class CharArray implements CharSequenceBackedByArray { myArray = null; myCount = chars.length(); myStringRef = null; - if (isSubSequence()) { - myDeferredChangesStorage = new TextChangesStorage(); - myStart = 0; - myEnd = -1; + myDeferredChangesLock.lock(); + try { + if (isSubSequence()) { + myDeferredChangesStorage = new TextChangesStorage(); + myStart = 0; + myEnd = -1; + } + else { + myDeferredChangesStorage.clear(); + } } - else { - myDeferredChangesStorage.clear(); + finally { + myDeferredChangesLock.unlock(); } + if (subj != null) { trimToSize(subj); } @@ -349,7 +356,13 @@ abstract class CharArray implements CharSequenceBackedByArray { if (myOriginalSequence != null) return myOriginalSequence.charAt(i); final char result; if (hasDeferredChanges()) { - result = myDeferredChangesStorage.charAt(myArray, i); + myDeferredChangesLock.lock(); + try { + result = myDeferredChangesStorage.charAt(myArray, i); + } + finally { + myDeferredChangesLock.unlock(); + } } else { result = myArray[i]; @@ -444,7 +457,13 @@ abstract class CharArray implements CharSequenceBackedByArray { if (start == end) return ""; final CharSequence result; if (myOriginalSequence == null) { - result = myDeferredChangesStorage.substring(myArray, start + myStart, end + myStart); + myDeferredChangesLock.lock(); + try { + result = myDeferredChangesStorage.substring(myArray, start + myStart, end + myStart); + } + finally { + myDeferredChangesLock.unlock(); + } } else { result = myOriginalSequence.subSequence(start, end); From de31fdc6d72bfdb265f5d7314956ff9e6552ba6f Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Wed, 19 Oct 2011 16:20:33 +0400 Subject: [PATCH 008/128] IDEA-75657 Duplicate line in console folding tooltip --- .../hint/EditorFragmentComponent.java | 25 +++++++++++++++++-- .../openapi/util/text/StringUtil.java | 10 ++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/codeInsight/hint/EditorFragmentComponent.java b/platform/platform-impl/src/com/intellij/codeInsight/hint/EditorFragmentComponent.java index d872e10b7228..bf92d9d976b0 100644 --- a/platform/platform-impl/src/com/intellij/codeInsight/hint/EditorFragmentComponent.java +++ b/platform/platform-impl/src/com/intellij/codeInsight/hint/EditorFragmentComponent.java @@ -25,6 +25,7 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.ex.FoldingModelEx; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.HintHint; import com.intellij.ui.LightweightHint; import com.intellij.ui.ScreenUtil; @@ -142,9 +143,29 @@ public class EditorFragmentComponent extends JPanel { boolean showFolding, boolean hideByAnyKey) { if (ApplicationManager.getApplication().isUnitTestMode()) return null; + Document document = editor.getDocument(); - int startLine = editor.offsetToLogicalPosition(range.getStartOffset()).line; - int endLine = Math.min(editor.offsetToLogicalPosition(range.getEndOffset()).line + 1, editor.getDocument().getLineCount() - 1); + int startOffset = range.getStartOffset(); + int startLine = document.getLineNumber(startOffset); + CharSequence text = document.getCharsSequence(); + // There is a possible case that we have a situation like below: + // line 1 + // line 2 + // line 3 + // We don't want to include 'line 2' to the target fragment then. + boolean incrementLine = false; + for (int offset = startOffset, max = Math.min(range.getEndOffset(), text.length()); offset < max; offset++) { + char c = text.charAt(offset); + incrementLine = StringUtil.isWhiteSpace(c); + if (!incrementLine || c == '\n') { + break; + } + } + if (incrementLine) { + startLine++; + } + + int endLine = Math.min(document.getLineNumber(range.getEndOffset()) + 1, document.getLineCount() - 1); //if (editor.logicalPositionToXY(new LogicalPosition(startLine, 0)).y >= editor.logicalPositionToXY(new LogicalPosition(endLine, 0)).y) return null; if (startLine >= endLine) return null; diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java index 8ee166838808..151f79addc5b 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -964,6 +964,16 @@ public class StringUtil { return s == null || s.trim().length() == 0; } + /** + * Allows to answer if given symbol is white space, tabulation or line feed. + * + * @param c symbol to check + * @return true if given symbol is white space, tabulation or line feed; false otherwise + */ + public static boolean isWhiteSpace(char c) { + return c == '\n' || c == '\t' || c == ' '; + } + @NotNull public static String getThrowableText(@NotNull Throwable aThrowable) { return ExceptionUtil.getThrowableText(aThrowable); From 7891da571c20d53f452db22b39a49906f7288d7d Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 19 Oct 2011 14:31:23 +0200 Subject: [PATCH 009/128] more tests for "Cast conflicts with 'instanceof'" quickfix --- .../replaceCastMethodInDeclaration.after.java | 7 +++++++ .../castConflicts/replaceCastMethodInDeclaration.java | 7 +++++++ .../bugs/castConflicts/replaceInstanceofMethod.after.java | 7 +++++++ .../bugs/castConflicts/replaceInstanceofMethod.java | 7 +++++++ .../fixes/bugs/CastConflictsWithInstanceofFixesTest.java | 8 ++++++++ 5 files changed, 36 insertions(+) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceCastMethodInDeclaration.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceCastMethodInDeclaration.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceInstanceofMethod.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceInstanceofMethod.java diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceCastMethodInDeclaration.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceCastMethodInDeclaration.after.java new file mode 100644 index 000000000000..d92f2357b257 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceCastMethodInDeclaration.after.java @@ -0,0 +1,7 @@ +public class Test { + void foo(Object o) { + if (o instanceof String) { + Integer i = String.class.cast(o); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceCastMethodInDeclaration.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceCastMethodInDeclaration.java new file mode 100644 index 000000000000..497e3135a74a --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceCastMethodInDeclaration.java @@ -0,0 +1,7 @@ +public class Test { + void foo(Object o) { + if (o instanceof String) { + Integer i = Integer.class.cast(o); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceInstanceofMethod.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceInstanceofMethod.after.java new file mode 100644 index 000000000000..581c312ab11e --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceInstanceofMethod.after.java @@ -0,0 +1,7 @@ +public class Test { + void foo(Object o) { + if (o instanceof Integer) { + Integer i = Integer.class.cast(o); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceInstanceofMethod.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceInstanceofMethod.java new file mode 100644 index 000000000000..54ad84c6e00f --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/bugs/castConflicts/replaceInstanceofMethod.java @@ -0,0 +1,7 @@ +public class Test { + void foo(Object o) { + if (o instanceof String) { + Integer i = Integer.class.cast(o); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/bugs/CastConflictsWithInstanceofFixesTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/bugs/CastConflictsWithInstanceofFixesTest.java index 17d6b2cff66a..9689129dbdea 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/bugs/CastConflictsWithInstanceofFixesTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/bugs/CastConflictsWithInstanceofFixesTest.java @@ -37,6 +37,14 @@ public class CastConflictsWithInstanceofFixesTest extends IGQuickFixesTestCase { doTest("replaceInstanceOf", "Replace 'String' with 'Integer' in instanceof"); } + public void testReplaceCastMethodInDeclaration() { + doTest("replaceCastMethodInDeclaration", "Replace 'Integer' with 'String' in cast"); + } + + public void testReplaceInstanceofMethod() { + doTest("replaceInstanceofMethod", "Replace 'String' with 'Integer' in instanceof"); + } + @Override protected String getRelativePath() { return "bugs/castConflicts"; From 29097396edd0bfee5deb363e9c6e9f412737388a Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 19 Oct 2011 15:58:14 +0400 Subject: [PATCH 010/128] detect facet only in suitable modules --- .../detection/impl/FrameworkDetectionContextImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionContextImpl.java b/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionContextImpl.java index da3ace0cc82b..3ebd09857481 100644 --- a/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionContextImpl.java +++ b/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionContextImpl.java @@ -22,6 +22,7 @@ import com.intellij.facet.impl.DefaultFacetsProvider; import com.intellij.framework.detection.DetectedFrameworkDescription; import com.intellij.framework.detection.FacetBasedFrameworkDetector; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ui.configuration.FacetsProvider; @@ -61,7 +62,7 @@ public class FrameworkDetectionContextImpl extends FrameworkDetectionContextBase final FacetsProvider provider = DefaultFacetsProvider.INSTANCE; for (Module module : filesByModule.keySet()) { final Collection facets = provider.getFacetsByType(module, facetType.getId()); - if (facetType.isOnlyOneFacetAllowed() && !facets.isEmpty()) { + if (!facetType.isSuitableModuleType(ModuleType.get(module)) || facetType.isOnlyOneFacetAllowed() && !facets.isEmpty()) { continue; } List existentConfigurations = new ArrayList(); From 751cc5aff92564588966c83c6dbe807ba86e1b48 Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 19 Oct 2011 17:00:05 +0400 Subject: [PATCH 011/128] xdebugger: fixed doubling watches node after editing --- .../com/intellij/xdebugger/impl/frame/WatchInplaceEditor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/WatchInplaceEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/WatchInplaceEditor.java index 235c689c4310..543b57423b50 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/WatchInplaceEditor.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/WatchInplaceEditor.java @@ -54,6 +54,7 @@ public class WatchInplaceEditor extends XDebuggerTreeInplaceEditor { } public void cancelEditing() { + if (!isShown()) return; super.cancelEditing(); int index = myRootNode.removeChildNode(getNode()); if (myOldNode != null) { From ad2301818c7c5613f38e883acca8078e44f524f7 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 19 Oct 2011 12:44:39 +0200 Subject: [PATCH 012/128] suggest inheritor members on second completion only, prefer the default collection getters to them --- .../CollectionsUtilityMethodsProvider.java | 4 +++ .../completion/JavaCompletionData.java | 2 +- .../JavaSmartCompletionContributor.java | 5 ++-- ...ariablesLiteralsAndAnnoMethodsWeigher.java | 5 ++++ .../InheritorEnumMembers-out.java | 0 .../{ => second}/InheritorEnumMembers.java | 0 .../{ => second}/InheritorMembers-out.java | 0 .../{ => second}/InheritorMembers.java | 0 .../PreferCollectionsEmptyList.java | 8 ++++++ .../SecondSmartTypeCompletionTest.java | 28 +++++++++++++++---- .../SmartTypeCompletionOrderingTest.groovy | 9 +++++- .../completion/SmartTypeCompletionTest.java | 2 -- .../codeInsight/lookup/LookupItem.java | 4 +-- .../GroovySmartCompletionContributor.java | 2 +- 14 files changed, 54 insertions(+), 15 deletions(-) rename java/java-tests/testData/codeInsight/completion/smartType/{ => second}/InheritorEnumMembers-out.java (100%) rename java/java-tests/testData/codeInsight/completion/smartType/{ => second}/InheritorEnumMembers.java (100%) rename java/java-tests/testData/codeInsight/completion/smartType/{ => second}/InheritorMembers-out.java (100%) rename java/java-tests/testData/codeInsight/completion/smartType/{ => second}/InheritorMembers.java (100%) create mode 100644 java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferCollectionsEmptyList.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/CollectionsUtilityMethodsProvider.java b/java/java-impl/src/com/intellij/codeInsight/completion/CollectionsUtilityMethodsProvider.java index a18458d5d690..edf3a01d342d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/CollectionsUtilityMethodsProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/CollectionsUtilityMethodsProvider.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.lookup.AutoCompletionPolicy; import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.openapi.util.Key; import com.intellij.psi.*; import com.intellij.util.Consumer; import org.jetbrains.annotations.NonNls; @@ -28,6 +29,8 @@ import static com.intellij.psi.CommonClassNames.*; * @author peter */ class CollectionsUtilityMethodsProvider { + public static final Key COLLECTION_FACTORY = Key.create("CollectionFactory"); + public static void addCompletions(@NotNull final JavaSmartCompletionParameters parameters, @NotNull final Consumer result) { final PsiElement element = parameters.getPosition(); @@ -85,6 +88,7 @@ class CollectionsUtilityMethodsProvider { final JavaMethodCallElement item = new JavaMethodCallElement(method, false, false); item.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE); item.setInferenceSubstitutor(SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, expectedType)); + item.putUserData(COLLECTION_FACTORY, true); result.consume(item); } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java index d9b26734fb77..600412bbe329 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java @@ -542,7 +542,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{ !(position.getParent() instanceof PsiLiteralExpression) && !(position.getParent().getParent() instanceof PsiSwitchLabelStatement)) { for (final ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) { - new JavaMembersGetter(info.getDefaultType()).addMembers(position, parameters.getInvocationCount() > 0, new Consumer() { + new JavaMembersGetter(info.getDefaultType()).addMembers(position, parameters.getInvocationCount() > 1, new Consumer() { @Override public void consume(LookupElement element) { result.addElement(element); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java index 32cb6da742ad..6dea9b5e0136 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java @@ -223,9 +223,10 @@ public class JavaSmartCompletionContributor extends CompletionContributor { parent != null && !(parent.getParent() instanceof PsiSwitchLabelStatement)) { for (ExpectedTypeInfo info : mergedInfos) { - new JavaMembersGetter(info.getType()).addMembers(position, true, noTypeCheck); + final boolean searchInheritors = params.getInvocationCount() > 1; + new JavaMembersGetter(info.getType()).addMembers(position, searchInheritors, noTypeCheck); if (!info.getDefaultType().equals(info.getType())) { - new JavaMembersGetter(info.getDefaultType()).addMembers(position, true, noTypeCheck); + new JavaMembersGetter(info.getDefaultType()).addMembers(position, searchInheritors, noTypeCheck); } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java index 86a2271a181a..5159fb5430db 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java @@ -44,6 +44,7 @@ public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends LookupEle qualifiedWithField, qualifiedWithGetter, superMethodParameters, + collectionFactory, normal, nonInitialized, classLiteral, @@ -70,6 +71,10 @@ public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends LookupEle if (object instanceof String && item.getUserData(JavaCompletionUtil.SUPER_METHOD_PARAMETERS) == Boolean.TRUE) { return MyResult.superMethodParameters; } + + if (item.getUserData(CollectionsUtilityMethodsProvider.COLLECTION_FACTORY) != null) { + return MyResult.collectionFactory; + } final JavaChainLookupElement chain = item.as(JavaChainLookupElement.CLASS_CONDITION_KEY); if (chain != null) { diff --git a/java/java-tests/testData/codeInsight/completion/smartType/InheritorEnumMembers-out.java b/java/java-tests/testData/codeInsight/completion/smartType/second/InheritorEnumMembers-out.java similarity index 100% rename from java/java-tests/testData/codeInsight/completion/smartType/InheritorEnumMembers-out.java rename to java/java-tests/testData/codeInsight/completion/smartType/second/InheritorEnumMembers-out.java diff --git a/java/java-tests/testData/codeInsight/completion/smartType/InheritorEnumMembers.java b/java/java-tests/testData/codeInsight/completion/smartType/second/InheritorEnumMembers.java similarity index 100% rename from java/java-tests/testData/codeInsight/completion/smartType/InheritorEnumMembers.java rename to java/java-tests/testData/codeInsight/completion/smartType/second/InheritorEnumMembers.java diff --git a/java/java-tests/testData/codeInsight/completion/smartType/InheritorMembers-out.java b/java/java-tests/testData/codeInsight/completion/smartType/second/InheritorMembers-out.java similarity index 100% rename from java/java-tests/testData/codeInsight/completion/smartType/InheritorMembers-out.java rename to java/java-tests/testData/codeInsight/completion/smartType/second/InheritorMembers-out.java diff --git a/java/java-tests/testData/codeInsight/completion/smartType/InheritorMembers.java b/java/java-tests/testData/codeInsight/completion/smartType/second/InheritorMembers.java similarity index 100% rename from java/java-tests/testData/codeInsight/completion/smartType/InheritorMembers.java rename to java/java-tests/testData/codeInsight/completion/smartType/second/InheritorMembers.java diff --git a/java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferCollectionsEmptyList.java b/java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferCollectionsEmptyList.java new file mode 100644 index 000000000000..2770782a68bc --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferCollectionsEmptyList.java @@ -0,0 +1,8 @@ +public class Aaaaaaa { + + { + java.util.List local = null; + java.util.List l = + } + +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SecondSmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SecondSmartTypeCompletionTest.java index 988d5f2ae0a2..f70d1d83fb47 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SecondSmartTypeCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SecondSmartTypeCompletionTest.java @@ -48,7 +48,7 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase { configure(); assertStringItems("foos().toArray(EMPTY_ARRAY)", "foos().toArray(EMPTY_ARRAY2)"); selectItem(myItems[0]); - checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java"); + checkResult(); } public void testToArrayGenericArrayCreation() throws Throwable { doTest(); } @@ -62,7 +62,7 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase { configure(); assertStringItems("foos().toArray(Bar.EMPTY_ARRAY)", "foos().toArray(Bar.EMPTY_ARRAY2)"); selectItem(myItems[0]); - checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java"); + checkResult(); } public void testNonInitializedField() throws Throwable { doTest(); } @@ -104,14 +104,14 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase { assertEquals("Arrays.asList(f.bar())", ((LookupItem)((LookupElementDecorator)myItems[0]).getDelegate()).getPresentableText()); assertEquals("Arrays.asList(f.foo())", ((LookupItem)((LookupElementDecorator)myItems[1]).getDelegate()).getPresentableText()); selectItem(myItems[1]); - checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java"); + checkResult(); } public void testRestoreInitialPrefix() throws Throwable { configureByFileNoComplete(BASE_PATH + "/" + getTestName(false) + ".java"); complete(1); assertStringItems("MyEnum.Bar", "MyEnum.Foo"); - checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java"); + checkResult(); complete(1); assertStringItems("my.getEnum", "MyEnum.Bar", "MyEnum.Foo"); } @@ -155,13 +155,17 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase { public void testEmptyListInMethodCall() throws Throwable { configure(); selectItem(myItems[0]); + checkResult(); + } + + private void checkResult() { checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java"); } public void testSingletonMap() throws Throwable { configure(); selectItem(myItems[0]); - checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java"); + checkResult(); } protected void checkResultByFile(@NonNls final String filePath) { @@ -174,7 +178,19 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase { private void doTest() throws Exception { configure(); - checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java"); + checkResult(); + } + + public void testInheritorMembers() throws Throwable { + configure(); + selectItem(myItems[0]); + checkResult(); + } + + public void testInheritorEnumMembers() throws Throwable { + configure(); + selectItem(myItems[0]); + checkResult(); } @Override diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy index a86eb2b43a57..dcb13ac55001 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy @@ -287,7 +287,14 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase { checkPreferredItems(0, "boo", "bar") } - + public void testPreferCollectionsEmptyList() throws Throwable { + myFixture.addClass("package foo; public class FList implements java.util.List { public static FList emptyList() {} }"); + configureNoCompletion(getTestName(false) + ".java"); + myFixture.complete(CompletionType.SMART, 2); + assertPreferredItems(0, "local", "local.subList", "emptyList", "singletonList", "unmodifiableList"); + assert 'Collections.emptyList' in lookup.items[2].allLookupStrings + assert 'FList.emptyList' in lookup.items[5].allLookupStrings + } @Override protected String getBasePath() { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java index 104712b8d2a4..70e030234c3e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java @@ -1026,8 +1026,6 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase { } public void testArrayInitializerBeforeVarargs() throws Throwable { doTest(); } - public void testInheritorMembers() throws Throwable { doTest(); } - public void testInheritorEnumMembers() throws Throwable { doTest(); } public void testDuplicateMembersFromSuperClass() throws Throwable { doTest(); } public void testMemberImportStatically() { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java index fa3c983a401a..076428bd32a8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java @@ -29,12 +29,12 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; -import gnu.trove.THashSet; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -67,7 +67,7 @@ public class LookupItem extends MutableLookupElement implements Comparable private double myPriority; private Map myAttributes = null; public static final LookupItem[] EMPTY_ARRAY = new LookupItem[0]; - private final Set myAllLookupStrings = new THashSet(); + private final Set myAllLookupStrings = new HashSet(); private String myPresentable; private AutoCompletionPolicy myAutoCompletionPolicy = AutoCompletionPolicy.SETTINGS_DEPENDENT; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java index fb7621625435..48ccf2fbdf4a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java @@ -218,7 +218,7 @@ public class GroovySmartCompletionContributor extends CompletionContributor { }; PsiType type = info.getType(); PsiType defType = info.getDefaultType(); - boolean searchInheritors = params.getInvocationCount() > 0; + boolean searchInheritors = params.getInvocationCount() > 1; if (type instanceof PsiClassType) { new GroovyMembersGetter((PsiClassType)type, reference).processMembers(searchInheritors, consumer); } From e142fd0ff48ccb68f424c66ed6d809f002717b01 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 19 Oct 2011 13:02:46 +0200 Subject: [PATCH 013/128] don't lift prefix items during smart completion (IDEA-75606) --- .../completion/SmartTypeCompletionOrderingTest.groovy | 2 +- .../codeInsight/completion/impl/CompletionServiceImpl.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy index dcb13ac55001..348ceb177809 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy @@ -21,7 +21,7 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase { } public void testJComponentAdd() throws Throwable { - checkPreferredItems(0, "name", "b", "foo", "fooBean239", "this"); + checkPreferredItems(0, "name", "b", "fooBean239", "this", "getName"); } public void testJComponentAddNew() throws Throwable { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java index e138d9922eef..337a2d3cfef4 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java @@ -279,6 +279,10 @@ public class CompletionServiceImpl extends CompletionService{ } + if (parameters.getCompletionType() == CompletionType.SMART) { + return sorter; + } + return sorter.withClassifier("priority", true, new ClassifierFactory("liftShorter") { @Override public Classifier createClassifier(final Classifier next) { From eb47e1d1115a38ef270395e5444dc1c1b15f7196 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 19 Oct 2011 15:22:09 +0200 Subject: [PATCH 014/128] smart enter to always insert a new line after the current, not before (IDEA-75554) --- .../codeInsight/completeStatement/AtBlockEnd_after.java | 2 +- .../codeInsight/completeStatement/BeforeFor_after.java | 2 +- .../completeStatement/BeforeStatement_after.java | 2 +- .../completeStatement/InPreceedingBlanks_after.java | 2 +- .../editorActions/smartEnter/SmartEnterAction.java | 6 +----- 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/java/java-tests/testData/codeInsight/completeStatement/AtBlockEnd_after.java b/java/java-tests/testData/codeInsight/completeStatement/AtBlockEnd_after.java index f83fa8a5d5f8..d7ff4d0a6173 100644 --- a/java/java-tests/testData/codeInsight/completeStatement/AtBlockEnd_after.java +++ b/java/java-tests/testData/codeInsight/completeStatement/AtBlockEnd_after.java @@ -2,7 +2,7 @@ public class Foo { { for(int i = 0; i < 100; i++) { x = 3; - } + } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completeStatement/BeforeFor_after.java b/java/java-tests/testData/codeInsight/completeStatement/BeforeFor_after.java index dc6562b13392..c1accd72e17e 100644 --- a/java/java-tests/testData/codeInsight/completeStatement/BeforeFor_after.java +++ b/java/java-tests/testData/codeInsight/completeStatement/BeforeFor_after.java @@ -1,7 +1,7 @@ public class Foo { { - for (int i = 0; i < 100; i++) { + } } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completeStatement/BeforeStatement_after.java b/java/java-tests/testData/codeInsight/completeStatement/BeforeStatement_after.java index bcee224f3e4f..86c825b75996 100644 --- a/java/java-tests/testData/codeInsight/completeStatement/BeforeStatement_after.java +++ b/java/java-tests/testData/codeInsight/completeStatement/BeforeStatement_after.java @@ -1,6 +1,6 @@ public class Foo { { - x = 3; + } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completeStatement/InPreceedingBlanks_after.java b/java/java-tests/testData/codeInsight/completeStatement/InPreceedingBlanks_after.java index fde9a343136d..3e4c55313dc0 100644 --- a/java/java-tests/testData/codeInsight/completeStatement/InPreceedingBlanks_after.java +++ b/java/java-tests/testData/codeInsight/completeStatement/InPreceedingBlanks_after.java @@ -1,7 +1,7 @@ public class Test { { x = 2; - foo(); + } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SmartEnterAction.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SmartEnterAction.java index aee148ec2336..fbfd303f766d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SmartEnterAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SmartEnterAction.java @@ -69,11 +69,7 @@ public class SmartEnterAction extends EditorAction { final int caretOffset = editor.getCaretModel().getOffset(); if (isInPreceedingBlanks(editor)) { - final int caretLine = doc.getLineNumber(caretOffset); - if (caretLine > 0) { - int prevLineEnd = doc.getLineEndOffset(caretLine - 1); - editor.getCaretModel().moveToOffset(prevLineEnd); - } + editor.getCaretModel().moveToOffset(doc.getLineEndOffset(doc.getLineNumber(caretOffset))); EditorActionHandler enterHandler = EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_ENTER); enterHandler.execute(editor, dataContext); return; From 2d187bdda9dc7c96cf6282c943c33a9020bb8a7d Mon Sep 17 00:00:00 2001 From: Evgeny Zakrevsky Date: Wed, 19 Oct 2011 17:38:28 +0400 Subject: [PATCH 015/128] debug logging removed --- platform/platform-impl/src/com/intellij/ui/EditorTextField.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/EditorTextField.java b/platform/platform-impl/src/com/intellij/ui/EditorTextField.java index cda8d45e898b..685c3402606b 100644 --- a/platform/platform-impl/src/com/intellij/ui/EditorTextField.java +++ b/platform/platform-impl/src/com/intellij/ui/EditorTextField.java @@ -650,8 +650,6 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, size = UIUtil.addInsets(size, myEditor.getInsets()); } - System.out.println(size); - return size; } From 90dc58a648d4f9f4eab0839b786c128112475c9c Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Wed, 19 Oct 2011 17:44:20 +0400 Subject: [PATCH 016/128] Cosmetics. --- .../ether/dependencyView/Mappings.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/jps/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/src/org/jetbrains/ether/dependencyView/Mappings.java index 18fd8108f6d5..d670c464ce23 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -369,7 +369,7 @@ public class Mappings { } } - private Set cache (final Collection x) { + private Set cache(final Collection x) { final Set y = new HashSet(); for (String s : x) { @@ -380,14 +380,15 @@ public class Mappings { } public boolean differentiate(final Mappings delta, - final Collection removed, - final Collection filesToCompile, - final Collection compiledFiles, - final Collection affectedFiles, - final Collection safeFiles) { + final Collection removed, + final Collection filesToCompile, + final Collection compiledFiles, + final Collection affectedFiles, + final Collection safeFiles) { final Set affectedCache = cache(affectedFiles); - final boolean result = differentiate(delta, cache(removed), cache(filesToCompile), cache(compiledFiles), affectedCache, cache(safeFiles)); + final boolean result = + differentiate(delta, cache(removed), cache(filesToCompile), cache(compiledFiles), affectedCache, cache(safeFiles)); for (StringCache.S a : affectedCache) { affectedFiles.add(a.value); @@ -808,7 +809,7 @@ public class Mappings { return true; } - public void integrate (final Mappings delta, final Collection removed) { + public void integrate(final Mappings delta, final Collection removed) { integrate(delta, cache(removed)); } From e3c5049e76e608a990ec4439eac7e3b9d8ecdb88 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 19 Oct 2011 15:59:03 +0200 Subject: [PATCH 017/128] Add option to only report if getter/setter is private to "Call to simple getter/setter from within class" inspections (IDEA-75505) --- .../siyeh/InspectionGadgetsBundle.properties | 6 +- .../CallToSimpleGetterInClassInspection.java | 75 ++++++++--------- .../CallToSimpleSetterInClassInspection.java | 81 ++++++++----------- .../CallToSimpleGetterInClass.html | 3 + .../CallToSimpleSetterInClass.html | 5 +- 5 files changed, 77 insertions(+), 93 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties index 02915a529fc5..23d05c2f8ed1 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties @@ -1282,9 +1282,11 @@ three.negations.per.method.ignore.option=Ignore negations in equals() methods three.negations.per.method.problem.descriptor=#ref contains {0} negations #loc thrown.exceptions.per.method.problem.descriptor=#ref has too many exceptions declared (num exceptions = {0}) #loc thrown.exceptions.per.method.limit.option=Exceptions thrown limit: -call.to.simple.getter.in.class.display.name.ignore.option=Ignore getter calls on other objects +call.to.simple.getter.in.class.ignore.option=Ignore getter calls on other objects +call.to.private.simple.getter.in.class.option=Only report getter is private call.to.simple.getter.in.class.inline.quickfix=Inline call to getter -call.to.simple.setter.in.class.display.name.ignore.option=Ignore setter calls on other objects +call.to.simple.setter.in.class.ignore.option=Ignore setter calls on other objects +call.to.private.setter.in.class.option=Only report when setter is private call.to.simple.setter.in.class.inline.quickfix=Inline call to setter make.static.quickfix=Make static length.one.strings.in.concatenation.replace.quickfix=Replace with character diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/CallToSimpleGetterInClassInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/CallToSimpleGetterInClassInspection.java index cf5e0ef11d53..2dcf9ad4782f 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/CallToSimpleGetterInClassInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/CallToSimpleGetterInClassInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ package com.siyeh.ig.performance; import com.intellij.codeInspection.ProblemDescriptor; -import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; +import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.search.searches.OverridingMethodsSearch; @@ -35,11 +35,12 @@ import javax.swing.*; public class CallToSimpleGetterInClassInspection extends BaseInspection { - /** - * @noinspection PublicField - */ + @SuppressWarnings("UnusedDeclaration") public boolean ignoreGetterCallsOnOtherObjects = false; + @SuppressWarnings("UnusedDeclaration") + public boolean onlyReportPrivateGetter = false; + @Override @NotNull public String getID() { @@ -49,23 +50,24 @@ public class CallToSimpleGetterInClassInspection extends BaseInspection { @Override @NotNull public String getDisplayName() { - return InspectionGadgetsBundle.message( - "call.to.simple.getter.in.class.display.name"); + return InspectionGadgetsBundle.message("call.to.simple.getter.in.class.display.name"); } @Override @NotNull public String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "call.to.simple.getter.in.class.problem.descriptor"); + return InspectionGadgetsBundle.message("call.to.simple.getter.in.class.problem.descriptor"); } @Override @Nullable public JComponent createOptionsPanel() { - return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message( - "call.to.simple.getter.in.class.display.name.ignore.option"), - this, "ignoreGetterCallsOnOtherObjects"); + final MultipleCheckboxOptionsPanel optionsPanel = new MultipleCheckboxOptionsPanel(this); + optionsPanel.addCheckbox(InspectionGadgetsBundle.message("call.to.simple.getter.in.class.ignore.option"), + "ignoreGetterCallsOnOtherObjects"); + optionsPanel.addCheckbox(InspectionGadgetsBundle.message("call.to.private.simple.getter.in.class.option"), + "onlyReportPrivateGetter"); + return optionsPanel; } @Override @@ -77,21 +79,17 @@ public class CallToSimpleGetterInClassInspection extends BaseInspection { @NotNull public String getName() { - return InspectionGadgetsBundle.message( - "call.to.simple.getter.in.class.inline.quickfix"); + return InspectionGadgetsBundle.message("call.to.simple.getter.in.class.inline.quickfix"); } @Override - public void doFix(Project project, ProblemDescriptor descriptor) - throws IncorrectOperationException { + public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement methodIdentifier = descriptor.getPsiElement(); - final PsiReferenceExpression methodExpression = - (PsiReferenceExpression)methodIdentifier.getParent(); + final PsiReferenceExpression methodExpression = (PsiReferenceExpression)methodIdentifier.getParent(); if (methodExpression == null) { return; } - final PsiMethodCallExpression call = - (PsiMethodCallExpression)methodExpression.getParent(); + final PsiMethodCallExpression call = (PsiMethodCallExpression)methodExpression.getParent(); if (call == null) { return; } @@ -104,15 +102,12 @@ public class CallToSimpleGetterInClassInspection extends BaseInspection { return; } final PsiStatement[] statements = body.getStatements(); - final PsiReturnStatement returnStatement = - (PsiReturnStatement)statements[0]; - final PsiExpression returnValue = - returnStatement.getReturnValue(); + final PsiReturnStatement returnStatement = (PsiReturnStatement)statements[0]; + final PsiExpression returnValue = returnStatement.getReturnValue(); if (!(returnValue instanceof PsiReferenceExpression)) { return; } - final PsiReferenceExpression referenceExpression = - (PsiReferenceExpression)returnValue; + final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)returnValue; final PsiField field = (PsiField)referenceExpression.resolve(); if (field == null) { return; @@ -121,14 +116,11 @@ public class CallToSimpleGetterInClassInspection extends BaseInspection { if (fieldName == null) { return; } - final PsiExpression qualifier = - methodExpression.getQualifierExpression(); + final PsiExpression qualifier = methodExpression.getQualifierExpression(); if (qualifier == null) { final JavaPsiFacade facade = JavaPsiFacade.getInstance(call.getProject()); final PsiResolveHelper resolveHelper = facade.getResolveHelper(); - final PsiVariable variable = - resolveHelper.resolveReferencedVariable(fieldName, - call); + final PsiVariable variable = resolveHelper.resolveReferencedVariable(fieldName, call); if (variable == null) { return; } @@ -150,15 +142,12 @@ public class CallToSimpleGetterInClassInspection extends BaseInspection { return new CallToSimpleGetterInClassVisitor(); } - private class CallToSimpleGetterInClassVisitor - extends BaseInspectionVisitor { + private class CallToSimpleGetterInClassVisitor extends BaseInspectionVisitor { @Override - public void visitMethodCallExpression( - @NotNull PsiMethodCallExpression call) { + public void visitMethodCallExpression(@NotNull PsiMethodCallExpression call) { super.visitMethodCallExpression(call); - final PsiClass containingClass = - ClassUtils.getContainingClass(call); + final PsiClass containingClass = ClassUtils.getContainingClass(call); if (containingClass == null) { return; } @@ -169,12 +158,9 @@ public class CallToSimpleGetterInClassInspection extends BaseInspection { if (!containingClass.equals(method.getContainingClass())) { return; } - final PsiReferenceExpression methodExpression = - call.getMethodExpression(); - final PsiExpression qualifier = - methodExpression.getQualifierExpression(); - if (qualifier != null && - !(qualifier instanceof PsiThisExpression)) { + final PsiReferenceExpression methodExpression = call.getMethodExpression(); + final PsiExpression qualifier = methodExpression.getQualifierExpression(); + if (qualifier != null && !(qualifier instanceof PsiThisExpression)) { if (ignoreGetterCallsOnOtherObjects) { return; } @@ -191,6 +177,9 @@ public class CallToSimpleGetterInClassInspection extends BaseInspection { if (!PropertyUtils.isSimpleGetter(method)) { return; } + if (onlyReportPrivateGetter && !method.hasModifierProperty(PsiModifier.PRIVATE)) { + return; + } final Query query = OverridingMethodsSearch.search(method, true); final PsiMethod overridingMethod = query.findFirst(); if (overridingMethod != null) { diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/CallToSimpleSetterInClassInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/CallToSimpleSetterInClassInspection.java index 4d96d312acbf..bc19d0073f16 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/CallToSimpleSetterInClassInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/CallToSimpleSetterInClassInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ package com.siyeh.ig.performance; import com.intellij.codeInspection.ProblemDescriptor; -import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; +import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.search.searches.OverridingMethodsSearch; @@ -36,11 +36,12 @@ import javax.swing.*; public class CallToSimpleSetterInClassInspection extends BaseInspection { - /** - * @noinspection PublicField - */ + @SuppressWarnings("UnusedDeclaration") public boolean ignoreSetterCallsOnOtherObjects = false; + @SuppressWarnings("UnusedDeclaration") + public boolean onlyReportPrivateSetter = false; + @NotNull public String getID() { return "CallToSimpleSetterFromWithinClass"; @@ -48,21 +49,22 @@ public class CallToSimpleSetterInClassInspection extends BaseInspection { @NotNull public String getDisplayName() { - return InspectionGadgetsBundle.message( - "call.to.simple.setter.in.class.display.name"); + return InspectionGadgetsBundle.message("call.to.simple.setter.in.class.display.name"); } @NotNull public String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "call.to.simple.setter.in.class.problem.descriptor"); + return InspectionGadgetsBundle.message("call.to.simple.setter.in.class.problem.descriptor"); } @Nullable public JComponent createOptionsPanel() { - return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message( - "call.to.simple.setter.in.class.display.name.ignore.option"), - this, "ignoreSetterCallsOnOtherObjects"); + final MultipleCheckboxOptionsPanel optionsPanel = new MultipleCheckboxOptionsPanel(this); + optionsPanel.addCheckbox(InspectionGadgetsBundle.message("call.to.simple.setter.in.class.ignore.option"), + "ignoreSetterCallsOnOtherObjects"); + optionsPanel.addCheckbox(InspectionGadgetsBundle.message("call.to.private.setter.in.class.option"), + "onlyReportPrivateSetter"); + return optionsPanel; } public InspectionGadgetsFix buildFix(Object... infos) { @@ -73,20 +75,17 @@ public class CallToSimpleSetterInClassInspection extends BaseInspection { @NotNull public String getName() { - return InspectionGadgetsBundle.message( - "call.to.simple.setter.in.class.inline.quickfix"); + return InspectionGadgetsBundle.message("call.to.simple.setter.in.class.inline.quickfix"); } public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement methodIdentifier = descriptor.getPsiElement(); - final PsiReferenceExpression methodExpression = - (PsiReferenceExpression)methodIdentifier.getParent(); + final PsiReferenceExpression methodExpression = (PsiReferenceExpression)methodIdentifier.getParent(); if (methodExpression == null) { return; } - final PsiMethodCallExpression call = - (PsiMethodCallExpression)methodExpression.getParent(); + final PsiMethodCallExpression call = (PsiMethodCallExpression)methodExpression.getParent(); if (call == null) { return; } @@ -102,14 +101,10 @@ public class CallToSimpleSetterInClassInspection extends BaseInspection { return; } final PsiStatement[] statements = body.getStatements(); - final PsiExpressionStatement assignmentStatement = - (PsiExpressionStatement)statements[0]; - final PsiAssignmentExpression assignment = (PsiAssignmentExpression) - assignmentStatement.getExpression(); - final PsiExpression qualifier = - methodExpression.getQualifierExpression(); - final PsiReferenceExpression lhs = (PsiReferenceExpression) - assignment.getLExpression(); + final PsiExpressionStatement assignmentStatement = (PsiExpressionStatement)statements[0]; + final PsiAssignmentExpression assignment = (PsiAssignmentExpression)assignmentStatement.getExpression(); + final PsiExpression qualifier = methodExpression.getQualifierExpression(); + final PsiReferenceExpression lhs = (PsiReferenceExpression)assignment.getLExpression(); final PsiField field = (PsiField)lhs.resolve(); if (field == null) { return; @@ -117,11 +112,8 @@ public class CallToSimpleSetterInClassInspection extends BaseInspection { final String fieldName = field.getName(); if (qualifier == null) { final JavaPsiFacade manager = JavaPsiFacade.getInstance(call.getProject()); - final PsiResolveHelper resolveHelper = - manager.getResolveHelper(); - final PsiVariable variable = - resolveHelper.resolveReferencedVariable(fieldName, - call); + final PsiResolveHelper resolveHelper = manager.getResolveHelper(); + final PsiVariable variable = resolveHelper.resolveReferencedVariable(fieldName, call); if (variable == null) { return; } @@ -130,14 +122,12 @@ public class CallToSimpleSetterInClassInspection extends BaseInspection { newExpression = fieldName + " = " + argument.getText(); } else { - newExpression = "this." + fieldName + " = " + - argument.getText(); + newExpression = "this." + fieldName + " = " + argument.getText(); } replaceExpression(call, newExpression); } else { - final String newExpression = qualifier.getText() + '.' + - fieldName + " = " + argument.getText(); + final String newExpression = qualifier.getText() + '.' + fieldName + " = " + argument.getText(); replaceExpression(call, newExpression); } } @@ -147,15 +137,12 @@ public class CallToSimpleSetterInClassInspection extends BaseInspection { return new CallToSimpleSetterInClassVisitor(); } - private class CallToSimpleSetterInClassVisitor - extends BaseInspectionVisitor { + private class CallToSimpleSetterInClassVisitor extends BaseInspectionVisitor { @Override - public void visitMethodCallExpression( - @NotNull PsiMethodCallExpression call) { + public void visitMethodCallExpression(@NotNull PsiMethodCallExpression call) { super.visitMethodCallExpression(call); - final PsiClass containingClass = - ClassUtils.getContainingClass(call); + final PsiClass containingClass = ClassUtils.getContainingClass(call); if (containingClass == null) { return; } @@ -166,12 +153,9 @@ public class CallToSimpleSetterInClassInspection extends BaseInspection { if (!containingClass.equals(method.getContainingClass())) { return; } - final PsiReferenceExpression methodExpression = - call.getMethodExpression(); - final PsiExpression qualifier = - methodExpression.getQualifierExpression(); - if (qualifier != null && - !(qualifier instanceof PsiThisExpression)) { + final PsiReferenceExpression methodExpression = call.getMethodExpression(); + final PsiExpression qualifier = methodExpression.getQualifierExpression(); + if (qualifier != null && !(qualifier instanceof PsiThisExpression)) { if (ignoreSetterCallsOnOtherObjects) { return; } @@ -188,6 +172,9 @@ public class CallToSimpleSetterInClassInspection extends BaseInspection { if (!PropertyUtils.isSimpleSetter(method)) { return; } + if (onlyReportPrivateSetter && !method.hasModifierProperty(PsiModifier.PRIVATE)) { + return; + } final Query query = OverridingMethodsSearch.search(method, true); final PsiMethod overridingMethod = query.findFirst(); if (overridingMethod != null) { diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleGetterInClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleGetterInClass.html index aa944f4edc42..576709e57737 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleGetterInClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleGetterInClass.html @@ -6,6 +6,9 @@ and does no other calculation. Such simple getter calls may be safely inlined, a improvement. Some coding standards also suggest against the use of simple getters for code clarity reasons.

+Use the first option below to only report on getter calls on this, not on objects of the same type passed in as a parameter. Use +the second option below to only report when the getter is private. +

Powered by InspectionGadgets \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleSetterInClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleSetterInClass.html index e8d1a8f2471c..ebb3f161ab44 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleSetterInClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleSetterInClass.html @@ -1,11 +1,14 @@ This inspection reports any calls to a simple property setter from within the property's class. -A simple property setter is defined as one which simply assigns a the value of its parameter to a field, +A simple property setter is defined as one which simply assigns the value of its parameter to a field, and does no other calculation. Such simple setter calls may be safely inlined, at a small performance improvement. Some coding standards also suggest against the use of simple setters for code clarity reasons.

+Use the first option below to only report on setter calls on this, not on objects of the same type passed in as a parameter. Use +the second option below to only report when the setter is private. +

Powered by InspectionGadgets \ No newline at end of file From 0de9ff1a120e9012f7b96eeb1b35a53ee165c9bc Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 19 Oct 2011 16:07:35 +0200 Subject: [PATCH 018/128] IDEA-75664 (CatchGenericClass should be removed) --- .../InspectionGadgets/src/META-INF/plugin.xml | 3 - .../siyeh/InspectionGadgetsBundle.properties | 2 - .../CatchGenericClassInspection.java | 81 ------------------- .../CatchGenericClass.html | 14 ---- 4 files changed, 100 deletions(-) delete mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/CatchGenericClassInspection.java delete mode 100644 plugins/InspectionGadgets/src/inspectionDescriptions/CatchGenericClass.html diff --git a/plugins/InspectionGadgets/src/META-INF/plugin.xml b/plugins/InspectionGadgets/src/META-INF/plugin.xml index 74fcf7854d92..0c1cad00fc0b 100644 --- a/plugins/InspectionGadgets/src/META-INF/plugin.xml +++ b/plugins/InspectionGadgets/src/META-INF/plugin.xml @@ -809,9 +809,6 @@ key="bad.exception.thrown.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.error.handling" enabledByDefault="false" level="WARNING" implementationClass="com.siyeh.ig.errorhandling.BadExceptionThrownInspection"/> - #ref has n missing.deprecated.annotation.problem.descriptor=Missing '@Deprecated' annotation on #ref() #loc missing.override.annotation.problem.descriptor=Missing '@Override' annotation on #ref() #loc non.thread.safe.lazy.initialization.problem.descriptor=Lazy initialization of static field #ref is not thread-safe #loc -catch.generic.class.problem.descriptor='catch' of generic #ref class should be replaced with more precise exception #loc empty.catch.block.problem.descriptor=Empty #ref block #loc unused.catch.parameter.problem.descriptor=Unused 'catch' parameter #ref #loc used.catch.parameter.named.ignore.problem.descriptor='catch' parameter named #ref is used #loc diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/CatchGenericClassInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/CatchGenericClassInspection.java deleted file mode 100644 index ba4cb9504d56..000000000000 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/CatchGenericClassInspection.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers - * - * 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.siyeh.ig.errorhandling; - -import com.intellij.psi.*; -import com.siyeh.InspectionGadgetsBundle; -import com.siyeh.ig.BaseInspection; -import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ExceptionUtils; -import org.jetbrains.annotations.NotNull; - -import java.util.Set; - -public class CatchGenericClassInspection extends BaseInspection { - - @Override - @NotNull - public String getDisplayName() { - return InspectionGadgetsBundle.message( - "catch.generic.class.display.name"); - } - - @Override - @NotNull - protected String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "catch.generic.class.problem.descriptor"); - } - - @Override - public BaseInspectionVisitor buildVisitor() { - return new CatchGenericClassVisitor(); - } - - private static class CatchGenericClassVisitor - extends BaseInspectionVisitor { - - @Override - public void visitTryStatement( - @NotNull PsiTryStatement statement) { - super.visitTryStatement(statement); - final PsiCodeBlock tryBlock = statement.getTryBlock(); - if (tryBlock == null) { - return; - } - final Set exceptionsThrown = - ExceptionUtils.calculateExceptionsThrown(tryBlock); - final PsiParameter[] parameters = - statement.getCatchBlockParameters(); - for (final PsiParameter parameter : parameters) { - checkParameter(parameter, exceptionsThrown); - } - } - - private void checkParameter(PsiParameter parameter, - Set exceptionsThrown) { - final PsiType type = parameter.getType(); - if (!ExceptionUtils.isGenericExceptionClass(type)) { - return; - } - if (exceptionsThrown.contains(type)) { - return; - } - final PsiTypeElement typeElement = parameter.getTypeElement(); - registerError(typeElement); - } - } -} \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CatchGenericClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CatchGenericClass.html deleted file mode 100644 index 532359d19f5f..000000000000 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CatchGenericClass.html +++ /dev/null @@ -1,14 +0,0 @@ - - -This inspection reports catching of a generic exception class. For clarity and -precision, it is recommended that specific exception classes be caught instead of generic ones. -This inspection reports catch blocks with arguments of the following types: -

    -
  • java.lang.Throwable
  • -
  • java.lang.Exception
  • -
  • java.lang.RuntimeException
  • -
-

-Powered by InspectionGadgets - - \ No newline at end of file From 46cc45cdee13c5c095f8ba2e50532a1a0b7716ed Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 19 Oct 2011 13:38:04 +0200 Subject: [PATCH 019/128] EA-30618 - IAE: PsiUtil.getAccessLevel --- .../impl/java/JavaClassTreeElementBase.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/java/java-impl/src/com/intellij/ide/structureView/impl/java/JavaClassTreeElementBase.java b/java/java-impl/src/com/intellij/ide/structureView/impl/java/JavaClassTreeElementBase.java index 2c679c04ad7a..8cb96c0c586b 100644 --- a/java/java-impl/src/com/intellij/ide/structureView/impl/java/JavaClassTreeElementBase.java +++ b/java/java-impl/src/com/intellij/ide/structureView/impl/java/JavaClassTreeElementBase.java @@ -19,10 +19,7 @@ import com.intellij.ide.structureView.impl.common.PsiTreeElementBase; import com.intellij.navigation.ColoredItemPresentation; import com.intellij.openapi.editor.colors.CodeInsightColors; import com.intellij.openapi.editor.colors.TextAttributesKey; -import com.intellij.psi.PsiDocCommentOwner; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiModifier; -import com.intellij.psi.PsiModifierListOwner; +import com.intellij.psi.*; import com.intellij.psi.util.PsiUtil; public abstract class JavaClassTreeElementBase extends PsiTreeElementBase implements AccessLevelProvider, @@ -44,7 +41,11 @@ public abstract class JavaClassTreeElementBase extends } public int getAccessLevel() { - return PsiUtil.getAccessLevel(((PsiModifierListOwner)getElement()).getModifierList()); + final PsiModifierList modifierList = ((PsiModifierListOwner)getElement()).getModifierList(); + if (modifierList == null) { + return PsiUtil.ACCESS_LEVEL_PUBLIC; + } + return PsiUtil.getAccessLevel(modifierList); } public int getSubLevel() { From 4db4d470bd3b92293ac713f0aa75dce750c21fa1 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 19 Oct 2011 13:39:07 +0200 Subject: [PATCH 020/128] EA-30608 - IOOBE: BaseSpellChecker.getSuggestions --- .../src/com/intellij/spellchecker/engine/BaseSpellChecker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/spellchecker/src/com/intellij/spellchecker/engine/BaseSpellChecker.java b/plugins/spellchecker/src/com/intellij/spellchecker/engine/BaseSpellChecker.java index 8002c8388ee9..1b3311743367 100644 --- a/plugins/spellchecker/src/com/intellij/spellchecker/engine/BaseSpellChecker.java +++ b/plugins/spellchecker/src/com/intellij/spellchecker/engine/BaseSpellChecker.java @@ -304,7 +304,7 @@ public class BaseSpellChecker implements SpellCheckerEngine { int bestMetrics = suggestions.get(0).getMetrics(); for (int i = 0; i < threshold; i++) { - if (suggestions.size() < i || bestMetrics - suggestions.get(i).getMetrics() > quality) { + if (suggestions.size() <= i || bestMetrics - suggestions.get(i).getMetrics() > quality) { break; } result.add(i, suggestions.get(i).getWord()); From 07c03306f771e8ae59d3c30cbda4707961edaed0 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 19 Oct 2011 13:41:52 +0200 Subject: [PATCH 021/128] EA-30540 - NPE: SimpleColoredComponent.doPaintText --- .../src/com/intellij/ui/SimpleColoredComponent.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java b/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java index 8f7e1f086bdd..fef3af00427a 100644 --- a/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java +++ b/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java @@ -464,7 +464,8 @@ public class SimpleColoredComponent extends JComponent implements Accessible { UIUtil.applyRenderingHints(g); applyAdditionalHints(g); - int baseSize = getFont().getSize(); + final Font ownFont = getFont(); + int baseSize = ownFont != null ? ownFont.getSize() : g.getFont().getSize(); boolean wasSmaller = false; for (int i = 0; i < myFragments.size(); i++) { final SimpleTextAttributes attributes = myAttributes.get(i); From 316a3f3bbc9f08c287a3407a514ad23abbac2bbf Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 19 Oct 2011 13:46:43 +0200 Subject: [PATCH 022/128] EA-30497 - CCE: ExtractIncludeAction.getHandler --- .../com/intellij/refactoring/lang/ExtractIncludeFileBase.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/lang/ExtractIncludeFileBase.java b/platform/lang-impl/src/com/intellij/refactoring/lang/ExtractIncludeFileBase.java index ff331f45af6a..b5e1eacc1b32 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/lang/ExtractIncludeFileBase.java +++ b/platform/lang-impl/src/com/intellij/refactoring/lang/ExtractIncludeFileBase.java @@ -43,6 +43,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.impl.source.resolve.reference.impl.providers.PsiFileSystemItemUtil; +import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.ui.ReplacePromptDialog; @@ -58,7 +59,7 @@ import java.util.List; /** * @author ven */ -public abstract class ExtractIncludeFileBase implements TitledHandler { +public abstract class ExtractIncludeFileBase implements RefactoringActionHandler, TitledHandler { private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.lang.ExtractIncludeFileBase"); private static final String REFACTORING_NAME = RefactoringBundle.message("extract.include.file.title"); protected PsiFile myIncludingFile; From 79e909d46afd75a223666da6e6c65bc009d87b25 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 19 Oct 2011 13:51:51 +0200 Subject: [PATCH 023/128] EA-30383 - assert: LocalSearchScope. --- .../intellij/ide/util/scopeChooser/ScopeChooserCombo.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java index 25537711dabe..00b00a11d8e1 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java +++ b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java @@ -42,6 +42,7 @@ import com.intellij.psi.search.scope.packageSet.NamedScopeManager; import com.intellij.psi.search.scope.packageSet.NamedScopesHolder; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilBase; +import com.intellij.psi.util.PsiUtilCore; import com.intellij.ui.ComboboxWithBrowseButton; import com.intellij.usages.Usage; import com.intellij.usages.UsageView; @@ -234,12 +235,12 @@ public class ScopeChooserCombo extends ComboboxWithBrowseButton implements Dispo final List elements = new ArrayList(); final PsiElement[] children = parent.getChildren(); for (PsiElement child : children) { - if (!(child instanceof PsiWhiteSpace)) { + if (!(child instanceof PsiWhiteSpace) && child.getContainingFile() != null) { elements.add(child); } } if (!elements.isEmpty()) { - SearchScope local = new LocalSearchScope(PsiUtilBase.toPsiElementArray(elements), IdeBundle.message("scope.selection")); + SearchScope local = new LocalSearchScope(PsiUtilCore.toPsiElementArray(elements), IdeBundle.message("scope.selection")); result.add(local); } } From 307def01d1ae9342da277d72e05d8088fcee1368 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 19 Oct 2011 13:56:18 +0200 Subject: [PATCH 024/128] EA-30375 - ISE: ComponentManagerImpl.getPicoContainer --- .../vcs/impl/ProjectFileIndexFacade.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/vcs/impl/ProjectFileIndexFacade.java b/platform/lang-impl/src/com/intellij/openapi/vcs/impl/ProjectFileIndexFacade.java index e6b26ee5025b..466ed9c7a8a8 100644 --- a/platform/lang-impl/src/com/intellij/openapi/vcs/impl/ProjectFileIndexFacade.java +++ b/platform/lang-impl/src/com/intellij/openapi/vcs/impl/ProjectFileIndexFacade.java @@ -19,6 +19,7 @@ package com.intellij.openapi.vcs.impl; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; +import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.roots.impl.DirectoryIndex; import com.intellij.openapi.vfs.VirtualFile; @@ -28,47 +29,47 @@ import org.jetbrains.annotations.Nullable; * @author yole */ public class ProjectFileIndexFacade extends FileIndexFacade { - private final ProjectRootManager myRootManager; private final DirectoryIndex myDirectoryIndex; + private final ProjectFileIndex myFileIndex; public ProjectFileIndexFacade(final Project project, final ProjectRootManager rootManager, final DirectoryIndex directoryIndex) { super(project); - myRootManager = rootManager; myDirectoryIndex = directoryIndex; + myFileIndex = rootManager.getFileIndex(); } public boolean isInContent(final VirtualFile file) { - return myRootManager.getFileIndex().isInContent(file); + return myFileIndex.isInContent(file); } @Override public boolean isInSource(VirtualFile file) { - return myRootManager.getFileIndex().isInSource(file); + return myFileIndex.isInSource(file); } @Override public boolean isInSourceContent(VirtualFile file) { - return myRootManager.getFileIndex().isInSourceContent(file); + return myFileIndex.isInSourceContent(file); } @Override public boolean isInLibraryClasses(VirtualFile file) { - return myRootManager.getFileIndex().isInLibraryClasses(file); + return myFileIndex.isInLibraryClasses(file); } @Override public boolean isInLibrarySource(VirtualFile file) { - return myRootManager.getFileIndex().isInLibrarySource(file); + return myFileIndex.isInLibrarySource(file); } public boolean isExcludedFile(final VirtualFile file) { - return myRootManager.getFileIndex().isIgnored(file); + return myFileIndex.isIgnored(file); } @Nullable @Override public Module getModuleForFile(VirtualFile file) { - return myRootManager.getFileIndex().getModuleForFile(file); + return myFileIndex.getModuleForFile(file); } public boolean isValidAncestor(final VirtualFile baseDir, VirtualFile childDir) { From ba6f6f82fd389c9ace630936b2d5c143fbd30b35 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 19 Oct 2011 14:48:34 +0200 Subject: [PATCH 025/128] EA-30172 - NPE: PsiElementBase.navigate --- .../core-impl/src/com/intellij/psi/impl/PsiElementBase.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiElementBase.java b/platform/core-impl/src/com/intellij/psi/impl/PsiElementBase.java index 3940760a9080..e3858a44e795 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiElementBase.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiElementBase.java @@ -22,6 +22,7 @@ import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; +import com.intellij.pom.Navigatable; import com.intellij.psi.*; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.search.GlobalSearchScope; @@ -132,7 +133,10 @@ public abstract class PsiElementBase extends ElementBase implements NavigatableP } public void navigate(boolean requestFocus) { - PsiNavigationSupport.getInstance().getDescriptor(this).navigate(requestFocus); + final Navigatable descriptor = PsiNavigationSupport.getInstance().getDescriptor(this); + if (descriptor != null) { + descriptor.navigate(requestFocus); + } } public boolean canNavigate() { From 02611aaffa303a83db186fb736c2a7c2a7fc3d9d Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 19 Oct 2011 14:56:42 +0200 Subject: [PATCH 026/128] @NotNull (EA-30171 - NPE: PsiDirectoryImpl.isValid) --- .../src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java | 2 +- .../src/com/intellij/psi/impl/file/PsiDirectoryFactory.java | 2 +- .../src/com/intellij/psi/impl/file/PsiDirectoryFactoryImpl.java | 2 +- .../src/com/intellij/psi/impl/file/PsiDirectoryImpl.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java b/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java index b002681bde19..0349435f65de 100644 --- a/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java +++ b/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java @@ -33,7 +33,7 @@ public class PsiJavaDirectoryFactory extends PsiDirectoryFactory { myManager = manager; } - public PsiDirectory createDirectory(final VirtualFile file) { + public PsiDirectory createDirectory(@NotNull final VirtualFile file) { return new PsiJavaDirectoryImpl(myManager, file); } diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactory.java b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactory.java index f5e2f574f725..8e31061895d0 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactory.java +++ b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactory.java @@ -32,7 +32,7 @@ public abstract class PsiDirectoryFactory { return ServiceManager.getService(project, PsiDirectoryFactory.class); } - public abstract PsiDirectory createDirectory(VirtualFile file); + public abstract PsiDirectory createDirectory(@NotNull VirtualFile file); @NotNull public abstract String getQualifiedName(@NotNull PsiDirectory directory, final boolean presentable); diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactoryImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactoryImpl.java index 2490262abfab..0c9c696d5cee 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactoryImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactoryImpl.java @@ -32,7 +32,7 @@ public class PsiDirectoryFactoryImpl extends PsiDirectoryFactory { public PsiDirectoryFactoryImpl(final PsiManagerImpl manager) { myManager = manager; } - public PsiDirectory createDirectory(final VirtualFile file) { + public PsiDirectory createDirectory(@NotNull final VirtualFile file) { return new PsiDirectoryImpl(myManager, file); } diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java index 06ee55ba0457..b9f8bd2a312b 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java @@ -63,7 +63,7 @@ public class PsiDirectoryImpl extends PsiElementBase implements PsiDirectory, Qu private final PsiManagerImpl myManager; private final VirtualFile myFile; - public PsiDirectoryImpl(PsiManagerImpl manager, VirtualFile file) { + public PsiDirectoryImpl(PsiManagerImpl manager, @NotNull VirtualFile file) { myManager = manager; myFile = file; } From 0c468e3a5b2281be13094c71d675aed2cce3145f Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 19 Oct 2011 14:59:59 +0200 Subject: [PATCH 027/128] don't return NULL_PSI_ELEMENT from JavaParserDefinition.createElement() (EA-30121 - IAE: PsiUtilCore$1.getLanguage) --- .../src/com/intellij/lang/java/JavaParserDefinition.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/lang/java/JavaParserDefinition.java b/java/java-psi-impl/src/com/intellij/lang/java/JavaParserDefinition.java index baa5a32af615..c7f63bff9152 100644 --- a/java/java-psi-impl/src/com/intellij/lang/java/JavaParserDefinition.java +++ b/java/java-psi-impl/src/com/intellij/lang/java/JavaParserDefinition.java @@ -33,7 +33,6 @@ import com.intellij.psi.impl.source.tree.JavaElementType; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.tree.TokenSet; -import com.intellij.psi.util.PsiUtilCore; import org.jetbrains.annotations.NotNull; /** @@ -82,7 +81,7 @@ public class JavaParserDefinition implements ParserDefinition { return ((JavaStubElementType)type).createPsi(node); } - return PsiUtilCore.NULL_PSI_ELEMENT; + throw new IllegalStateException("incorrect element type for JavaParserDefinition: " + type); } public PsiFile createFile(final FileViewProvider viewProvider) { From 01429c30220c2df167679c71fe8d0d0613722db0 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 19 Oct 2011 15:01:39 +0200 Subject: [PATCH 028/128] EA-30115 - IAE: Extensions.getArea --- .../src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java index 5cbca1b7df63..795138502727 100644 --- a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java @@ -486,8 +486,10 @@ public class ScopeTreeViewPanel extends JPanel implements Disposable { append(node.toString(), SimpleTextAttributes.fromTextAttributes(textAttributes)); String oldToString = toString(); - for(ProjectViewNodeDecorator decorator: Extensions.getExtensions(ProjectViewNodeDecorator.EP_NAME, myProject)) { - decorator.decorate(node, this); + if (!myProject.isDisposed()) { + for(ProjectViewNodeDecorator decorator: Extensions.getExtensions(ProjectViewNodeDecorator.EP_NAME, myProject)) { + decorator.decorate(node, this); + } } if (toString().equals(oldToString)) { // nothing was decorated final String locationString = node.getComment(); From d942283c28cb2dfa7d88ee0852f93c5ca15146db Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 19 Oct 2011 15:18:05 +0200 Subject: [PATCH 029/128] EA-29878 - PIEAE: PsiElementBase.getContainingFile --- .../com/intellij/ide/projectView/impl/nodes/ClassTreeNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/ClassTreeNode.java b/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/ClassTreeNode.java index f33eab6b2520..e747772193ef 100644 --- a/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/ClassTreeNode.java +++ b/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/ClassTreeNode.java @@ -95,7 +95,7 @@ public class ClassTreeNode extends BasePsiMemberNode{ @Override public String getTitle() { final PsiClass psiClass = getValue(); - if (psiClass != null) { + if (psiClass != null && psiClass.isValid()) { return psiClass.getQualifiedName(); } return super.getTitle(); From 0464e14c23f8816910d3f00f5399de4dc563c8c0 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 19 Oct 2011 16:13:16 +0200 Subject: [PATCH 030/128] EA-29781 - CCE: ComboBoxPropertyEditor.updateUI --- .../editors/ComboBoxPropertyEditor.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/editors/ComboBoxPropertyEditor.java b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/editors/ComboBoxPropertyEditor.java index efdc5d5c59b7..f8a2e9019408 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/editors/ComboBoxPropertyEditor.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/editors/ComboBoxPropertyEditor.java @@ -38,16 +38,19 @@ public abstract class ComboBoxPropertyEditor extends PropertyEditor { public final void updateUI() { SwingUtilities.updateComponentTreeUI(myCbx); - SwingUtilities.updateComponentTreeUI((JComponent)myCbx.getRenderer()); + final ListCellRenderer renderer = myCbx.getRenderer(); + if (renderer instanceof JComponent) { + SwingUtilities.updateComponentTreeUI((JComponent)renderer); + } } - public V getValue() throws Exception{ - if(myCbx.isEditable()){ + public V getValue() throws Exception { + if (myCbx.isEditable()) { final Component editorComponent = myCbx.getEditor().getEditorComponent(); //noinspection unchecked return (V)((JTextField)editorComponent).getText(); } - else{ + else { //noinspection unchecked return (V)myCbx.getSelectedItem(); } From a5ee25cd17cf2c81a494d8ce934b249e0f4f6d77 Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Wed, 19 Oct 2011 18:41:38 +0400 Subject: [PATCH 031/128] Cosmetics --- reformatted code. --- .../org/jetbrains/ether/DirectoryScanner.java | 276 +++--- jps/src/org/jetbrains/ether/DotPrinter.java | 111 ++- jps/src/org/jetbrains/ether/Main.java | 468 +++++----- jps/src/org/jetbrains/ether/MockFS.java | 191 ++-- jps/src/org/jetbrains/ether/Options.java | 423 ++++----- jps/src/org/jetbrains/ether/Pair.java | 42 +- .../org/jetbrains/ether/ProjectWrapper.java | 3 +- jps/src/org/jetbrains/ether/RW.java | 356 +++---- jps/src/org/jetbrains/ether/Reporter.java | 139 ++- .../ether/dependencyView/AntListener.java | 504 +++++----- .../ether/dependencyView/Callbacks.java | 37 +- .../dependencyView/ClassfileAnalyzer.java | 1 - .../ether/dependencyView/Difference.java | 175 ++-- .../ether/dependencyView/FieldRepr.java | 76 +- .../ether/dependencyView/FoxyMap.java | 203 ++-- .../ether/dependencyView/Mappings.java | 38 +- .../ether/dependencyView/MethodRepr.java | 213 ++--- .../dependencyView/PackageNameSelector.java | 398 ++++---- .../jetbrains/ether/dependencyView/Proto.java | 116 ++- .../ether/dependencyView/ProtoMember.java | 225 ++--- .../ether/dependencyView/StringCache.java | 158 ++-- .../ether/dependencyView/TypeRepr.java | 573 ++++++------ .../ether/dependencyView/UsageRepr.java | 866 +++++++++--------- 23 files changed, 2810 insertions(+), 2782 deletions(-) diff --git a/jps/src/org/jetbrains/ether/DirectoryScanner.java b/jps/src/org/jetbrains/ether/DirectoryScanner.java index 929eb7a1ce4d..92cfedbe3a96 100644 --- a/jps/src/org/jetbrains/ether/DirectoryScanner.java +++ b/jps/src/org/jetbrains/ether/DirectoryScanner.java @@ -18,159 +18,157 @@ import java.util.regex.Pattern; public class DirectoryScanner { - public static class Result { - final Set myFiles; - long myLatest; - long myEarliest; + public static class Result { + final Set myFiles; + long myLatest; + long myEarliest; - public Result () { - myFiles = new HashSet (); - myLatest = 0; - myEarliest = Long.MAX_VALUE; - } - - public void update (final ProjectWrapper.FileWrapper w) { - final long t = w.getStamp (); - - if (t > myLatest) - myLatest = t; - - if (t< myEarliest) - myEarliest = t; - - myFiles.add(w); - } - - public long getEarliest () { - return myEarliest; - } - - public long getLatest () { - return myLatest; - } - - public Set getFiles () { - return myFiles; - } + public Result() { + myFiles = new HashSet(); + myLatest = 0; + myEarliest = Long.MAX_VALUE; } - private static class Crawler { - final Result myResult; - final FileFilter myFilter; - final ProjectWrapper myProjectWrapper; + public void update(final ProjectWrapper.FileWrapper w) { + final long t = w.getStamp(); - public Crawler (final FileFilter ff, final ProjectWrapper pw) { - myResult = new Result(); - myFilter = ff; - myProjectWrapper = pw; - } + if (t > myLatest) myLatest = t; - public Result getResult () { - return myResult; - } + if (t < myEarliest) myEarliest = t; - public void run(File root) { - if (root.exists()) { - final File[] files = root.listFiles(myFilter); - - for (int i = 0; i < files.length; i++) { - myResult.update (myProjectWrapper.new FileWrapper(files[i])); - } - - final File[] subdirs = root.listFiles(myDirectoryFilter); - - for (int i = 0; i < subdirs.length; i++) { - run(subdirs[i]); - } - } - } + myFiles.add(w); } - private static FileFilter myDirectoryFilter = new FileFilter() { + public long getEarliest() { + return myEarliest; + } + + public long getLatest() { + return myLatest; + } + + public Set getFiles() { + return myFiles; + } + } + + private static class Crawler { + final Result myResult; + final FileFilter myFilter; + final ProjectWrapper myProjectWrapper; + + public Crawler(final FileFilter ff, final ProjectWrapper pw) { + myResult = new Result(); + myFilter = ff; + myProjectWrapper = pw; + } + + public Result getResult() { + return myResult; + } + + public void run(File root) { + if (root.exists()) { + final File[] files = root.listFiles(myFilter); + + for (int i = 0; i < files.length; i++) { + myResult.update(myProjectWrapper.new FileWrapper(files[i])); + } + + final File[] subdirs = root.listFiles(myDirectoryFilter); + + for (int i = 0; i < subdirs.length; i++) { + run(subdirs[i]); + } + } + } + } + + private static FileFilter myDirectoryFilter = new FileFilter() { + public boolean accept(File f) { + final String name = f.getName(); + + return f.isDirectory() && !name.equals(".") && !name.equals(".."); + } + }; + + private static FileFilter myTrueFilter = new FileFilter() { + public boolean accept(File s) { + return s.isFile(); + } + }; + + private static FileFilter createFilter(final Collection excludes) { + if (excludes == null) { + return myTrueFilter; + } + + StringBuilder buf = new StringBuilder(); + + for (String exclude : excludes) { + StringBuilder alternative = new StringBuilder(); + + if (exclude != null) { + for (int i = 0; i < exclude.length(); i++) { + final char c = exclude.charAt(i); + + switch (c) { + case '.': + case '\\': + case '*': + case '^': + case '$': + case '[': + case '(': + case '|': + alternative.append("\\"); + alternative.append(c); + break; + + case '?': + alternative.append("."); + break; + + default: + alternative.append(c); + } + } + } + + if (alternative.length() > 0) { + alternative.append(".*"); + + if (buf.length() > 0) buf.append("|"); + + buf.append("("); + buf.append(alternative); + buf.append(')'); + } + } + + if (buf.length() > 0) { + final Pattern patt = Pattern.compile(buf.toString()); + + return new FileFilter() { public boolean accept(File f) { - final String name = f.getName(); + final Matcher m = patt.matcher(f.getAbsolutePath()); + final boolean ok = !m.matches(); - return f.isDirectory() && !name.equals(".") && !name.equals(".."); + return ok && f.isFile(); } - }; - - private static FileFilter myTrueFilter = new FileFilter() { - public boolean accept(File s) { - return s.isFile(); - } - }; - - private static FileFilter createFilter(final Collection excludes) { - if (excludes == null) { - return myTrueFilter; - } - - StringBuilder buf = new StringBuilder(); - - for (String exclude : excludes) { - StringBuilder alternative = new StringBuilder(); - - if (exclude != null) { - for (int i = 0; i < exclude.length(); i++) { - final char c = exclude.charAt(i); - - switch (c) { - case '.': - case '\\': - case '*': - case '^': - case '$': - case '[': - case '(': - case '|': - alternative.append("\\"); - alternative.append(c); - break; - - case '?': - alternative.append("."); - break; - - default: - alternative.append(c); - } - } - } - - if (alternative.length() > 0) { - alternative.append(".*"); - - if (buf.length() > 0) - buf.append("|"); - - buf.append("("); - buf.append(alternative); - buf.append(')'); - } - } - - if (buf.length() > 0) { - final Pattern patt = Pattern.compile(buf.toString()); - - return new FileFilter() { - public boolean accept(File f) { - final Matcher m = patt.matcher(f.getAbsolutePath()); - final boolean ok = !m.matches(); - - return ok && f.isFile(); - } - }; - } - - return myTrueFilter; + }; } - public static Result getFiles(final Set roots, final Set excludes, final ProjectWrapper pw) { - final Crawler cw = new Crawler(createFilter(excludes), pw); + return myTrueFilter; + } - for (String root : roots) - cw.run(new File(pw.getAbsolutePath(root))); + public static Result getFiles(final Set roots, final Set excludes, final ProjectWrapper pw) { + final Crawler cw = new Crawler(createFilter(excludes), pw); - return cw.getResult(); + for (String root : roots) { + cw.run(new File(pw.getAbsolutePath(root))); } + + return cw.getResult(); + } } diff --git a/jps/src/org/jetbrains/ether/DotPrinter.java b/jps/src/org/jetbrains/ether/DotPrinter.java index 70f8952f73b4..cb45d0dc4fa6 100644 --- a/jps/src/org/jetbrains/ether/DotPrinter.java +++ b/jps/src/org/jetbrains/ether/DotPrinter.java @@ -1,6 +1,5 @@ package org.jetbrains.ether; -import java.io.BufferedWriter; import java.io.PrintStream; /** @@ -11,69 +10,69 @@ import java.io.PrintStream; * To change this template use File | Settings | File Templates. */ public class DotPrinter { - private final PrintStream stream; + private final PrintStream stream; - public DotPrinter(final PrintStream stream) { - this.stream = stream; + public DotPrinter(final PrintStream stream) { + this.stream = stream; + } + + private static String escape(final String s) { + final StringBuilder b = new StringBuilder(); + + for (int i = 0; i < s.length(); i++) { + final char c = s.charAt(i); + + if (c == '_' || Character.isDigit(c) || Character.isLetter(c)) { + b.append(c); + } + else if (c == '-') { + b.append('_'); + } + else { + b.append(Character.getNumericValue(c)); + } } - private static String escape(final String s) { - final StringBuilder b = new StringBuilder(); + return b.toString(); + } - for (int i = 0; i < s.length(); i++) { - final char c = s.charAt(i); + public static void header(final PrintStream s) { + if (s != null) s.println("digraph X {"); + } - if (c == '_' || Character.isDigit(c) || Character.isLetter(c)) { - b.append(c); - } else if (c == '-') { - b.append('_'); - } else { - b.append(Character.getNumericValue(c)); - } - } + public void header() { + header(stream); + } - return b.toString(); + public static void footer(final PrintStream s) { + if (s != null) s.println("}"); + } + + public void footer() { + footer(stream); + } + + public static void node(final PrintStream s, String n) { + if (s != null) { + n = escape(n); + s.println(" " + n + "[label=\"" + n + "\"];"); } + } - public static void header(final PrintStream s) { - if (s != null) - s.println("digraph X {"); + public void node(final String n) { + node(stream, n); + } + + public static void edge(final PrintStream s, String b, String e) { + if (s != null) { + b = escape(b); + e = escape(e); + + s.println(" " + b + " -> " + e + ";"); } + } - public void header() { - header(stream); - } - - public static void footer(final PrintStream s) { - if (s != null) - s.println("}"); - } - - public void footer() { - footer(stream); - } - - public static void node(final PrintStream s, String n) { - if (s != null) { - n = escape(n); - s.println(" " + n + "[label=\"" + n + "\"];"); - } - } - - public void node(final String n) { - node(stream, n); - } - - public static void edge(final PrintStream s, String b, String e) { - if (s != null) { - b = escape(b); - e = escape(e); - - s.println(" " + b + " -> " + e + ";"); - } - } - - public void edge(final String b, final String e) { - edge(stream, b, e); - } + public void edge(final String b, final String e) { + edge(stream, b, e); + } } diff --git a/jps/src/org/jetbrains/ether/Main.java b/jps/src/org/jetbrains/ether/Main.java index 24bd4b214fa5..6e773535028f 100644 --- a/jps/src/org/jetbrains/ether/Main.java +++ b/jps/src/org/jetbrains/ether/Main.java @@ -1,6 +1,8 @@ package org.jetbrains.ether; -import java.io.*; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; import java.util.List; /** @@ -13,257 +15,257 @@ import java.util.List; * The main class to start with */ public class Main { - private static final Options myOptions; + private static final Options myOptions; - private enum Action { - REBUILD, - MAKE, - CLEAN, - NONE + private enum Action { + REBUILD, + MAKE, + CLEAN, + NONE + } + + static { + final Options.Descriptor[] descrs = {new Options.Descriptor("script", "script", "s", Options.ArgumentSpecifier.MANDATORY, + "specify script for project library/sdk setup; use prefix '@' to specify script file"), + new Options.Descriptor("inspect", "inspect", "i", Options.ArgumentSpecifier.OPTIONAL, + "list relevant information for the whole project or specified module"), + new Options.Descriptor("save", "save", "x", Options.ArgumentSpecifier.NONE, "collect and save project information"), + new Options.Descriptor("clean", "clean", "c", Options.ArgumentSpecifier.NONE, "clean project"), + new Options.Descriptor("rebuild", "rebuild", "r", Options.ArgumentSpecifier.NONE, "rebuild project"), + new Options.Descriptor("make", "make", "m", Options.ArgumentSpecifier.OPTIONAL, "make the whole project or specified module"), + new Options.Descriptor("tests", "tests", "t", Options.ArgumentSpecifier.NONE, "make tests as well"), + new Options.Descriptor("force", "force", "f", Options.ArgumentSpecifier.NONE, "force actions"), + new Options.Descriptor("incremental", "incremental", "u", Options.ArgumentSpecifier.NONE, "perform incremental make"), + new Options.Descriptor("help", "help", "h", Options.ArgumentSpecifier.NONE, "show help on options"), + new Options.Descriptor("log", "log", "l", Options.ArgumentSpecifier.OPTIONAL, "log into file (for development purposes)")}; + + myOptions = new Options(descrs); + } + + private static PrintStream logStream = null; + private static boolean logStreamSet = false; + + private static PrintStream getLog() { + if (logStreamSet) { + return logStream; } - static { - final Options.Descriptor[] descrs = { - new Options.Descriptor("script", "script", "s", Options.ArgumentSpecifier.MANDATORY, "specify script for project library/sdk setup; use prefix '@' to specify script file"), - new Options.Descriptor("inspect", "inspect", "i", Options.ArgumentSpecifier.OPTIONAL, "list relevant information for the whole project or specified module"), - new Options.Descriptor("save", "save", "x", Options.ArgumentSpecifier.NONE, "collect and save project information"), - new Options.Descriptor("clean", "clean", "c", Options.ArgumentSpecifier.NONE, "clean project"), - new Options.Descriptor("rebuild", "rebuild", "r", Options.ArgumentSpecifier.NONE, "rebuild project"), - new Options.Descriptor("make", "make", "m", Options.ArgumentSpecifier.OPTIONAL, "make the whole project or specified module"), - new Options.Descriptor("tests", "tests", "t", Options.ArgumentSpecifier.NONE, "make tests as well"), - new Options.Descriptor("force", "force", "f", Options.ArgumentSpecifier.NONE, "force actions"), - new Options.Descriptor("incremental", "incremental", "u", Options.ArgumentSpecifier.NONE, "perform incremental make"), - new Options.Descriptor("help", "help", "h", Options.ArgumentSpecifier.NONE, "show help on options"), - new Options.Descriptor("log", "log", "l", Options.ArgumentSpecifier.OPTIONAL, "log into file (for development purposes)") - }; + logStreamSet = true; - myOptions = new Options(descrs); + final Options.Argument arg = myOptions.get("log"); + + if (arg == null) { + return null; } - private static PrintStream logStream = null; - private static boolean logStreamSet = false; - - private static PrintStream getLog() { - if (logStreamSet) { - return logStream; - } - - logStreamSet = true; - - final Options.Argument arg = myOptions.get("log"); - - if (arg == null) { - return null; - } - - if (arg instanceof Options.Value) { - try { - return logStream = new PrintStream(new FileOutputStream(((Options.Value) arg).get())); - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } - - if (arg instanceof Options.Switch) { - return logStream = System.out; - } - + if (arg instanceof Options.Value) { + try { + return logStream = new PrintStream(new FileOutputStream(((Options.Value)arg).get())); + } + catch (IOException e) { + e.printStackTrace(); return null; + } } - private static boolean doSave() { - return myOptions.get("save") instanceof Options.Switch; + if (arg instanceof Options.Switch) { + return logStream = System.out; } - private static boolean doTests() { - return myOptions.get("tests") instanceof Options.Switch; + return null; + } + + private static boolean doSave() { + return myOptions.get("save") instanceof Options.Switch; + } + + private static boolean doTests() { + return myOptions.get("tests") instanceof Options.Switch; + } + + private static boolean doRebuild() { + return myOptions.get("rebuild") instanceof Options.Switch; + } + + private static boolean doForce() { + return myOptions.get("force") instanceof Options.Switch; + } + + private static boolean doIncremental() { + return myOptions.get("incremental") instanceof Options.Switch; + } + + private static boolean doHelp() { + return myOptions.get("help") instanceof Options.Switch; + } + + private static Options.Argument doInspect() { + return myOptions.get("inspect"); + } + + private static Options.Argument doMake() { + return myOptions.get("make"); + } + + private static boolean doClean() { + return myOptions.get("clean") instanceof Options.Switch; + } + + private static String getScript() { + final Options.Argument arg = myOptions.get("script"); + + if (arg instanceof Options.Value) return ((Options.Value)arg).get(); + + return null; + } + + private static ProjectWrapper.Flags getFlags() { + return new ProjectWrapper.Flags() { + public boolean tests() { + return doTests(); + } + + public boolean force() { + return doForce(); + } + + public boolean incremental() { + return doIncremental(); + } + + public PrintStream logStream() { + return getLog(); + } + }; + } + + private static void checkConsistency() { + int test = 0; + + if (doClean()) test++; + if (doMake() != null) test++; + if (doRebuild()) test++; + + if (test > 1) { + System.err.print("WARNING: Conflicting options (should be --make OR --rebuild OR --clean); preferring "); + if (doMake() != null) { + System.err.println("make."); + } + else if (doRebuild()) System.err.println("rebuild."); } - private static boolean doRebuild() { - return myOptions.get("rebuild") instanceof Options.Switch; + if (doClean() || doRebuild()) { + if (doTests()) { + System.err.println("WARNING: extra --tests option ignored."); + } + if (doForce()) { + System.err.println("WARNING: extra --force option ignored."); + } + } + } + + private static Action getAction() { + if (doMake() != null) { + return Action.MAKE; } - private static boolean doForce() { - return myOptions.get("force") instanceof Options.Switch; + if (doRebuild()) return Action.REBUILD; + + if (doClean()) return Action.CLEAN; + + return Action.NONE; + } + + public static void main(String[] args) { + System.out.println("JetBrains.com build server. (C) JetBrains.com, 2010-2011.\n"); + + final List notes = myOptions.parse(args); + + for (String note : notes) { + System.err.println("WARNING: " + note); } - private static boolean doIncremental() { - return myOptions.get("incremental") instanceof Options.Switch; + checkConsistency(); + + if (doHelp()) { + System.out.println("Usage: ??? \n"); + System.out.println("Options are:"); + System.out.println(myOptions.memo()); + } + + final List projects = myOptions.getFree(); + + if (projects.isEmpty() && !doHelp()) { + System.out.println("Nothing to do; use --help or -h option to see the help.\n"); + } + + for (String prj : projects) { + boolean saved = false; + ProjectWrapper project = null; + + switch (getAction()) { + case CLEAN: + System.out.println("Cleaning project \"" + prj + "\""); + project = ProjectWrapper.load(prj, getScript(), false); + + project.clean(); + project.save(); + saved = true; + break; + + case REBUILD: + System.out.println("Rebuilding project \"" + prj + "\""); + project = ProjectWrapper.load(prj, getScript(), false); + project.rebuild(); + project.save(); + saved = true; + break; + + case MAKE: + final Options.Argument make = doMake(); + + if (make instanceof Options.Value) { + final String module = ((Options.Value)make).get(); + System.out.println("Making module \"" + module + "\" in project \"" + prj + "\""); + project = ProjectWrapper.load(prj, getScript(), true); + project.makeModule(module, getFlags()); + project.save(); + saved = true; + } + else if (make instanceof Options.Switch) { + System.out.println("Making all modules in project \"" + prj + "\""); + project = ProjectWrapper.load(prj, getScript(), true); + project.makeModule(null, getFlags()); + project.save(); + saved = true; + } + ; + break; + } + + final Options.Argument inspect = doInspect(); + + if (inspect instanceof Options.Switch) { + project = ProjectWrapper.load(prj, getScript(), true); + project.report(); + if (doSave()) { + project.save(); + saved = true; } - - private static boolean doHelp() { - return myOptions.get("help") instanceof Options.Switch; - } - - private static Options.Argument doInspect() { - return myOptions.get("inspect"); - } - - private static Options.Argument doMake() { - return myOptions.get("make"); - } - - private static boolean doClean() { - return myOptions.get("clean") instanceof Options.Switch; - } - - private static String getScript() { - final Options.Argument arg = myOptions.get("script"); - - if (arg instanceof Options.Value) - return ((Options.Value) arg).get(); - - return null; - } - - private static ProjectWrapper.Flags getFlags () { - return new ProjectWrapper.Flags() { - public boolean tests () { - return doTests(); - } - - public boolean force () { - return doForce(); - } - - public boolean incremental () { - return doIncremental(); - } - - public PrintStream logStream () { - return getLog(); - } - }; - } - - private static void checkConsistency() { - int test = 0; - - if (doClean()) test++; - if (doMake() != null) test++; - if (doRebuild()) test++; - - if (test > 1) { - System.err.print("WARNING: Conflicting options (should be --make OR --rebuild OR --clean); preferring "); - if (doMake() != null) - System.err.println("make."); - else if (doRebuild()) - System.err.println("rebuild."); + } + else if (inspect instanceof Options.Value) { + project = ProjectWrapper.load(prj, getScript(), true); + project.report(((Options.Value)inspect).get()); + if (doSave()) { + project.save(); + saved = true; } + } - if (doClean() || doRebuild()) { - if (doTests()) { - System.err.println("WARNING: extra --tests option ignored."); - } - if (doForce()) { - System.err.println("WARNING: extra --force option ignored."); - } - } - } - - private static Action getAction() { - if (doMake() != null) { - return Action.MAKE; - } - - if (doRebuild()) - return Action.REBUILD; - - if (doClean()) - return Action.CLEAN; - - return Action.NONE; - } - - public static void main(String[] args) { - System.out.println("JetBrains.com build server. (C) JetBrains.com, 2010-2011.\n"); - - final List notes = myOptions.parse(args); - - for (String note : notes) { - System.err.println("WARNING: " + note); - } - - checkConsistency(); - - if (doHelp()) { - System.out.println("Usage: ??? \n"); - System.out.println("Options are:"); - System.out.println(myOptions.memo()); - } - - final List projects = myOptions.getFree(); - - if (projects.isEmpty() && !doHelp()) { - System.out.println("Nothing to do; use --help or -h option to see the help.\n"); - } - - for (String prj : projects) { - boolean saved = false; - ProjectWrapper project = null; - - switch (getAction()) { - case CLEAN: - System.out.println("Cleaning project \"" + prj + "\""); - project = ProjectWrapper.load(prj, getScript(), false); - - project.clean(); - project.save(); - saved = true; - break; - - case REBUILD: - System.out.println("Rebuilding project \"" + prj + "\""); - project = ProjectWrapper.load(prj, getScript(), false); - project.rebuild(); - project.save(); - saved = true; - break; - - case MAKE: - final Options.Argument make = doMake(); - - if (make instanceof Options.Value) { - final String module = ((Options.Value) make).get(); - System.out.println("Making module \"" + module + "\" in project \"" + prj + "\""); - project = ProjectWrapper.load(prj, getScript(), true); - project.makeModule(module, getFlags ()); - project.save(); - saved = true; - } else if (make instanceof Options.Switch) { - System.out.println("Making all modules in project \"" + prj + "\""); - project = ProjectWrapper.load(prj, getScript(), true); - project.makeModule(null, getFlags ()); - project.save(); - saved = true; - } - ; - break; - } - - final Options.Argument inspect = doInspect(); - - if (inspect instanceof Options.Switch) { - project = ProjectWrapper.load(prj, getScript(), true); - project.report(); - if (doSave()) { - project.save(); - saved = true; - } - } else if (inspect instanceof Options.Value) { - project = ProjectWrapper.load(prj, getScript(), true); - project.report(((Options.Value) inspect).get()); - if (doSave()) { - project.save(); - saved = true; - } - } - - if (doSave() && !saved) { - project = ProjectWrapper.load(prj, getScript(), true); - project.save(); - } - } + if (doSave() && !saved) { + project = ProjectWrapper.load(prj, getScript(), true); + project.save(); + } } + } } diff --git a/jps/src/org/jetbrains/ether/MockFS.java b/jps/src/org/jetbrains/ether/MockFS.java index a4bb40486387..c81aa8e775dc 100644 --- a/jps/src/org/jetbrains/ether/MockFS.java +++ b/jps/src/org/jetbrains/ether/MockFS.java @@ -1,6 +1,5 @@ package org.jetbrains.ether; -import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; import java.util.*; @@ -13,116 +12,116 @@ import java.util.*; * To change this template use File | Settings | File Templates. */ public class MockFS { - final Map myFiles = new HashMap(); - final File myRoot; + final Map myFiles = new HashMap(); + final File myRoot; - private File getFile(java.io.File f) { - if (f.getAbsolutePath().startsWith(myRoot.getAbsolutePath())) { - File g = myFiles.get(f); + private File getFile(java.io.File f) { + if (f.getAbsolutePath().startsWith(myRoot.getAbsolutePath())) { + File g = myFiles.get(f); - if (g != null) { - return g; - } + if (g != null) { + return g; + } - g = new File(f, false); + g = new File(f, false); - myFiles.put(f, g); + myFiles.put(f, g); - return g; - } - - return null; + return g; } - public class File extends java.io.File { - final Set mySubFiles = new HashSet(); - final File myParent; + return null; + } - private File(final java.io.File file, final boolean root) { - super(file.getPath()); + public class File extends java.io.File { + final Set mySubFiles = new HashSet(); + final File myParent; - if (root) { - myParent = null; - return; - } + private File(final java.io.File file, final boolean root) { + super(file.getPath()); - final java.io.File parent = file.getParentFile(); + if (root) { + myParent = null; + return; + } - myParent = parent == null ? null : getFile(parent); + final java.io.File parent = file.getParentFile(); - if (myParent != null) { - myParent.mySubFiles.add(this); - } - } + myParent = parent == null ? null : getFile(parent); - @Override - public String[] list() { - return list(new FilenameFilter() { - public boolean accept(java.io.File dir, String name) { - return true; - } - }); - } - - @Override - public String[] list(final FilenameFilter filter) { - final List result = new LinkedList(); - - for (final File f : mySubFiles) { - if (filter.accept(this, f.getName())) { - result.add(f.getName()); - } - } - - return result.toArray(new String[result.size()]); - } - - @Override - public java.io.File[] listFiles() { - return mySubFiles.toArray(new File[mySubFiles.size()]); - } - - @Override - public java.io.File[] listFiles(final FilenameFilter filter) { - final List result = new LinkedList(); - - for (File f : mySubFiles) { - if (filter.accept(this, f.getName())) { - result.add(f); - } - } - - return result.toArray(new File[result.size()]); - } - - @Override - public java.io.File[] listFiles(final FileFilter filter) { - final List result = new LinkedList(); - - for (File f : mySubFiles) { - if (filter.accept(f)) { - result.add(f); - } - } - - return result.toArray(new File[result.size()]); - } + if (myParent != null) { + myParent.mySubFiles.add(this); + } } - private MockFS(final String root) { - final java.io.File rootFile = new java.io.File(root); - - myRoot = new File(rootFile, true); - myFiles.put(rootFile, myRoot); - } - - public static File fromFiles(final String root, final Collection files) { - final MockFS fs = new MockFS(root); - - for (String f : files) { - fs.getFile(new java.io.File (f)); + @Override + public String[] list() { + return list(new FilenameFilter() { + public boolean accept(java.io.File dir, String name) { + return true; } - - return fs.myRoot; + }); } + + @Override + public String[] list(final FilenameFilter filter) { + final List result = new LinkedList(); + + for (final File f : mySubFiles) { + if (filter.accept(this, f.getName())) { + result.add(f.getName()); + } + } + + return result.toArray(new String[result.size()]); + } + + @Override + public java.io.File[] listFiles() { + return mySubFiles.toArray(new File[mySubFiles.size()]); + } + + @Override + public java.io.File[] listFiles(final FilenameFilter filter) { + final List result = new LinkedList(); + + for (File f : mySubFiles) { + if (filter.accept(this, f.getName())) { + result.add(f); + } + } + + return result.toArray(new File[result.size()]); + } + + @Override + public java.io.File[] listFiles(final FileFilter filter) { + final List result = new LinkedList(); + + for (File f : mySubFiles) { + if (filter.accept(f)) { + result.add(f); + } + } + + return result.toArray(new File[result.size()]); + } + } + + private MockFS(final String root) { + final java.io.File rootFile = new java.io.File(root); + + myRoot = new File(rootFile, true); + myFiles.put(rootFile, myRoot); + } + + public static File fromFiles(final String root, final Collection files) { + final MockFS fs = new MockFS(root); + + for (String f : files) { + fs.getFile(new java.io.File(f)); + } + + return fs.myRoot; + } } diff --git a/jps/src/org/jetbrains/ether/Options.java b/jps/src/org/jetbrains/ether/Options.java index 4f62f39062d9..266c2bed6a0a 100644 --- a/jps/src/org/jetbrains/ether/Options.java +++ b/jps/src/org/jetbrains/ether/Options.java @@ -16,240 +16,251 @@ import java.util.regex.Pattern; */ public class Options { - public enum ArgumentSpecifier { - MANDATORY, - OPTIONAL, - NONE; + public enum ArgumentSpecifier { + MANDATORY, + OPTIONAL, + NONE; + } + + public abstract interface Argument { + } + + public static class Switch implements Argument { + + } + + private static Switch SWITCH = new Switch(); + + public static class Value implements Argument { + private final String myValue; + + Value(final String s) { + myValue = s; } - public abstract interface Argument { + public String get() { + return myValue; + } + } + + private class Cursor { + int myPos; + final int myLength; + final String[] myArgs; + + Cursor(final String[] args) { + myArgs = args; + myPos = 0; + myLength = myArgs.length; } - public static class Switch implements Argument { + public String look() { + if (myPos >= myLength) return null; + return myArgs[myPos]; } - private static Switch SWITCH = new Switch(); - - public static class Value implements Argument { - private final String myValue; - - Value (final String s) { - myValue = s; - } - - public String get () { - return myValue; - } + public void shift() { + myPos++; } - private class Cursor { - int myPos; - final int myLength; - final String[] myArgs; + public String lookahead() { + final String arg = myArgs[myPos + 1]; + myPos += 2; - Cursor (final String[] args) { - myArgs = args; - myPos = 0; - myLength = myArgs.length; - } - - public String look () { - if (myPos >= myLength) - return null; - - return myArgs [myPos]; - } - - public void shift () { - myPos++; - } - public String lookahead () { - final String arg = myArgs[myPos+1]; - myPos += 2; - - return arg; - } - - public boolean nextIsArg () { - return (myPos < myLength - 1 && ! myArgs[myPos+1].startsWith("-")); - } - - public boolean endOf () { - return myPos >= myLength; - } + return arg; } - private interface Callback { - void update (String key, Argument value); - void addFree (String value); - void report (String note); + public boolean nextIsArg() { + return (myPos < myLength - 1 && !myArgs[myPos + 1].startsWith("-")); } - public static class Descriptor { - private final ArgumentSpecifier myArgumentSpecifier; - private final String myKey; - private final String myLong; - private final String myShort; - private final String myMemo; + public boolean endOf() { + return myPos >= myLength; + } + } - private final Pattern myLongPattern; + private interface Callback { + void update(String key, Argument value); - Descriptor (final String key, final String longForm, final String shortForm, final ArgumentSpecifier as, final String memo) { - myArgumentSpecifier = as; - myKey = key; - myLong = longForm; - myShort = shortForm; - myMemo = memo; + void addFree(String value); - myLongPattern = myLong == null ? null : Pattern.compile("^--" + myLong + "(=(.*))?$"); - } + void report(String note); + } - public String memo () { - final StringBuilder buf = new StringBuilder(); - String longArg = "", shortArg = ""; + public static class Descriptor { + private final ArgumentSpecifier myArgumentSpecifier; + private final String myKey; + private final String myLong; + private final String myShort; + private final String myMemo; - switch (myArgumentSpecifier) { + private final Pattern myLongPattern; + + Descriptor(final String key, final String longForm, final String shortForm, final ArgumentSpecifier as, final String memo) { + myArgumentSpecifier = as; + myKey = key; + myLong = longForm; + myShort = shortForm; + myMemo = memo; + + myLongPattern = myLong == null ? null : Pattern.compile("^--" + myLong + "(=(.*))?$"); + } + + public String memo() { + final StringBuilder buf = new StringBuilder(); + String longArg = "", shortArg = ""; + + switch (myArgumentSpecifier) { + case OPTIONAL: + longArg = "[=]"; + shortArg = " []"; + break; + + case NONE: + longArg = ""; + shortArg = ""; + break; + + case MANDATORY: + longArg = "="; + shortArg = " "; + break; + } + + buf.append(" --" + myLong + longArg + ", -" + myShort + shortArg + "\n"); + buf.append(" " + myMemo + "\n"); + + return buf.toString(); + } + + public boolean proceed(final Cursor cursor, final Callback callback) { + if (cursor.endOf()) return false; + + final String arg = cursor.look(); + + if (!arg.startsWith("-")) { + callback.addFree(arg); + cursor.shift(); + return true; + } + + if (myShort != null && arg.equals("-" + myShort)) { + switch (myArgumentSpecifier) { + case NONE: + callback.update(myKey, SWITCH); + break; + + default: + if (cursor.nextIsArg()) { + callback.update(myKey, new Value(cursor.lookahead())); + } + else { + switch (myArgumentSpecifier) { case OPTIONAL: - longArg = "[=]"; - shortArg = " []"; - break; - - case NONE: - longArg = ""; - shortArg = ""; - break; - + callback.update(myKey, SWITCH); + break; case MANDATORY: - longArg = "="; - shortArg = " "; - break; - } - - buf.append(" --" + myLong + longArg + ", -" + myShort + shortArg + "\n"); - buf.append(" " + myMemo + "\n"); - - return buf.toString(); - } - - public boolean proceed (final Cursor cursor, final Callback callback) { - if (cursor.endOf()) - return false; - - final String arg = cursor.look(); - - if (! arg.startsWith("-")) { - callback.addFree(arg); - cursor.shift(); - return true; - } - - if (myShort != null && arg.equals("-" + myShort)) { - switch (myArgumentSpecifier) { - case NONE: - callback.update(myKey, SWITCH); - break; - - default: - if (cursor.nextIsArg()) - callback.update(myKey, new Value(cursor.lookahead())); - else - switch (myArgumentSpecifier) { - case OPTIONAL: - callback.update(myKey, SWITCH); - break; - case MANDATORY: - callback.report("option \"" + arg + "\" requires an argument, discarding."); - } - }; - - cursor.shift(); - return true; - } - - final Matcher m = myLongPattern.matcher(arg); - - if (myLong != null && m.matches()) { - final String prm = m.group(2); - - switch (myArgumentSpecifier) { - case MANDATORY: - if (prm == null) - callback.report("option \"" + arg + "\" requires an argument, discarding."); - else - callback.update(myKey, new Value (prm)); - break; - - case NONE: - if (prm == null) - callback.update(myKey, SWITCH); - else - callback.report("option \"" + arg + "\" does not take an argument, omitting."); - break; - - case OPTIONAL: - callback.update(myKey, prm == null ? SWITCH : new Value(prm)); - break; - } - - cursor.shift(); - return true; - } - - return false; - } - } - - private Map myOptions = new HashMap (); - private List myFree; - - private final Descriptor[] myDescriptors; - - Options (final Descriptor[] descrs) { - myDescriptors = descrs; - } - - public List parse (final String[] args) { - myOptions.clear(); - myFree = new ArrayList (); - final List notes = new ArrayList (); - final Callback cb = new Callback() { - public void addFree (final String value) { - myFree.add(value); - } - public void update (final String key, final Argument value) { - myOptions.put(key, value); - } - public void report (final String note) { - notes.add(note); - } - }; - final Cursor cursor = new Cursor(args); - - while (!cursor.endOf()) { - boolean recognized = false; - - for (int i = 0; i myOptions = new HashMap(); + private List myFree; + + private final Descriptor[] myDescriptors; + + Options(final Descriptor[] descrs) { + myDescriptors = descrs; + } + + public List parse(final String[] args) { + myOptions.clear(); + myFree = new ArrayList(); + final List notes = new ArrayList(); + final Callback cb = new Callback() { + public void addFree(final String value) { + myFree.add(value); + } + + public void update(final String key, final Argument value) { + myOptions.put(key, value); + } + + public void report(final String note) { + notes.add(note); + } + }; + final Cursor cursor = new Cursor(args); + + while (!cursor.endOf()) { + boolean recognized = false; + + for (int i = 0; i < myDescriptors.length; i++) { + recognized |= myDescriptors[i].proceed(cursor, cb); + } + + if (!recognized) { + cb.report("unrecognized option \"" + cursor.look() + "\" omitted."); + cursor.shift(); + } } - public Argument get (final String name) { - return myOptions.get(name); - } + return notes; + } - public List getFree () { - return myFree; - } + public Argument get(final String name) { + return myOptions.get(name); + } - public String memo () { + public List getFree() { + return myFree; + } + + public String memo() { final StringBuilder buf = new StringBuilder(); for (final Descriptor descriptor : myDescriptors) { diff --git a/jps/src/org/jetbrains/ether/Pair.java b/jps/src/org/jetbrains/ether/Pair.java index f852c5876573..0baef4fd92bc 100644 --- a/jps/src/org/jetbrains/ether/Pair.java +++ b/jps/src/org/jetbrains/ether/Pair.java @@ -8,31 +8,31 @@ package org.jetbrains.ether; * To change this template use File | Settings | File Templates. */ public class Pair { - public final X fst; - public final Y snd; + public final X fst; + public final Y snd; - public Pair(final X fst, final Y snd) { - this.fst = fst; - this.snd = snd; - } + public Pair(final X fst, final Y snd) { + this.fst = fst; + this.snd = snd; + } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; - Pair pair = (Pair) o; + Pair pair = (Pair)o; - if (!fst.equals(pair.fst)) return false; - if (!snd.equals(pair.snd)) return false; + if (!fst.equals(pair.fst)) return false; + if (!snd.equals(pair.snd)) return false; - return true; - } + return true; + } - @Override - public int hashCode() { - int result = fst.hashCode(); - result = 31 * result + snd.hashCode(); - return result; - } + @Override + public int hashCode() { + int result = fst.hashCode(); + result = 31 * result + snd.hashCode(); + return result; + } } diff --git a/jps/src/org/jetbrains/ether/ProjectWrapper.java b/jps/src/org/jetbrains/ether/ProjectWrapper.java index 9a69d7f12c09..b277658e6152 100644 --- a/jps/src/org/jetbrains/ether/ProjectWrapper.java +++ b/jps/src/org/jetbrains/ether/ProjectWrapper.java @@ -1186,7 +1186,8 @@ public class ProjectWrapper { compiledFiles.addAll(filesToCompile); affectedFiles.removeAll(filesToCompile); - final boolean incremental = dependencyMapping.differentiate(delta, removed, filesToCompile, compiledFiles, affectedFiles, safeFiles); + final boolean incremental = + dependencyMapping.differentiate(delta, removed, filesToCompile, compiledFiles, affectedFiles, safeFiles); dependencyMapping.integrate(delta, removed); diff --git a/jps/src/org/jetbrains/ether/RW.java b/jps/src/org/jetbrains/ether/RW.java index 2d9999ca9d32..aaf2faf84688 100644 --- a/jps/src/org/jetbrains/ether/RW.java +++ b/jps/src/org/jetbrains/ether/RW.java @@ -14,210 +14,218 @@ import java.util.Collection; */ public class RW { - public interface Writable { - public void write(BufferedWriter w); + public interface Writable { + public void write(BufferedWriter w); + } + + public static void writeln(final BufferedWriter w, final Collection c, final ToWritable t) { + if (c == null) { + writeln(w, "0"); + return; } - public static void writeln(final BufferedWriter w, final Collection c, final ToWritable t) { - if (c == null) { - writeln(w, "0"); - return; - } + writeln(w, Integer.toString(c.size())); - writeln(w, Integer.toString(c.size())); + for (T e : c) { + t.convert(e).write(w); + } + } - for (T e : c) { - t.convert(e).write(w); - } + public static void writeEncodedString(final BufferedWriter w, final String val) { + final int size = val == null ? 0 : val.length(); + + writeln(w, Integer.toString(size)); + + for (int i = 0; i < size; i++) { + writeln(w, Integer.toString((int)val.charAt(i))); + } + } + + public static void writeln(final BufferedWriter w, final Collection c) { + if (c == null) { + writeln(w, "0"); + return; } - public static void writeEncodedString(final BufferedWriter w, final String val) { - final int size = val == null ? 0 : val.length(); + writeln(w, Integer.toString(c.size())); - writeln(w, Integer.toString(size)); + for (Writable e : c) { + e.write(w); + } + } - for (int i = 0; i < size; i++) { - writeln(w, Integer.toString((int) val.charAt(i))); - } + public interface ToWritable { + public Writable convert(T x); + } + + public static void writeln(final BufferedWriter w, final T[] c, final ToWritable t) { + if (c == null) { + writeln(w, "0"); + return; } - public static void writeln(final BufferedWriter w, final Collection c) { - if (c == null) { - writeln(w, "0"); - return; - } + writeln(w, Integer.toString(c.length)); - writeln(w, Integer.toString(c.size())); + for (int i = 0; i < c.length; i++) { + t.convert(c[i]).write(w); + } + } - for (Writable e : c) { - e.write(w); - } + public static void writeln(final BufferedWriter w, final T[] c) { + if (c == null) { + writeln(w, "0"); + return; } - public interface ToWritable { - public Writable convert(T x); + writeln(w, Integer.toString(c.length)); + + for (int i = 0; i < c.length; i++) { + c[i].write(w); + } + } + + public static void writeln(final BufferedWriter w, final String s) { + try { + if (s == null) { + w.write(""); + } + else { + w.write(s); + } + w.newLine(); + } + catch (IOException e) { + e.printStackTrace(); + } + } + + public interface Reader { + public T read(BufferedReader r); + } + + public static ToWritable fromString = new ToWritable() { + public Writable convert(final String s) { + return new Writable() { + public void write(BufferedWriter w) { + writeln(w, s); + } + }; + } + }; + + public static ToWritable fromWritable = new ToWritable() { + public Writable convert(final Writable w) { + return w; + } + }; + + public static Reader myStringReader = new Reader() { + public String read(final BufferedReader r) { + try { + return r.readLine(); + } + catch (IOException e) { + e.printStackTrace(); + return null; + } + } + }; + + public static Collection readMany(final BufferedReader r, final Reader c, final Collection acc) { + final int size = readInt(r); + + for (int i = 0; i < size; i++) { + acc.add(c.read(r)); } - public static void writeln(final BufferedWriter w, final T[] c, final ToWritable t) { - if (c == null) { - writeln(w, "0"); - return; - } + return acc; + } - writeln(w, Integer.toString(c.length)); + public static String lookString(final BufferedReader r) { + try { + r.mark(256); + final String s = r.readLine(); + r.reset(); - for (int i = 0; i < c.length; i++) { - t.convert(c[i]).write(w); - } + return s; + } + catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + public static void readTag(final BufferedReader r, final String tag) { + try { + final String s = r.readLine(); + + if (!s.equals(tag)) System.err.println("Parsing error: expected \"" + tag + "\", but found \"" + s + "\""); + } + catch (IOException e) { + e.printStackTrace(); + } + } + + public static String readString(final BufferedReader r) { + try { + return r.readLine(); + } + catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + public static String readEncodedString(final BufferedReader r) { + final StringBuilder b = new StringBuilder(); + + final int size = readInt(r); + + for (int i = 0; i < size; i++) { + final int c = readInt(r); + b.append((char)c); } - public static void writeln(final BufferedWriter w, final T[] c) { - if (c == null) { - writeln(w, "0"); - return; - } + return b.toString(); + } - writeln(w, Integer.toString(c.length)); + public static long readLong(final BufferedReader r) { + final String s = readString(r); - for (int i = 0; i < c.length; i++) { - c[i].write(w); - } - } - - public static void writeln(final BufferedWriter w, final String s) { - try { - if (s == null) - w.write(""); - else - w.write(s); - w.newLine(); - } catch (IOException e) { - e.printStackTrace(); - } + try { + return Long.parseLong(s); } - - public interface Reader { - public T read(BufferedReader r); + catch (Exception n) { + System.err.println("Parsing error: expected long, but found \"" + s + "\""); + return 0; } + } - public static ToWritable fromString = new ToWritable() { - public Writable convert(final String s) { - return new Writable() { - public void write(BufferedWriter w) { - writeln(w, s); - } - }; - } - }; + public static int readInt(final BufferedReader r) { + final String s = readString(r); - public static ToWritable fromWritable = new ToWritable() { - public Writable convert(final Writable w) { - return w; - } - }; - - public static Reader myStringReader = new Reader() { - public String read(final BufferedReader r) { - try { - return r.readLine(); - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } - }; - - public static Collection readMany(final BufferedReader r, final Reader c, final Collection acc) { - final int size = readInt(r); - - for (int i = 0; i < size; i++) { - acc.add(c.read(r)); - } - - return acc; + try { + return Integer.parseInt(s); } - - public static String lookString(final BufferedReader r) { - try { - r.mark(256); - final String s = r.readLine(); - r.reset(); - - return s; - } catch (IOException e) { - e.printStackTrace(); - return null; - } + catch (Exception n) { + System.err.println("Parsing error: expected integer, but found \"" + s + "\""); + return 0; } + } - public static void readTag(final BufferedReader r, final String tag) { - try { - final String s = r.readLine(); + public static String readStringAttribute(final BufferedReader r, final String tag) { + try { + final String s = r.readLine(); - if (!s.equals(tag)) - System.err.println("Parsing error: expected \"" + tag + "\", but found \"" + s + "\""); - } catch (IOException e) { - e.printStackTrace(); - } + if (s.startsWith(tag)) return s.substring(tag.length()); + + System.err.println("Parsing error: expected \"" + tag + "\", but found \"" + s + "\""); + + return null; } - - public static String readString(final BufferedReader r) { - try { - return r.readLine(); - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } - - public static String readEncodedString(final BufferedReader r) { - final StringBuilder b = new StringBuilder(); - - final int size = readInt(r); - - for (int i = 0; i < size; i++) { - final int c = readInt(r); - b.append((char) c); - } - - return b.toString(); - } - - public static long readLong(final BufferedReader r) { - final String s = readString(r); - - try { - return Long.parseLong(s); - } catch (Exception n) { - System.err.println("Parsing error: expected long, but found \"" + s + "\""); - return 0; - } - } - - public static int readInt(final BufferedReader r) { - final String s = readString(r); - - try { - return Integer.parseInt(s); - } catch (Exception n) { - System.err.println("Parsing error: expected integer, but found \"" + s + "\""); - return 0; - } - } - - public static String readStringAttribute(final BufferedReader r, final String tag) { - try { - final String s = r.readLine(); - - if (s.startsWith(tag)) - return s.substring(tag.length()); - - System.err.println("Parsing error: expected \"" + tag + "\", but found \"" + s + "\""); - - return null; - } catch (IOException e) { - e.printStackTrace(); - return null; - } + catch (IOException e) { + e.printStackTrace(); + return null; } + } } diff --git a/jps/src/org/jetbrains/ether/Reporter.java b/jps/src/org/jetbrains/ether/Reporter.java index e828f899a273..697b6e4163e1 100644 --- a/jps/src/org/jetbrains/ether/Reporter.java +++ b/jps/src/org/jetbrains/ether/Reporter.java @@ -2,7 +2,9 @@ package org.jetbrains.ether; import org.jetbrains.jps.Module; -import java.io.*; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; /** * Created by IntelliJ IDEA. @@ -12,91 +14,88 @@ import java.io.*; * To change this template use File | Settings | File Templates. */ public class Reporter { - public static final String myOkFlag = ".jps.ok"; - public static final String myFailFlag = ".jps.fail"; + public static final String myOkFlag = ".jps.ok"; + public static final String myFailFlag = ".jps.fail"; - private static String getSafePath (final String path) { - final File f = new File(path); + private static String getSafePath(final String path) { + final File f = new File(path); - if (! f.exists()) { - f.mkdir(); - } - - return path; + if (!f.exists()) { + f.mkdir(); } - private static String getOkFlag(final Module m) { - final String outputPath = m.getOutputPath(); + return path; + } - if (outputPath == null) - return null; + private static String getOkFlag(final Module m) { + final String outputPath = m.getOutputPath(); - return getSafePath (outputPath) + File.separator + myOkFlag; + if (outputPath == null) return null; + + return getSafePath(outputPath) + File.separator + myOkFlag; + } + + private static String getFailFlag(final Module m) { + final String outputPath = m.getOutputPath(); + + if (outputPath == null) return null; + + return getSafePath(outputPath) + File.separator + myFailFlag; + } + + private static String getOkTestFlag(final Module m) { + final String testOutputPath = m.getTestOutputPath(); + + if (testOutputPath == null) return null; + + return getSafePath(testOutputPath) + File.separator + myOkFlag; + } + + private static String getFailTestFlag(final Module m) { + final String testOutputPath = m.getTestOutputPath(); + + if (testOutputPath == null) { + return null; } - private static String getFailFlag(final Module m) { - final String outputPath = m.getOutputPath(); + return getSafePath(testOutputPath) + File.separator + myFailFlag; + } - if (outputPath == null) - return null; + private static void write(final String name, final String contents) { + if (name == null) return; + + try { + final File file = new File(name); + final String path = file.getParent(); + + new File(path).mkdirs(); + + final FileWriter writer = new FileWriter(name); + + writer.write(contents); + writer.close(); - return getSafePath (outputPath) + File.separator + myFailFlag; } - - private static String getOkTestFlag(final Module m) { - final String testOutputPath = m.getTestOutputPath(); - - if (testOutputPath == null) - return null; - - return getSafePath (testOutputPath) + File.separator + myOkFlag; + catch (IOException e) { + throw new RuntimeException(e); } + } - private static String getFailTestFlag(final Module m) { - final String testOutputPath = m.getTestOutputPath(); - - if (testOutputPath == null) { - return null; - } - - return getSafePath(testOutputPath) + File.separator + myFailFlag; + public static void reportBuildSuccess(final Module m, final boolean tests) { + if (tests) { + write(getOkTestFlag(m), "dummy"); } - - private static void write(final String name, final String contents) { - if (name == null) - return; - - try { - final File file = new File (name); - final String path = file.getParent(); - - new File (path).mkdirs(); - - final FileWriter writer = new FileWriter(name); - - writer.write(contents); - writer.close(); - - } catch (IOException e) { - throw new RuntimeException(e); - } + else { + write(getOkFlag(m), "dummy"); } + } - public static void reportBuildSuccess(final Module m, final boolean tests) { - if (tests) { - write(getOkTestFlag(m), "dummy"); - } - else { - write(getOkFlag(m), "dummy"); - } + public static void reportBuildFailure(final Module m, final boolean tests, final String reason) { + if (tests) { + write(getFailTestFlag(m), reason); } - - public static void reportBuildFailure(final Module m, final boolean tests, final String reason) { - if (tests) { - write(getFailTestFlag(m), reason); - } - else { - write(getFailFlag(m), reason); - } + else { + write(getFailFlag(m), reason); } + } } diff --git a/jps/src/org/jetbrains/ether/dependencyView/AntListener.java b/jps/src/org/jetbrains/ether/dependencyView/AntListener.java index 9418197130a5..ee921a7d86eb 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/AntListener.java +++ b/jps/src/org/jetbrains/ether/dependencyView/AntListener.java @@ -22,282 +22,286 @@ import java.util.regex.Pattern; * To change this template use File | Settings | File Templates. */ public class AntListener implements BuildListener { - private static final Pattern read = Pattern.compile("\\[parsing started (.*)\\]"); - private static final Pattern written = Pattern.compile("\\[wrote (.*)\\]"); + private static final Pattern read = Pattern.compile("\\[parsing started (.*)\\]"); + private static final Pattern written = Pattern.compile("\\[wrote (.*)\\]"); - private final Map> readFiles = new HashMap>(); - private final Map> writtenFiles = new HashMap>(); - private final String targetFolder; - private final int stripLength; - private final List sourceRoots; - private final Callbacks.Backend callback; + private final Map> readFiles = new HashMap>(); + private final Map> writtenFiles = new HashMap>(); + private final String targetFolder; + private final int stripLength; + private final List sourceRoots; + private final Callbacks.Backend callback; - private static String basename(final String name, final String extension) { - return name.substring(0, name.length() - extension.length()); + private static String basename(final String name, final String extension) { + return name.substring(0, name.length() - extension.length()); + } + + private static ClassReader getClassReader(final String fullName) { + try { + final File f = new File(fullName); + final byte[] buffer = new byte[(int)f.length()]; + final FileInputStream i = new FileInputStream(f); + + final int n = i.read(buffer); + + i.close(); + + assert ((int)f.length() == n); + + return new ClassReader(buffer); + } + catch (IOException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + return null; + } + } + + private class ClassFileInfo { + final String packageName; + final String fullName; + List subClasses = null; + + public ClassFileInfo(final String fullName, final String packageName) { + this.packageName = packageName; + this.fullName = fullName; } - private static ClassReader getClassReader(final String fullName) { - try { - final File f = new File(fullName); - final byte[] buffer = new byte[(int) f.length()]; - final FileInputStream i = new FileInputStream(f); + public void attachSubClass(final String name) { + if (subClasses == null) { + subClasses = new LinkedList(); + } - final int n = i.read(buffer); - - i.close(); - - assert ((int) f.length() == n); - - return new ClassReader(buffer); - } catch (IOException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - return null; - } + subClasses.add(name); } - private class ClassFileInfo { - final String packageName; - final String fullName; - List subClasses = null; + public String getFullName() { + return fullName; + } - public ClassFileInfo(final String fullName, final String packageName) { - this.packageName = packageName; - this.fullName = fullName; + public String getPackageName() { + return packageName; + } + + public String toString() { + final StringBuilder builder = new StringBuilder(); + + builder.append(" Root: ").append(fullName).append(", package ").append(packageName).append("\n"); + builder.append(" Subclasses:"); + + if (subClasses != null) { + for (String s : subClasses) { + builder.append(" ").append(s); + } + } + + builder.append(".\n"); + + return builder.toString(); + } + + public void associate(final Callbacks.SourceFileNameLookup sourceFileNameLookup) { + if (callback != null) { + callback.associate(fullName, sourceFileNameLookup, getClassReader(fullName)); + + if (subClasses != null) { + for (String s : subClasses) { + callback.associate(s, sourceFileNameLookup, getClassReader(s)); + } + } + } + } + } + + public AntListener(final String targetFolder, final List sourceRoots, final Callbacks.Backend callback) { + this.targetFolder = targetFolder; + this.sourceRoots = sourceRoots; + this.callback = callback; + stripLength = targetFolder.length() + 1; + } + + public void buildStarted(BuildEvent event) { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void buildFinished(BuildEvent event) { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void targetStarted(BuildEvent event) { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void targetFinished(BuildEvent event) { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void taskStarted(BuildEvent event) { + } + + public void taskFinished(BuildEvent event) { + if (event.getTask().getTaskName().equals("javac")) { + for (Map.Entry> e : writtenFiles.entrySet()) { + final String className = e.getKey(); + + final List infos = e.getValue(); + final List read = readFiles.get(className); + + if (infos.size() == 1 && read != null && read.size() == 1) { + infos.get(0).associate(Callbacks.getDefaultLookup(read.get(0))); + continue; } - public void attachSubClass(final String name) { - if (subClasses == null) { - subClasses = new LinkedList(); - } + process: + for (ClassFileInfo c : infos) { + final String packageName = c.getPackageName(); - subClasses.add(name); - } + final Callbacks.SourceFileNameLookup sourceNameLookup = new Callbacks.SourceFileNameLookup() { + public String get(final String sourceAttribute) { - public String getFullName() { - return fullName; - } + assert (sourceAttribute != null); - public String getPackageName() { - return packageName; - } + final String className = basename(sourceAttribute, ".java"); + final List candidates = readFiles.get(className); - public String toString() { - final StringBuilder builder = new StringBuilder(); + assert (candidates != null); - builder.append(" Root: ").append(fullName).append(", package ").append(packageName).append("\n"); - builder.append(" Subclasses:"); + if (candidates.size() == 1) { + return candidates.get(0); + } - if (subClasses != null) - for (String s : subClasses) { - builder.append(" ").append(s); + for (String r : candidates) { + if (new PackageNameSelector().get(r).equals(packageName)) { + return r; } + } - builder.append(".\n"); + assert (false); - return builder.toString(); + return null; + } + }; + + c.associate(sourceNameLookup); } + } - public void associate(final Callbacks.SourceFileNameLookup sourceFileNameLookup) { - if (callback != null) { - callback.associate(fullName, sourceFileNameLookup, getClassReader(fullName)); + /* + System.out.println("Written files info:"); - if (subClasses != null) { - for (String s : subClasses) { - callback.associate(s, sourceFileNameLookup, getClassReader(s)); - } - } - } + for (Map.Entry> e : writtenFiles.entrySet()) { + final String className = e.getKey(); + final List infos = e.getValue(); + + System.out.println(" Class name: " + className); + System.out.println(" Class file info(s): "); + + for (ClassFileInfo c : infos) { + System.out.println(c.toString()); + } + } + + System.out.println("End."); + + System.out.println("Read files info:"); + + for (Map.Entry> e : readFiles.entrySet()) { + final String className = e.getKey(); + final List files = e.getValue(); + + System.out.println(" Class name: " + className); + System.out.print(" Files:"); + + for (String file : files) { + System.out.print(" " + file); + } + + System.out.println("."); + } + System.out.println("End."); + */ + } + } + + private String extractPackage(final String s) { + if (s.length() < stripLength) return ""; + + return s.substring(stripLength); + } + + public void messageLogged(BuildEvent event) { + final String m = event.getMessage(); + final Matcher writtenMatcher = written.matcher(m); + final Matcher readMatcher = read.matcher(m); + + if (writtenMatcher.matches()) { + final String fullName = writtenMatcher.group(1); + final File file = new File(fullName); + + final String classFileName = file.getName(); + final String packageName = extractPackage(fullName.substring(0, fullName.length() - classFileName.length() - 1)); + + String className = basename(classFileName, ".class"); + boolean subClass = false; + + final int i = className.indexOf('$'); + + if (i >= 0) { + className = className.substring(0, i); + subClass = true; + } + + List info = writtenFiles.get(className); + + + if (info == null) { + info = new LinkedList(); + writtenFiles.put(className, info); + } + + boolean updated = false; + + for (ClassFileInfo ci : info) { + if (subClass) { + if (ci.getPackageName().equals(packageName)) { + ci.attachSubClass(fullName); + updated = true; + } } - } - - public AntListener(final String targetFolder, final List sourceRoots, final Callbacks.Backend callback) { - this.targetFolder = targetFolder; - this.sourceRoots = sourceRoots; - this.callback = callback; - stripLength = targetFolder.length() + 1; - } - - public void buildStarted(BuildEvent event) { - //To change body of implemented methods use File | Settings | File Templates. - } - - public void buildFinished(BuildEvent event) { - //To change body of implemented methods use File | Settings | File Templates. - } - - public void targetStarted(BuildEvent event) { - //To change body of implemented methods use File | Settings | File Templates. - } - - public void targetFinished(BuildEvent event) { - //To change body of implemented methods use File | Settings | File Templates. - } - - public void taskStarted(BuildEvent event) { - } - - public void taskFinished(BuildEvent event) { - if (event.getTask().getTaskName().equals("javac")) { - for (Map.Entry> e : writtenFiles.entrySet()) { - final String className = e.getKey(); - - final List infos = e.getValue(); - final List read = readFiles.get(className); - - if (infos.size() == 1 && read != null && read.size() == 1) { - infos.get(0).associate(Callbacks.getDefaultLookup(read.get(0))); - continue; - } - - process: - for (ClassFileInfo c : infos) { - final String packageName = c.getPackageName(); - - final Callbacks.SourceFileNameLookup sourceNameLookup = new Callbacks.SourceFileNameLookup() { - public String get(final String sourceAttribute) { - - assert (sourceAttribute != null); - - final String className = basename(sourceAttribute, ".java"); - final List candidates = readFiles.get(className); - - assert (candidates != null); - - if (candidates.size() == 1) { - return candidates.get(0); - } - - for (String r : candidates) { - if (new PackageNameSelector().get(r).equals(packageName)) { - return r; - } - } - - assert (false); - - return null; - } - }; - - c.associate(sourceNameLookup); - } - } - - /* - System.out.println("Written files info:"); - - for (Map.Entry> e : writtenFiles.entrySet()) { - final String className = e.getKey(); - final List infos = e.getValue(); - - System.out.println(" Class name: " + className); - System.out.println(" Class file info(s): "); - - for (ClassFileInfo c : infos) { - System.out.println(c.toString()); - } - } - - System.out.println("End."); - - System.out.println("Read files info:"); - - for (Map.Entry> e : readFiles.entrySet()) { - final String className = e.getKey(); - final List files = e.getValue(); - - System.out.println(" Class name: " + className); - System.out.print(" Files:"); - - for (String file : files) { - System.out.print(" " + file); - } - - System.out.println("."); - } - System.out.println("End."); - */ + else { + if (ci.getFullName().equals(fullName)) { + updated = true; + break; + } } - } + } - private String extractPackage(final String s) { - if (s.length() < stripLength) - return ""; - - return s.substring(stripLength); - } - - public void messageLogged(BuildEvent event) { - final String m = event.getMessage(); - final Matcher writtenMatcher = written.matcher(m); - final Matcher readMatcher = read.matcher(m); - - if (writtenMatcher.matches()) { - final String fullName = writtenMatcher.group(1); - final File file = new File(fullName); - - final String classFileName = file.getName(); - final String packageName = extractPackage(fullName.substring(0, fullName.length() - classFileName.length() - 1)); - - String className = basename(classFileName, ".class"); - boolean subClass = false; - - final int i = className.indexOf('$'); - - if (i >= 0) { - className = className.substring(0, i); - subClass = true; - } - - List info = writtenFiles.get(className); - - - if (info == null) { - info = new LinkedList(); - writtenFiles.put(className, info); - } - - boolean updated = false; - - for (ClassFileInfo ci : info) { - if (subClass) { - if (ci.getPackageName().equals(packageName)) { - ci.attachSubClass(fullName); - updated = true; - } - } else { - if (ci.getFullName().equals(fullName)) { - updated = true; - break; - } - } - } - - if (!updated) { - if (subClass) { - final ClassFileInfo c = new ClassFileInfo(targetFolder + File.separator + packageName + File.separator + className + ".class", packageName); - c.attachSubClass(fullName); - info.add(c); - } else { - info.add(new ClassFileInfo(fullName, packageName)); - } - } + if (!updated) { + if (subClass) { + final ClassFileInfo c = + new ClassFileInfo(targetFolder + File.separator + packageName + File.separator + className + ".class", packageName); + c.attachSubClass(fullName); + info.add(c); } - - if (readMatcher.matches()) { - final String fullName = readMatcher.group(1); - final File file = new File(fullName); - final String sourceFileName = file.getName(); - final String className = basename(sourceFileName, ".java"); - - List files = readFiles.get(className); - - if (files == null) { - files = new LinkedList(); - readFiles.put(className, files); - } - - files.add(fullName); + else { + info.add(new ClassFileInfo(fullName, packageName)); } + } } + + if (readMatcher.matches()) { + final String fullName = readMatcher.group(1); + final File file = new File(fullName); + final String sourceFileName = file.getName(); + final String className = basename(sourceFileName, ".java"); + + List files = readFiles.get(className); + + if (files == null) { + files = new LinkedList(); + readFiles.put(className, files); + } + + files.add(fullName); + } + } } diff --git a/jps/src/org/jetbrains/ether/dependencyView/Callbacks.java b/jps/src/org/jetbrains/ether/dependencyView/Callbacks.java index c5b0fc5f4033..f89f05e6514a 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/Callbacks.java +++ b/jps/src/org/jetbrains/ether/dependencyView/Callbacks.java @@ -14,22 +14,27 @@ import java.util.Set; * To change this template use File | Settings | File Templates. */ public class Callbacks { - public interface SourceFileNameLookup { - String get(String sourceAttribute); - } + public interface SourceFileNameLookup { + String get(String sourceAttribute); + } - public static SourceFileNameLookup getDefaultLookup(final String name) { - return new SourceFileNameLookup() { - public String get(final String sourceAttribute) { - return name; - } - }; - } + public static SourceFileNameLookup getDefaultLookup(final String name) { + return new SourceFileNameLookup() { + public String get(final String sourceAttribute) { + return name; + } + }; + } - public interface Backend { - Collection getClassFiles(); - void associate(String classFileName, SourceFileNameLookup sourceLookup, ClassReader cr); - void associate(Set>> classes, Pair> usages, String sourceFileName); - void associateForm(StringCache.S formName, StringCache.S className); - } + public interface Backend { + Collection getClassFiles(); + + void associate(String classFileName, SourceFileNameLookup sourceLookup, ClassReader cr); + + void associate(Set>> classes, + Pair> usages, + String sourceFileName); + + void associateForm(StringCache.S formName, StringCache.S className); + } } diff --git a/jps/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java b/jps/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java index c17057217ad7..57e01c94dd92 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java +++ b/jps/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java @@ -1,6 +1,5 @@ package org.jetbrains.ether.dependencyView; -import com.sun.org.apache.bcel.internal.generic.PUTFIELD; import org.jetbrains.ether.Pair; import org.objectweb.asm.*; import org.objectweb.asm.commons.EmptyVisitor; diff --git a/jps/src/org/jetbrains/ether/dependencyView/Difference.java b/jps/src/org/jetbrains/ether/dependencyView/Difference.java index 7d5bb2208255..4746cf7c0aca 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/Difference.java +++ b/jps/src/org/jetbrains/ether/dependencyView/Difference.java @@ -12,104 +12,107 @@ import java.util.*; * To change this template use File | Settings | File Templates. */ public abstract class Difference { - public static final int NONE = 0; - public static final int ACCESS = 1; - public static final int TYPE = 2; - public static final int VALUE = 4; - public static final int SIGNATURE = 8; - public static final int SUPERCLASS = 16; + public static final int NONE = 0; + public static final int ACCESS = 1; + public static final int TYPE = 2; + public static final int VALUE = 4; + public static final int SIGNATURE = 8; + public static final int SUPERCLASS = 16; - public interface Specifier { - public Collection added(); + public interface Specifier { + public Collection added(); - public Collection removed(); + public Collection removed(); - public Collection> changed(); + public Collection> changed(); - public boolean unchanged(); + public boolean unchanged(); + } + + public static Specifier make(final Set past, final Set now) { + if (past == null) { + final Collection removed = new HashSet(); + final Collection> changed = new HashSet>(); + + return new Specifier() { + public Collection added() { + return now; + } + + public Collection removed() { + return removed; + } + + public Collection> changed() { + return changed; + } + + public boolean unchanged() { + return false; + } + }; } - public static Specifier make(final Set past, final Set now) { - if (past == null) { - final Collection removed = new HashSet(); - final Collection> changed = new HashSet>(); + final Set added = new HashSet(now); - return new Specifier() { - public Collection added() { - return now; - } + added.removeAll(past); - public Collection removed() { - return removed; - } + final Set removed = new HashSet(past); - public Collection> changed() { - return changed; - } + removed.removeAll(now); - public boolean unchanged() { - return false; - } - }; - } + final Set> changed = new HashSet>(); + final Set intersect = new HashSet(past); + final Map nowMap = new HashMap(); - final Set added = new HashSet(now); - - added.removeAll(past); - - final Set removed = new HashSet(past); - - removed.removeAll(now); - - final Set> changed = new HashSet>(); - final Set intersect = new HashSet(past); - final Map nowMap = new HashMap(); - - for (T s : now) { - if (intersect.contains(s)) { - nowMap.put(s, s); - } - } - - intersect.retainAll(now); - - for (T x : intersect) { - final T y = nowMap.get(x); - - if (x instanceof Proto) { - final Proto px = (Proto) x; - final Proto py = (Proto) y; - final Difference diff = py.difference(px); - - if (!diff.no()) { - changed.add(new Pair(x, diff)); - } - } - } - - return new Specifier() { - public Collection added() { - return added; - } - - public Collection removed() { - return removed; - } - - public Collection> changed() { - return changed; - } - - public boolean unchanged() { - return changed.isEmpty() && added.isEmpty() && removed.isEmpty(); - } - }; + for (T s : now) { + if (intersect.contains(s)) { + nowMap.put(s, s); + } } - public abstract int base(); + intersect.retainAll(now); - public abstract boolean no(); - public abstract int addedModifiers (); - public abstract int removedModifiers (); - public abstract boolean packageLocalOn(); + for (T x : intersect) { + final T y = nowMap.get(x); + + if (x instanceof Proto) { + final Proto px = (Proto)x; + final Proto py = (Proto)y; + final Difference diff = py.difference(px); + + if (!diff.no()) { + changed.add(new Pair(x, diff)); + } + } + } + + return new Specifier() { + public Collection added() { + return added; + } + + public Collection removed() { + return removed; + } + + public Collection> changed() { + return changed; + } + + public boolean unchanged() { + return changed.isEmpty() && added.isEmpty() && removed.isEmpty(); + } + }; + } + + public abstract int base(); + + public abstract boolean no(); + + public abstract int addedModifiers(); + + public abstract int removedModifiers(); + + public abstract boolean packageLocalOn(); } diff --git a/jps/src/org/jetbrains/ether/dependencyView/FieldRepr.java b/jps/src/org/jetbrains/ether/dependencyView/FieldRepr.java index 106492b9c5be..b9de604334fc 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/FieldRepr.java +++ b/jps/src/org/jetbrains/ether/dependencyView/FieldRepr.java @@ -1,10 +1,8 @@ package org.jetbrains.ether.dependencyView; import org.jetbrains.ether.RW; -import org.objectweb.asm.Type; import java.io.BufferedReader; -import java.io.BufferedWriter; import java.util.Set; /** @@ -15,44 +13,44 @@ import java.util.Set; * To change this template use File | Settings | File Templates. */ public class FieldRepr extends ProtoMember { - public void updateClassUsages(final Set s) { - type.updateClassUsages(s); + public void updateClassUsages(final Set s) { + type.updateClassUsages(s); + } + + public FieldRepr(final int a, final String n, final String d, final String s, final Object v) { + super(a, s, StringCache.get(n), TypeRepr.getType(d), v); + } + + public FieldRepr(final BufferedReader r) { + super(r); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final FieldRepr fieldRepr = (FieldRepr)o; + + return name.equals(fieldRepr.name); + } + + @Override + public int hashCode() { + return 31 * name.hashCode(); + } + + public static RW.Reader reader = new RW.Reader() { + public FieldRepr read(final BufferedReader r) { + return new FieldRepr(r); } + }; - public FieldRepr(final int a, final String n, final String d, final String s, final Object v) { - super(a, s, StringCache.get(n), TypeRepr.getType(d), v); - } + public UsageRepr.Usage createUsage(final StringCache.S owner) { + return UsageRepr.createFieldUsage(name.value, owner.value, type.getDescr()); + } - public FieldRepr(final BufferedReader r) { - super(r); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final FieldRepr fieldRepr = (FieldRepr) o; - - return name.equals(fieldRepr.name); - } - - @Override - public int hashCode() { - return 31 * name.hashCode(); - } - - public static RW.Reader reader = new RW.Reader() { - public FieldRepr read(final BufferedReader r) { - return new FieldRepr(r); - } - }; - - public UsageRepr.Usage createUsage (final StringCache.S owner) { - return UsageRepr.createFieldUsage(name.value, owner.value, type.getDescr()); - } - - public UsageRepr.Usage createAssignUsage (final StringCache.S owner) { - return UsageRepr.createFieldAssignUsage(name.value, owner.value, type.getDescr()); - } + public UsageRepr.Usage createAssignUsage(final StringCache.S owner) { + return UsageRepr.createFieldAssignUsage(name.value, owner.value, type.getDescr()); + } } diff --git a/jps/src/org/jetbrains/ether/dependencyView/FoxyMap.java b/jps/src/org/jetbrains/ether/dependencyView/FoxyMap.java index 4d08d94e0817..8711258540ec 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/FoxyMap.java +++ b/jps/src/org/jetbrains/ether/dependencyView/FoxyMap.java @@ -11,122 +11,129 @@ import java.util.*; */ public class FoxyMap implements Map { - public interface CollectionConstructor { - public Collection create(); + public interface CollectionConstructor { + public Collection create(); + } + + private final Map map = new HashMap(); + + private final CollectionConstructor constr; + + public FoxyMap(final CollectionConstructor c) { + constr = c; + } + + public int size() { + return map.size(); + } + + public boolean isEmpty() { + return map.isEmpty(); + } + + public boolean containsKey(final Object key) { + return map.containsKey(key); + } + + public boolean containsValue(final Object value) { + return map.containsValue(value); + } + + public Object get(final Object key) { + return map.get(key); + } + + public Collection foxyGet(final K key) { + final Object c = get(key); + + if (c == null) { + return null; } - private final Map map = new HashMap(); - - private final CollectionConstructor constr; - - public FoxyMap(final CollectionConstructor c) { - constr = c; + if (c instanceof Collection) { + return (Collection)c; } - public int size() { - return map.size(); + final Collection l = constr.create(); + + l.add((V)c); + + return l; + } + + public Object put(final K key, final Object value) { + final Object c = get(key); + + if (c == null) { + map.put(key, value); } + else { + if (c instanceof Collection) { + if (value instanceof Collection) { + ((Collection)c).addAll((Collection)value); + } + else { + ((Collection)c).add(value); + } + } + else { + final Collection d = constr.create(); - public boolean isEmpty() { - return map.isEmpty(); - } + d.add(c); - public boolean containsKey(final Object key) { - return map.containsKey(key); - } - - public boolean containsValue(final Object value) { - return map.containsValue(value); - } - - public Object get(final Object key) { - return map.get(key); - } - - public Collection foxyGet(final K key) { - final Object c = get(key); - - if (c == null) { - return null; + if (value instanceof Collection) { + d.addAll((Collection)value); + } + else { + d.add(value); } - if (c instanceof Collection) { - return (Collection) c; - } - - final Collection l = constr.create(); - - l.add((V) c); - - return l; + map.put(key, d); + } } - public Object put(final K key, final Object value) { - final Object c = get(key); + return c; + } - if (c == null) { - map.put(key, value); - } else { - if (c instanceof Collection) { - if (value instanceof Collection) - ((Collection) c).addAll((Collection) value); - else - ((Collection) c).add(value); - } else { - final Collection d = constr.create(); + public Object remove(final Object key) { + return map.remove(key); + } - d.add(c); + public void putAll(Map m) { + for (Entry e : m.entrySet()) { + remove(e.getKey()); + put(e.getKey(), e.getValue()); + } + } - if (value instanceof Collection) - d.addAll((Collection) value); - else - d.add(value); + public void clear() { + map.clear(); + } - map.put(key, d); - } - } + public Set keySet() { + return map.keySet(); + } - return c; + public Collection values() { + final List l = new LinkedList(); + + for (Object value : map.values()) { + if (value instanceof Collection) { + l.addAll((Collection)value); + } + else { + l.add(value); + } } - public Object remove(final Object key) { - return map.remove(key); - } + return l; + } - public void putAll(Map m) { - for (Entry e : m.entrySet()) { - remove(e.getKey()); - put(e.getKey(), e.getValue()); - } - } + public Collection foxyValues() { + return (Collection)values(); + } - public void clear() { - map.clear(); - } - - public Set keySet() { - return map.keySet(); - } - - public Collection values() { - final List l = new LinkedList(); - - for (Object value : map.values()) { - if (value instanceof Collection) { - l.addAll((Collection) value); - } else { - l.add(value); - } - } - - return l; - } - - public Collection foxyValues() { - return (Collection) values(); - } - - public Set> entrySet() { - return map.entrySet(); - } + public Set> entrySet() { + return map.entrySet(); + } } diff --git a/jps/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/src/org/jetbrains/ether/dependencyView/Mappings.java index d670c464ce23..635fdcc19e63 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -6,9 +6,6 @@ import org.jetbrains.ether.ProjectWrapper; import org.objectweb.asm.ClassReader; import org.objectweb.asm.Opcodes; -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; import java.lang.annotation.ElementType; import java.lang.annotation.RetentionPolicy; import java.util.*; @@ -896,15 +893,14 @@ public class Mappings { } public void associate(final String classFileName, final Callbacks.SourceFileNameLookup sourceFileName, final ClassReader cr) { - final StringCache.S classFileNameS = StringCache.get(project != null? project.getRelativePath(classFileName) : classFileName); + final StringCache.S classFileNameS = StringCache.get(project != null ? project.getRelativePath(classFileName) : classFileName); final Pair>> result = ClassfileAnalyzer.analyze(classFileNameS, cr); final ClassRepr repr = result.fst; final UsageRepr.Cluster localUsages = result.snd.fst; final Set localAnnotationUsages = result.snd.snd; final String srcFileName = sourceFileName.get(repr == null ? null : repr.getSourceFileName().value); - final StringCache.S sourceFileNameS = - StringCache.get(project != null? project.getRelativePath(srcFileName) : srcFileName); + final StringCache.S sourceFileNameS = StringCache.get(project != null ? project.getRelativePath(srcFileName) : srcFileName); for (UsageRepr.Usage u : localUsages.getUsages()) { updateDependency(sourceFileNameS, u.getOwner()); @@ -1019,34 +1015,4 @@ public class Mappings { return null; } - - public void print() { - try { - final BufferedWriter w = new BufferedWriter(new FileWriter("dep.txt")); - for (StringCache.S key : fileToFileDependency.keySet()) { - final Set value = (Set)fileToFileDependency.foxyGet(key); - - w.write(key.value + " -->"); - w.newLine(); - - if (value != null) { - for (StringCache.S s : value) { - if (s == null) { - w.write(" "); - } - else { - w.write(" " + s.value); - } - - w.newLine(); - } - } - } - - w.close(); - } - catch (IOException e) { - e.printStackTrace(); - } - } } diff --git a/jps/src/org/jetbrains/ether/dependencyView/MethodRepr.java b/jps/src/org/jetbrains/ether/dependencyView/MethodRepr.java index bac25e5f4857..ef74c9118702 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/MethodRepr.java +++ b/jps/src/org/jetbrains/ether/dependencyView/MethodRepr.java @@ -18,131 +18,132 @@ import java.util.Set; * To change this template use File | Settings | File Templates. */ public class MethodRepr extends ProtoMember { - private static TypeRepr.AbstractType[] dummyAbstractType = new TypeRepr.AbstractType[0]; + private static TypeRepr.AbstractType[] dummyAbstractType = new TypeRepr.AbstractType[0]; - public final TypeRepr.AbstractType[] argumentTypes; - public final Set exceptions; + public final TypeRepr.AbstractType[] argumentTypes; + public final Set exceptions; - public abstract class Diff extends Difference { - public abstract Specifier exceptions(); - public abstract boolean defaultAdded (); - public abstract boolean defaultRemoved (); - } + public abstract class Diff extends Difference { + public abstract Specifier exceptions(); - @Override - public Difference difference(final Proto past) { - final Difference diff = super.difference(past); - final Difference.Specifier excs = Difference.make(((MethodRepr) past).exceptions, exceptions); + public abstract boolean defaultAdded(); - return new Diff() { - @Override - public int addedModifiers() { - return diff.addedModifiers(); - } + public abstract boolean defaultRemoved(); + } - @Override - public int removedModifiers() { - return diff.removedModifiers(); - } + @Override + public Difference difference(final Proto past) { + final Difference diff = super.difference(past); + final Difference.Specifier excs = Difference.make(((MethodRepr)past).exceptions, exceptions); - @Override - public boolean no() { - return base() == NONE && !defaultAdded() && !defaultRemoved() && excs.unchanged(); - } + return new Diff() { + @Override + public int addedModifiers() { + return diff.addedModifiers(); + } - @Override - public boolean defaultAdded() { - return hasValue() && !((MethodRepr) past).hasValue(); - } + @Override + public int removedModifiers() { + return diff.removedModifiers(); + } - @Override - public boolean defaultRemoved() { - return !hasValue() && ((MethodRepr) past).hasValue(); - } + @Override + public boolean no() { + return base() == NONE && !defaultAdded() && !defaultRemoved() && excs.unchanged(); + } - @Override - public Specifier exceptions() { - return excs; - } + @Override + public boolean defaultAdded() { + return hasValue() && !((MethodRepr)past).hasValue(); + } - @Override - public int base() { - return diff.base(); - } + @Override + public boolean defaultRemoved() { + return !hasValue() && ((MethodRepr)past).hasValue(); + } - @Override - public boolean packageLocalOn() { - return diff.packageLocalOn(); - } - }; - } + @Override + public Specifier exceptions() { + return excs; + } - public void updateClassUsages(final Set s) { - type.updateClassUsages(s); + @Override + public int base() { + return diff.base(); + } - for (int i = 0; i < argumentTypes.length; i++) { - argumentTypes[i].updateClassUsages(s); - } - - if (exceptions != null) - for (TypeRepr.AbstractType typ : exceptions) { - typ.updateClassUsages(s); - } - } - - public MethodRepr(final int a, final String n, final String s, final String d, final String[] e, final Object value) { - super(a, s, StringCache.get(n), TypeRepr.getType(Type.getReturnType(d)), value); - exceptions = (Set) TypeRepr.createClassType(e, new HashSet()); - argumentTypes = TypeRepr.getType(Type.getArgumentTypes(d)); - } - - public MethodRepr(final BufferedReader r) { - super(r); - argumentTypes = RW.readMany(r, TypeRepr.reader, new ArrayList()).toArray(dummyAbstractType); - exceptions = (Set) RW.readMany(r, TypeRepr.reader, new HashSet()); - } - - public void write(final BufferedWriter w) { - super.write(w); - RW.writeln(w, argumentTypes, TypeRepr.fromAbstractType); - RW.writeln(w, exceptions); - } - - public static RW.Reader reader = new RW.Reader() { - public MethodRepr read(final BufferedReader r) { - return new MethodRepr(r); - } + @Override + public boolean packageLocalOn() { + return diff.packageLocalOn(); + } }; + } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public void updateClassUsages(final Set s) { + type.updateClassUsages(s); - final MethodRepr that = (MethodRepr) o; - - return name .equals(that.name ) && - type .equals(that.type) && - Arrays.equals(argumentTypes, that.argumentTypes); + for (int i = 0; i < argumentTypes.length; i++) { + argumentTypes[i].updateClassUsages(s); } - @Override - public int hashCode() { - return 31 * (31 * Arrays.hashCode(argumentTypes) + type.hashCode()) + name.hashCode(); + if (exceptions != null) { + for (TypeRepr.AbstractType typ : exceptions) { + typ.updateClassUsages(s); + } + } + } + + public MethodRepr(final int a, final String n, final String s, final String d, final String[] e, final Object value) { + super(a, s, StringCache.get(n), TypeRepr.getType(Type.getReturnType(d)), value); + exceptions = (Set)TypeRepr.createClassType(e, new HashSet()); + argumentTypes = TypeRepr.getType(Type.getArgumentTypes(d)); + } + + public MethodRepr(final BufferedReader r) { + super(r); + argumentTypes = RW.readMany(r, TypeRepr.reader, new ArrayList()).toArray(dummyAbstractType); + exceptions = (Set)RW.readMany(r, TypeRepr.reader, new HashSet()); + } + + public void write(final BufferedWriter w) { + super.write(w); + RW.writeln(w, argumentTypes, TypeRepr.fromAbstractType); + RW.writeln(w, exceptions); + } + + public static RW.Reader reader = new RW.Reader() { + public MethodRepr read(final BufferedReader r) { + return new MethodRepr(r); + } + }; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final MethodRepr that = (MethodRepr)o; + + return name.equals(that.name) && type.equals(that.type) && Arrays.equals(argumentTypes, that.argumentTypes); + } + + @Override + public int hashCode() { + return 31 * (31 * Arrays.hashCode(argumentTypes) + type.hashCode()) + name.hashCode(); + } + + public UsageRepr.Usage createUsage(final StringCache.S owner) { + final StringBuilder buf = new StringBuilder(); + + buf.append("("); + + for (TypeRepr.AbstractType t : argumentTypes) { + buf.append(t.getDescr()); } - public UsageRepr.Usage createUsage (final StringCache.S owner) { - final StringBuilder buf = new StringBuilder(); + buf.append(")"); + buf.append(type.getDescr()); - buf.append("("); - - for (TypeRepr.AbstractType t : argumentTypes) { - buf.append(t.getDescr()); - } - - buf.append(")"); - buf.append(type.getDescr()); - - return UsageRepr.createMethodUsage(name.value, owner.value, buf.toString()); - } + return UsageRepr.createMethodUsage(name.value, owner.value, buf.toString()); + } } diff --git a/jps/src/org/jetbrains/ether/dependencyView/PackageNameSelector.java b/jps/src/org/jetbrains/ether/dependencyView/PackageNameSelector.java index 26474ad21e39..14a4a837217d 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/PackageNameSelector.java +++ b/jps/src/org/jetbrains/ether/dependencyView/PackageNameSelector.java @@ -13,220 +13,232 @@ import java.io.IOException; * To change this template use File | Settings | File Templates. */ public class PackageNameSelector { - String buffer = null; - int index = 0; - BufferedReader reader = null; - char saved; - boolean isSaved = false; + String buffer = null; + int index = 0; + BufferedReader reader = null; + char saved; + boolean isSaved = false; - private void read() { - try { - buffer = reader.readLine(); - index = 0; - } catch (IOException e) { - e.printStackTrace(); - } + private void read() { + try { + buffer = reader.readLine(); + index = 0; + } + catch (IOException e) { + e.printStackTrace(); + } + } + + private char get() { + if (buffer == null) { + return 0; + } + else if (index == buffer.length()) { + read(); + return '\r'; } - private char get() { - if (buffer == null) { - return 0; - } else if (index == buffer.length()) { - read(); - return '\r'; - } + final char c = buffer.charAt(index++); - final char c = buffer.charAt(index++); - - if (c == 0) { - return ' '; - } - - return c; + if (c == 0) { + return ' '; } - private char symbol() { - if (isSaved) { - isSaved = false; - return saved; - } + return c; + } - final char c = get(); - - switch (c) { - case '"': { - loop: - while (true) { - switch (get()) { - case 0: - return 0; - case '"': - case '\r': - break loop; - case '\\': - switch (get()) { - case 0: - return 0; - case '\r': - break loop; - } - } - } - return ' '; - } - - case '\'': { - loop: - while (true) { - switch (get()) { - case 0: - return 0; - case '\'': - case '\r': - break loop; - case '\\': - switch (get()) { - case 0: - return 0; - case '\r': - break loop; - } - } - } - return ' '; - } - - case '/': { - final char d = get(); - - if (d == '/') { - loop: - while (true) { - switch (get()) { - case 0: - return 0; - case '\r': - break loop; - } - } - return ' '; - } else if (d == '*') { - loop: - while (true) { - switch (get()) { - case 0: - return 0; - case '*': - inner: - while (true) { - switch (get()) { - case 0: - return 0; - - case '/': - break loop; - case '*': - continue; - default: - break inner; - } - } - } - } - return ' '; - } else { - saved = d; - isSaved = true; - return c; - } - } - - default: { - return c; - } - } + private char symbol() { + if (isSaved) { + isSaved = false; + return saved; } - private void open(final String fileName) { - try { - reader = new BufferedReader(new FileReader(new File(fileName))); - read(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private void close() { - try { - if (reader != null) { - reader.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - private String parse() { - final StringBuilder b = new StringBuilder(); - int state = 0; + final char c = get(); + switch (c) { + case '"': { + loop: while (true) { - final char c = symbol(); - switch (c) { - case 0: { - return ""; - } + switch (get()) { + case 0: + return 0; + case '"': + case '\r': + break loop; + case '\\': + switch (get()) { + case 0: + return 0; + case '\r': + break loop; + } + } + } + return ' '; + } - default: { - switch (state) { - case 0: // Initial state - if (Character.isLetter(c)) { - b.append(c); - state = 1; - } - break; + case '\'': { + loop: + while (true) { + switch (get()) { + case 0: + return 0; + case '\'': + case '\r': + break loop; + case '\\': + switch (get()) { + case 0: + return 0; + case '\r': + break loop; + } + } + } + return ' '; + } - case 1: // Identifier - if (Character.isLetter(c)) { - b.append(c); - } else if (Character.isWhitespace(c)) { - final String ident = b.toString(); - b.setLength(0); - if (ident.equals("package")) { - state = 2; - } else if (ident.equals("import")) { - return ""; - } - } else { - state = 0; - } - break; + case '/': { + final char d = get(); - case 2: // Post "package - if (Character.isWhitespace(c)) { + if (d == '/') { + loop: + while (true) { + switch (get()) { + case 0: + return 0; + case '\r': + break loop; + } + } + return ' '; + } + else if (d == '*') { + loop: + while (true) { + switch (get()) { + case 0: + return 0; + case '*': + inner: + while (true) { + switch (get()) { + case 0: + return 0; - } else if (c == '.') { - b.append(File.separatorChar); - } else if (c == ';') { - return b.toString(); - } else { - b.append(c); - } - } + case '/': + break loop; + case '*': + continue; + default: + break inner; + } } } + } + return ' '; } + else { + saved = d; + isSaved = true; + return c; + } + } + + default: { + return c; + } } + } - public String get(final String fileName) { - open(fileName); - - final String result = parse(); - - close(); - - return result; + private void open(final String fileName) { + try { + reader = new BufferedReader(new FileReader(new File(fileName))); + read(); } + catch (IOException e) { + e.printStackTrace(); + } + } + + private void close() { + try { + if (reader != null) { + reader.close(); + } + } + catch (IOException e) { + e.printStackTrace(); + } + } + + private String parse() { + final StringBuilder b = new StringBuilder(); + int state = 0; + + while (true) { + final char c = symbol(); + switch (c) { + case 0: { + return ""; + } + + default: { + switch (state) { + case 0: // Initial state + if (Character.isLetter(c)) { + b.append(c); + state = 1; + } + break; + + case 1: // Identifier + if (Character.isLetter(c)) { + b.append(c); + } + else if (Character.isWhitespace(c)) { + final String ident = b.toString(); + b.setLength(0); + if (ident.equals("package")) { + state = 2; + } + else if (ident.equals("import")) { + return ""; + } + } + else { + state = 0; + } + break; + + case 2: // Post "package + if (Character.isWhitespace(c)) { + + } + else if (c == '.') { + b.append(File.separatorChar); + } + else if (c == ';') { + return b.toString(); + } + else { + b.append(c); + } + } + } + } + } + } + + public String get(final String fileName) { + open(fileName); + + final String result = parse(); + + close(); + + return result; + } // // final private static String whiteSpacePattern = "(/\\*.*?\\*/|//[^\\r\\n\\f\\x0B]*)"; diff --git a/jps/src/org/jetbrains/ether/dependencyView/Proto.java b/jps/src/org/jetbrains/ether/dependencyView/Proto.java index 4c4981571b06..aea00fcab802 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/Proto.java +++ b/jps/src/org/jetbrains/ether/dependencyView/Proto.java @@ -14,76 +14,72 @@ import java.io.BufferedWriter; * To change this template use File | Settings | File Templates. */ public abstract class Proto implements RW.Writable { - public final int access; - public final StringCache.S signature; - public final StringCache.S name; + public final int access; + public final StringCache.S signature; + public final StringCache.S name; - protected Proto(final int access, final String signature, final StringCache.S name) { - this.access = access; - this.signature = StringCache.get(signature != null ? signature : ""); - this.name = name; + protected Proto(final int access, final String signature, final StringCache.S name) { + this.access = access; + this.signature = StringCache.get(signature != null ? signature : ""); + this.name = name; + } + + protected Proto(final BufferedReader r) { + access = RW.readInt(r); + signature = StringCache.get(RW.readString(r)); + name = StringCache.get(RW.readString(r)); + } + + public void write(final BufferedWriter w) { + RW.writeln(w, Integer.toString(access)); + RW.writeln(w, signature.value); + RW.writeln(w, name.value); + } + + public Difference difference(final Proto past) { + int diff = Difference.NONE; + + if (past.access != access) { + diff |= Difference.ACCESS; } - protected Proto (final BufferedReader r) { - access = RW.readInt (r); - signature = StringCache.get(RW.readString(r)); - name = StringCache.get(RW.readString(r)); + if (!past.signature.equals(signature)) { + diff |= Difference.SIGNATURE; } - public void write (final BufferedWriter w) { - RW.writeln(w, Integer.toString (access)); - RW.writeln(w, signature.value); - RW.writeln(w, name.value); - } + final int base = diff; - public Difference difference (final Proto past) { - int diff = Difference.NONE; + return new Difference() { + @Override + public int base() { + return base; + } - if (past.access != access) { - diff |= Difference.ACCESS; - } + @Override + public boolean no() { + return base == Difference.NONE; + } - if (! past.signature.equals(signature)) { - diff |= Difference.SIGNATURE; - } + @Override + public int addedModifiers() { + return ~past.access & access; + } - final int base = diff; + @Override + public int removedModifiers() { + return ~access & past.access; + } - return new Difference() { - @Override - public int base() { - return base; - } + @Override + public boolean packageLocalOn() { + return ((past.access & Opcodes.ACC_PRIVATE) != 0 || + (past.access & Opcodes.ACC_PUBLIC) != 0 || + (past.access & Opcodes.ACC_PROTECTED) != 0) - @Override - public boolean no() { - return base == Difference.NONE; - } + && - @Override - public int addedModifiers() { - return ~past.access & access; - } - - @Override - public int removedModifiers() { - return ~access & past.access; - } - - @Override - public boolean packageLocalOn() { - return - ((past.access & Opcodes.ACC_PRIVATE) != 0 || - (past.access & Opcodes.ACC_PUBLIC) != 0 || - (past.access & Opcodes.ACC_PROTECTED) != 0 - ) - - && - - ((access & Opcodes.ACC_PRIVATE) == 0 && - (access & Opcodes.ACC_PROTECTED) == 0 && - (access & Opcodes.ACC_PUBLIC) == 0); - } - }; - } + ((access & Opcodes.ACC_PRIVATE) == 0 && (access & Opcodes.ACC_PROTECTED) == 0 && (access & Opcodes.ACC_PUBLIC) == 0); + } + }; + } } diff --git a/jps/src/org/jetbrains/ether/dependencyView/ProtoMember.java b/jps/src/org/jetbrains/ether/dependencyView/ProtoMember.java index ccfdfba8824b..f0b35cd934a9 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/ProtoMember.java +++ b/jps/src/org/jetbrains/ether/dependencyView/ProtoMember.java @@ -13,130 +13,135 @@ import java.io.BufferedWriter; * To change this template use File | Settings | File Templates. */ public abstract class ProtoMember extends Proto { - public final TypeRepr.AbstractType type; - public final Object value; + public final TypeRepr.AbstractType type; + public final Object value; - public boolean hasValue () { - return value != null; + public boolean hasValue() { + return value != null; + } + + protected ProtoMember(final int access, + final String signature, + final StringCache.S name, + final TypeRepr.AbstractType t, + final Object value) { + super(access, signature, name); + this.type = t; + this.value = value; + } + + private static Object readTyped(final BufferedReader r, final String tag) { + if (tag.equals("string")) { + return RW.readEncodedString(r); } - protected ProtoMember(final int access, final String signature, final StringCache.S name, final TypeRepr.AbstractType t, final Object value) { - super(access, signature, name); - this.type = t; - this.value = value; + if (tag.equals("none")) { + return null; } - private static Object readTyped(final BufferedReader r, final String tag) { - if (tag.equals("string")) { - return RW.readEncodedString(r); + final String val = RW.readString(r); + + if (tag.equals("integer")) return Integer.parseInt(val); + + if (tag.equals("long")) return Long.parseLong(val); + + if (tag.equals("float")) return Float.parseFloat(val); + + if (tag.equals("double")) return Double.parseDouble(val); + + return null; + } + + protected ProtoMember(final BufferedReader r) { + super(r); + type = TypeRepr.reader.read(r); + value = readTyped(r, RW.readString(r)); + } + + public void write(final BufferedWriter w) { + super.write(w); + type.write(w); + + if (value instanceof String) { + RW.writeln(w, "string"); + RW.writeEncodedString(w, (String)value); + } + else if (value instanceof Integer) { + RW.writeln(w, "integer"); + RW.writeln(w, value.toString()); + } + else if (value instanceof Long) { + RW.writeln(w, "long"); + RW.writeln(w, value.toString()); + } + else if (value instanceof Float) { + RW.writeln(w, "float"); + RW.writeln(w, value.toString()); + } + else if (value instanceof Double) { + RW.writeln(w, "double"); + RW.writeln(w, value.toString()); + } + else { + RW.writeln(w, "none"); + } + } + + public Difference difference(final Proto past) { + final ProtoMember m = (ProtoMember)past; + final Difference diff = super.difference(past); + int base = diff.base(); + + if (!m.type.equals(type)) { + base |= Difference.TYPE; + } + + switch ((value == null ? 0 : 1) + (m.value == null ? 0 : 2)) { + case 3: + if (!value.equals(m.value)) { + base |= Difference.VALUE; } + break; - if (tag.equals("none")) { - return null; - } + case 2: + base |= Difference.VALUE; + break; - final String val = RW.readString(r); + case 1: + base |= Difference.VALUE; + break; - if (tag.equals("integer")) - return Integer.parseInt(val); - - if (tag.equals("long")) - return Long.parseLong(val); - - if (tag.equals("float")) - return Float.parseFloat(val); - - if (tag.equals("double")) - return Double.parseDouble(val); - - return null; + case 0: + break; } - protected ProtoMember(final BufferedReader r) { - super(r); - type = TypeRepr.reader.read(r); - value = readTyped(r, RW.readString(r)); - } + final int newBase = base; - public void write(final BufferedWriter w) { - super.write(w); - type.write(w); + return new Difference() { + @Override + public int base() { + return newBase; + } - if (value instanceof String) { - RW.writeln(w, "string"); - RW.writeEncodedString(w, (String) value); - } else if (value instanceof Integer) { - RW.writeln(w, "integer"); - RW.writeln(w, value.toString()); - } else if (value instanceof Long) { - RW.writeln(w, "long"); - RW.writeln(w, value.toString()); - } else if (value instanceof Float) { - RW.writeln(w, "float"); - RW.writeln(w, value.toString()); - } else if (value instanceof Double) { - RW.writeln(w, "double"); - RW.writeln(w, value.toString()); - } else { - RW.writeln(w, "none"); - } - } + @Override + public boolean no() { + return newBase == Difference.NONE && diff.no(); + } - public Difference difference(final Proto past) { - final ProtoMember m = (ProtoMember) past; - final Difference diff = super.difference(past); - int base = diff.base(); + @Override + public int addedModifiers() { + return diff.addedModifiers(); + } - if (!m.type.equals(type)) { - base |= Difference.TYPE; - } + @Override + public int removedModifiers() { + return diff.removedModifiers(); + } - switch ((value == null ? 0 : 1) + (m.value == null ? 0 : 2)) { - case 3: - if (!value.equals(m.value)) { - base |= Difference.VALUE; - } - break; - - case 2: - base |= Difference.VALUE; - break; - - case 1: - base |= Difference.VALUE; - break; - - case 0: - break; - } - - final int newBase = base; - - return new Difference () { - @Override - public int base() { - return newBase; - } - - @Override - public boolean no() { - return newBase == Difference.NONE && diff.no(); - } - - @Override - public int addedModifiers() { - return diff.addedModifiers(); - } - - @Override - public int removedModifiers() { - return diff.removedModifiers(); - } - - @Override - public boolean packageLocalOn() { - return diff.packageLocalOn(); - } - }; - } + @Override + public boolean packageLocalOn() { + return diff.packageLocalOn(); + } + }; + } } diff --git a/jps/src/org/jetbrains/ether/dependencyView/StringCache.java b/jps/src/org/jetbrains/ether/dependencyView/StringCache.java index d40db9b4ba23..76ea22948ede 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/StringCache.java +++ b/jps/src/org/jetbrains/ether/dependencyView/StringCache.java @@ -17,97 +17,99 @@ import java.util.Map; */ public class StringCache { - public static class S implements Comparable, RW.Writable { - public final int index; - public final String value; + public static class S implements Comparable, RW.Writable { + public final int index; + public final String value; - private S(final int i, final String v) { - index = i; - value = v; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - S s = (S) o; - - if (index != s.index) return false; - - return true; - } - - @Override - public int hashCode() { - return index; - } - - public int compareTo(S o) { - return index - o.index; - } - - public void write(BufferedWriter w) { - RW.writeln(w, value); - } - - public static final RW.Reader reader = new RW.Reader() { - public S read(final BufferedReader r) { - final String s = RW.readString(r); - return StringCache.get(s); - } - }; - - public String toString () { - return value; - } + private S(final int i, final String v) { + index = i; + value = v; } - private static final Map map = new HashMap(); - private static int index = 0; + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; - public static S get(final String s) { + S s = (S)o; + + if (index != s.index) return false; + + return true; + } + + @Override + public int hashCode() { + return index; + } + + public int compareTo(S o) { + return index - o.index; + } + + public void write(BufferedWriter w) { + RW.writeln(w, value); + } + + public static final RW.Reader reader = new RW.Reader() { + public S read(final BufferedReader r) { + final String s = RW.readString(r); + return StringCache.get(s); + } + }; + + public String toString() { + return value; + } + } + + private static final Map map = new HashMap(); + private static int index = 0; + + public static S get(final String s) { // if (s == null) // return null; // - S r = map.get(s); + S r = map.get(s); - if (r == null) { - r = new S(index++, s); - map.put(s, r); - } - - return r; + if (r == null) { + r = new S(index++, s); + map.put(s, r); } - public static S[] get(final String[] s) { - if (s == null) { - return null; - } + return r; + } - final S[] r = new S[s.length]; - - for (int i = 0; i < r.length; i++) - r[i] = get(s[i]); - - return r; + public static S[] get(final String[] s) { + if (s == null) { + return null; } - public static RW.ToWritable fromS = new RW.ToWritable() { - public RW.Writable convert(S x) { - return RW.fromString.convert(x.value); - } - }; + final S[] r = new S[s.length]; - public static RW.Reader reader = new RW.Reader() { - public S read(final BufferedReader r) { - try { - return get(r.readLine()); - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } - }; + for (int i = 0; i < r.length; i++) { + r[i] = get(s[i]); + } + + return r; + } + + public static RW.ToWritable fromS = new RW.ToWritable() { + public RW.Writable convert(S x) { + return RW.fromString.convert(x.value); + } + }; + + public static RW.Reader reader = new RW.Reader() { + public S read(final BufferedReader r) { + try { + return get(r.readLine()); + } + catch (IOException e) { + e.printStackTrace(); + return null; + } + } + }; } diff --git a/jps/src/org/jetbrains/ether/dependencyView/TypeRepr.java b/jps/src/org/jetbrains/ether/dependencyView/TypeRepr.java index 08f5cdb602a6..69a367ff62e8 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/TypeRepr.java +++ b/jps/src/org/jetbrains/ether/dependencyView/TypeRepr.java @@ -16,301 +16,302 @@ import java.util.*; */ public class TypeRepr { - public static abstract class AbstractType implements RW.Writable { - public abstract void updateClassUsages(Set s); + public static abstract class AbstractType implements RW.Writable { + public abstract void updateClassUsages(Set s); - public abstract String getDescr(); + public abstract String getDescr(); + } + + public static class PrimitiveType extends AbstractType { + public final StringCache.S type; + + @Override + public String getDescr() { + return type.value; } - public static class PrimitiveType extends AbstractType { - public final StringCache.S type; + @Override + public void updateClassUsages(Set s) { - @Override - public String getDescr() { - return type.value; + } + + public void write(final BufferedWriter w) { + RW.writeln(w, "primitive"); + RW.writeln(w, type.value); + } + + PrimitiveType(final String type) { + this.type = StringCache.get(type); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final PrimitiveType that = (PrimitiveType)o; + + return type.equals(that.type); + } + + @Override + public int hashCode() { + return type.hashCode(); + } + } + + public static class ArrayType extends AbstractType { + public final AbstractType elementType; + + public AbstractType getDeepElementType() { + AbstractType current = this; + + while (current instanceof ArrayType) { + current = ((ArrayType)current).elementType; + } + + return current; + } + + @Override + public String getDescr() { + return "[" + elementType.getDescr(); + } + + @Override + public void updateClassUsages(Set s) { + elementType.updateClassUsages(s); + } + + ArrayType(final AbstractType elementType) { + this.elementType = elementType; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final ArrayType arrayType = (ArrayType)o; + + return elementType.equals(arrayType.elementType); + } + + @Override + public int hashCode() { + return elementType.hashCode(); + } + + public void write(BufferedWriter w) { + RW.writeln(w, "array"); + elementType.write(w); + } + } + + public static class ClassType extends AbstractType { + public final StringCache.S className; + public final AbstractType[] typeArgs; + + @Override + public String getDescr() { + return "L" + className.value + ";"; + } + + @Override + public void updateClassUsages(Set s) { + s.add(UsageRepr.createClassUsage(className)); + } + + ClassType(final BufferedReader r) { + className = StringCache.get(RW.readString(r)); + final Collection args = RW.readMany(r, reader, new LinkedList()); + typeArgs = args.toArray(new AbstractType[args.size()]); + } + + ClassType(final String className) { + this.className = StringCache.get(className); + typeArgs = new AbstractType[0]; + } + + ClassType(final StringCache.S className) { + this.className = className; + typeArgs = new AbstractType[0]; + } + + ClassType(final String className, final AbstractType[] typeArgs) { + this.className = StringCache.get(className); + this.typeArgs = typeArgs; + } + + ClassType(final StringCache.S className, final AbstractType[] typeArgs) { + this.className = className; + this.typeArgs = typeArgs; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final ClassType classType = (ClassType)o; + + if (className != null ? !className.equals(classType.className) : classType.className != null) return false; + if (!Arrays.equals(typeArgs, classType.typeArgs)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = className != null ? className.hashCode() : 0; + result = 31 * result + (typeArgs != null ? Arrays.hashCode(typeArgs) : 0); + return result; + } + + public void write(BufferedWriter w) { + RW.writeln(w, "class"); + RW.writeln(w, className.value); + RW.writeln(w, typeArgs); + } + } + + public static ClassType createClassType(final String s) { + return (ClassType)getType(new ClassType(s)); + } + + public static ClassType createClassType(final StringCache.S s) { + return (ClassType)getType(new ClassType(s)); + } + + public static ClassType[] createClassType(final String[] s) { + if (s == null) { + return null; + } + + final ClassType[] types = new ClassType[s.length]; + + for (int i = 0; i < types.length; i++) { + types[i] = createClassType(s[i]); + } + + return types; + } + + public static Collection createClassType(final String[] s, final Collection acc) { + if (s != null) { + for (String ss : s) { + acc.add(createClassType(ss)); + } + } + + return acc; + } + + public static Collection createClassType(final Collection s, final Collection acc) { + if (s != null) { + for (String ss : s) { + acc.add(createClassType(ss)); + } + } + + return acc; + } + + private static final Map map = new HashMap(); + + private static AbstractType getType(final AbstractType t) { + final AbstractType r = map.get(t); + + if (r != null) { + return r; + } + + map.put(t, t); + + return t; + } + + public static AbstractType getType(final String descr) { + final Type t = Type.getType(descr); + + switch (t.getSort()) { + case Type.OBJECT: + return getType(new ClassType(t.getClassName())); + + case Type.ARRAY: + return getType(new ArrayType(getType(t.getElementType()))); + + default: + return getType(new PrimitiveType(descr)); + } + } + + public static AbstractType getType(final Type t) { + return getType(t.getDescriptor()); + } + + public static AbstractType[] getType(final Type[] t) { + final AbstractType[] r = new AbstractType[t.length]; + + for (int i = 0; i < r.length; i++) { + r[i] = getType(t[i]); + } + + return r; + } + + public static AbstractType[] getType(final String[] t) { + if (t == null) { + return null; + } + + final AbstractType[] types = new AbstractType[t.length]; + + for (int i = 0; i < types.length; i++) { + types[i] = getType(Type.getType(t[i])); + } + + return types; + } + + public static RW.Reader reader = new RW.Reader() { + public AbstractType read(final BufferedReader r) { + AbstractType elementType = null; + int level = 0; + + while (true) { + final String tag = RW.readString(r); + + if (tag.equals("primitive")) { + elementType = getType(new PrimitiveType(RW.readString(r))); + break; } - @Override - public void updateClassUsages(Set s) { - + if (tag.equals("class")) { + elementType = getType(new ClassType(r)); + break; } + if (tag.equals("array")) { + level++; + } + } + + for (int i = 0; i < level; i++) { + elementType = getType(new ArrayType(elementType)); + } + + return elementType; + } + }; + + public static RW.ToWritable fromAbstractType = new RW.ToWritable() { + public RW.Writable convert(final AbstractType x) { + return new RW.Writable() { public void write(final BufferedWriter w) { - RW.writeln(w, "primitive"); - RW.writeln(w, type.value); - } - - PrimitiveType(final String type) { - this.type = StringCache.get(type); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final PrimitiveType that = (PrimitiveType) o; - - return type.equals(that.type); - } - - @Override - public int hashCode() { - return type.hashCode(); + x.write(w); } + }; } - - public static class ArrayType extends AbstractType { - public final AbstractType elementType; - - public AbstractType getDeepElementType() { - AbstractType current = this; - - while (current instanceof ArrayType) { - current = ((ArrayType) current).elementType; - } - - return current; - } - - @Override - public String getDescr() { - return "[" + elementType.getDescr(); - } - - @Override - public void updateClassUsages(Set s) { - elementType.updateClassUsages(s); - } - - ArrayType(final AbstractType elementType) { - this.elementType = elementType; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final ArrayType arrayType = (ArrayType) o; - - return elementType.equals(arrayType.elementType); - } - - @Override - public int hashCode() { - return elementType.hashCode(); - } - - public void write(BufferedWriter w) { - RW.writeln(w, "array"); - elementType.write(w); - } - } - - public static class ClassType extends AbstractType { - public final StringCache.S className; - public final AbstractType[] typeArgs; - - @Override - public String getDescr() { - return "L" + className.value + ";"; - } - - @Override - public void updateClassUsages(Set s) { - s.add(UsageRepr.createClassUsage(className)); - } - - ClassType(final BufferedReader r){ - className = StringCache.get(RW.readString(r)); - final Collection args = RW.readMany(r, reader, new LinkedList()); - typeArgs = args.toArray(new AbstractType[args.size()]); - } - - ClassType(final String className) { - this.className = StringCache.get(className); - typeArgs = new AbstractType[0]; - } - - ClassType(final StringCache.S className) { - this.className = className; - typeArgs = new AbstractType[0]; - } - - ClassType(final String className, final AbstractType[] typeArgs) { - this.className = StringCache.get(className); - this.typeArgs = typeArgs; - } - - ClassType(final StringCache.S className, final AbstractType[] typeArgs) { - this.className = className; - this.typeArgs = typeArgs; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final ClassType classType = (ClassType) o; - - if (className != null ? !className.equals(classType.className) : classType.className != null) return false; - if (!Arrays.equals(typeArgs, classType.typeArgs)) return false; - - return true; - } - - @Override - public int hashCode() { - int result = className != null ? className.hashCode() : 0; - result = 31 * result + (typeArgs != null ? Arrays.hashCode(typeArgs) : 0); - return result; - } - - public void write(BufferedWriter w) { - RW.writeln(w, "class"); - RW.writeln(w, className.value); - RW.writeln(w, typeArgs); - } - } - - public static ClassType createClassType(final String s) { - return (ClassType) getType(new ClassType(s)); - } - - public static ClassType createClassType(final StringCache.S s) { - return (ClassType) getType(new ClassType(s)); - } - - public static ClassType[] createClassType(final String[] s) { - if (s == null) { - return null; - } - - final ClassType[] types = new ClassType[s.length]; - - for (int i = 0; i < types.length; i++) { - types[i] = createClassType(s[i]); - } - - return types; - } - - public static Collection createClassType(final String[] s, final Collection acc) { - if (s != null) { - for (String ss : s) { - acc.add(createClassType(ss)); - } - } - - return acc; - } - - public static Collection createClassType(final Collection s, final Collection acc) { - if (s != null) { - for (String ss : s) { - acc.add(createClassType(ss)); - } - } - - return acc; - } - - private static final Map map = new HashMap(); - - private static AbstractType getType(final AbstractType t) { - final AbstractType r = map.get(t); - - if (r != null) { - return r; - } - - map.put(t, t); - - return t; - } - - public static AbstractType getType(final String descr) { - final Type t = Type.getType(descr); - - switch (t.getSort()) { - case Type.OBJECT: - return getType(new ClassType(t.getClassName())); - - case Type.ARRAY: - return getType(new ArrayType(getType(t.getElementType()))); - - default: - return getType(new PrimitiveType(descr)); - } - } - - public static AbstractType getType(final Type t) { - return getType(t.getDescriptor()); - } - - public static AbstractType[] getType(final Type[] t) { - final AbstractType[] r = new AbstractType[t.length]; - - for (int i = 0; i < r.length; i++) - r[i] = getType(t[i]); - - return r; - } - - public static AbstractType[] getType(final String[] t) { - if (t == null) { - return null; - } - - final AbstractType[] types = new AbstractType[t.length]; - - for (int i = 0; i < types.length; i++) { - types[i] = getType(Type.getType(t[i])); - } - - return types; - } - - public static RW.Reader reader = new RW.Reader() { - public AbstractType read(final BufferedReader r) { - AbstractType elementType = null; - int level = 0; - - while (true) { - final String tag = RW.readString(r); - - if (tag.equals("primitive")) { - elementType = getType(new PrimitiveType(RW.readString(r))); - break; - } - - if (tag.equals("class")) { - elementType = getType(new ClassType(r)); - break; - } - - if (tag.equals("array")) { - level++; - } - } - - for (int i = 0; i < level; i++) { - elementType = getType(new ArrayType(elementType)); - } - - return elementType; - } - }; - - public static RW.ToWritable fromAbstractType = new RW.ToWritable() { - public RW.Writable convert(final AbstractType x) { - return new RW.Writable() { - public void write(final BufferedWriter w) { - x.write(w); - } - }; - } - }; + }; } diff --git a/jps/src/org/jetbrains/ether/dependencyView/UsageRepr.java b/jps/src/org/jetbrains/ether/dependencyView/UsageRepr.java index b4aad0014426..ee4df5db872e 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/UsageRepr.java +++ b/jps/src/org/jetbrains/ether/dependencyView/UsageRepr.java @@ -16,488 +16,500 @@ import java.util.*; * To change this template use File | Settings | File Templates. */ public class UsageRepr { - private final static TypeRepr.AbstractType[] dummyAbstractType = new TypeRepr.AbstractType[0]; + private final static TypeRepr.AbstractType[] dummyAbstractType = new TypeRepr.AbstractType[0]; - private final static Map map = new HashMap(); + private final static Map map = new HashMap(); - private static Usage getUsage(final Usage u) { - final Usage r = map.get(u); + private static Usage getUsage(final Usage u) { + final Usage r = map.get(u); - if (r == null) { - map.put(u, u); - return u; - } - - return r; + if (r == null) { + map.put(u, u); + return u; } - public static class Cluster implements RW.Writable { - final Set usages = new HashSet(); - final Map> residentialMap = new HashMap>(); + return r; + } - public Cluster() { - } + public static class Cluster implements RW.Writable { + final Set usages = new HashSet(); + final Map> residentialMap = new HashMap>(); - public Cluster(final BufferedReader r) { - final int size = RW.readInt(r); - - for (int i = 0; i < size; i++) { - final Usage u = reader.read(r); - final Set s = (Set) RW.readMany(r, StringCache.reader, new HashSet()); - - usages.add(u); - residentialMap.put(u, s); - } - } - - public void write(final BufferedWriter w) { - RW.writeln(w, Integer.toString(usages.size())); - - for (Usage u : usages) { - u.write(w); - RW.writeln(w, residentialMap.get(u)); - } - } - - public void addUsage(final String residence, final Usage usage) { - final StringCache.S r = StringCache.get(residence); - - Set s = residentialMap.get(usage); - - if (s == null) { - s = new HashSet(); - residentialMap.put(usage, s); - } - - s.add(r); - usages.add(usage); - } - - public Set getUsages() { - return usages; - } - - public Set getResidence(final Usage usage) { - return residentialMap.get(usage); - } - - public void updateCluster(final Cluster c) { - usages.addAll(c.getUsages()); - for (Map.Entry> e : c.residentialMap.entrySet()) { - final Usage u = e.getKey(); - final Set v = e.getValue(); - final Set s = residentialMap.get(u); - - if (s == null) { - residentialMap.put(u, v); - } else { - s.addAll(v); - } - } - } - - public boolean isEmpty() { - return usages.isEmpty(); - } + public Cluster() { } - public static abstract class Usage implements RW.Writable { - public abstract StringCache.S getOwner(); + public Cluster(final BufferedReader r) { + final int size = RW.readInt(r); + + for (int i = 0; i < size; i++) { + final Usage u = reader.read(r); + final Set s = (Set)RW.readMany(r, StringCache.reader, new HashSet()); + + usages.add(u); + residentialMap.put(u, s); + } } - public static abstract class FMUsage extends Usage { - public final StringCache.S name; - public final StringCache.S owner; + public void write(final BufferedWriter w) { + RW.writeln(w, Integer.toString(usages.size())); - @Override - public StringCache.S getOwner() { - return owner; - } - - protected FMUsage(final String n, final String o) { - name = StringCache.get(n); - owner = StringCache.get(o); - } - - protected FMUsage(final BufferedReader r) { - name = StringCache.get(RW.readString(r)); - owner = StringCache.get(RW.readString(r)); - } + for (Usage u : usages) { + u.write(w); + RW.writeln(w, residentialMap.get(u)); + } } - public static class FieldUsage extends FMUsage { - public final TypeRepr.AbstractType type; + public void addUsage(final String residence, final Usage usage) { + final StringCache.S r = StringCache.get(residence); - private FieldUsage(final String n, final String o, final String d) { - super(n, o); - type = TypeRepr.getType(d); - } + Set s = residentialMap.get(usage); - private FieldUsage(final BufferedReader r) { - super(r); - type = TypeRepr.reader.read(r); - } + if (s == null) { + s = new HashSet(); + residentialMap.put(usage, s); + } - public void write(final BufferedWriter w) { - RW.writeln(w, "fieldUsage"); - RW.writeln(w, name.value); - RW.writeln(w, owner.value); - type.write(w); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final FieldUsage that = (FieldUsage) o; - - return type.equals(that.type) && name.equals(that.name) && owner.equals(that.owner); - } - - @Override - public int hashCode() { - return 31 * (31 * type.hashCode() + (name.hashCode())) + owner.hashCode(); - } + s.add(r); + usages.add(usage); } - public static class FieldAssignUsage extends FieldUsage { - private FieldAssignUsage(final String n, final String o, final String d) { - super(n, o, d); - } - - private FieldAssignUsage(final BufferedReader r) { - super(r); - } - - public void write(final BufferedWriter w) { - RW.writeln(w, "fieldAssignUsage"); - RW.writeln(w, name.value); - RW.writeln(w, owner.value); - type.write(w); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final FieldAssignUsage that = (FieldAssignUsage) o; - - return type.equals(that.type) && name.equals(that.name) && owner.equals(that.owner); - } - - @Override - public int hashCode() { - return super.hashCode() + 1; - } + public Set getUsages() { + return usages; } - public static class MethodUsage extends FMUsage { - public final TypeRepr.AbstractType[] argumentTypes; - public final TypeRepr.AbstractType returnType; - - private MethodUsage(final String n, final String o, final String d) { - super(n, o); - argumentTypes = TypeRepr.getType(Type.getArgumentTypes(d)); - returnType = TypeRepr.getType(Type.getReturnType(d)); - } - - private MethodUsage(final BufferedReader r) { - super(r); - argumentTypes = RW.readMany(r, TypeRepr.reader, new ArrayList()).toArray(dummyAbstractType); - returnType = TypeRepr.reader.read(r); - } - - public void write(final BufferedWriter w) { - RW.writeln(w, "methodUsage"); - RW.writeln(w, name.value); - RW.writeln(w, owner.value); - RW.writeln(w, argumentTypes, TypeRepr.fromAbstractType); - returnType.write(w); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final MethodUsage that = (MethodUsage) o; - - if (!Arrays.equals(argumentTypes, that.argumentTypes)) return false; - if (returnType != null ? !returnType.equals(that.returnType) : that.returnType != null) return false; - if (name != null ? !name.equals(that.name) : that.name != null) return false; - if (owner != null ? !owner.equals(that.owner) : that.owner != null) return false; - - return Arrays.equals(argumentTypes, that.argumentTypes) && - returnType.equals(that.returnType) && - name.equals(that.name) && - owner.equals(that.owner); - } - - @Override - public int hashCode() { - return ((31 * Arrays.hashCode(argumentTypes) + (returnType.hashCode())) * 31 + (name.hashCode())) * 31 + (owner.hashCode()); - } + public Set getResidence(final Usage usage) { + return residentialMap.get(usage); } - public static class ClassUsage extends Usage { - final StringCache.S className; + public void updateCluster(final Cluster c) { + usages.addAll(c.getUsages()); + for (Map.Entry> e : c.residentialMap.entrySet()) { + final Usage u = e.getKey(); + final Set v = e.getValue(); + final Set s = residentialMap.get(u); - @Override - public StringCache.S getOwner() { - return className; + if (s == null) { + residentialMap.put(u, v); } - - private ClassUsage(final String n) { - className = StringCache.get(n); - } - - private ClassUsage(final StringCache.S n) { - className = n; - } - - private ClassUsage(final BufferedReader r) { - className = StringCache.get(RW.readString(r)); - } - - private ClassUsage(final BufferedReader r, boolean b) { - super(); - className = StringCache.get(RW.readString(r)); - } - - public void write(final BufferedWriter w) { - RW.writeln(w, "classUsage"); - RW.writeln(w, className.value); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final ClassUsage that = (ClassUsage) o; - - return className.equals(that.className); - } - - @Override - public int hashCode() { - return className.hashCode(); + else { + s.addAll(v); } + } } - public static class ClassExtendsUsage extends Usage { - protected final StringCache.S className; + public boolean isEmpty() { + return usages.isEmpty(); + } + } - @Override - public StringCache.S getOwner() { - return className; - } + public static abstract class Usage implements RW.Writable { + public abstract StringCache.S getOwner(); + } - public ClassExtendsUsage(final StringCache.S n) { - className = n; - } + public static abstract class FMUsage extends Usage { + public final StringCache.S name; + public final StringCache.S owner; - public ClassExtendsUsage(final BufferedReader r) { - className = StringCache.get(RW.readString(r)); - } - - public void write(final BufferedWriter w) { - RW.writeln(w, "classExtendsUsage"); - RW.writeln(w, className.value); - } - - @Override - public int hashCode() { - return className.hashCode() + 1; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ClassExtendsUsage that = (ClassExtendsUsage) o; - - if (!className.equals(that.className)) return false; - - return true; - } + @Override + public StringCache.S getOwner() { + return owner; } - public static class ClassNewUsage extends ClassExtendsUsage { - public ClassNewUsage(StringCache.S n) { - super(n); - } - - public ClassNewUsage(BufferedReader r) { - super(r); - } - - public void write(final BufferedWriter w) { - RW.writeln(w, "classNewUsage"); - RW.writeln(w, className.value); - } - - @Override - public int hashCode() { - return className.hashCode() + 2; - } + protected FMUsage(final String n, final String o) { + name = StringCache.get(n); + owner = StringCache.get(o); } - public static class AnnotationUsage extends Usage { - public static final RW.Reader elementTypeReader = new RW.Reader() { - public ElementType read(final BufferedReader r) { - return ElementType.valueOf(RW.readString(r)); - } - }; + protected FMUsage(final BufferedReader r) { + name = StringCache.get(RW.readString(r)); + owner = StringCache.get(RW.readString(r)); + } + } - public static final RW.ToWritable elementTypeToWritable = new RW.ToWritable() { - public RW.Writable convert(final ElementType x) { - return new RW.Writable() { - public void write(final BufferedWriter w) { - RW.writeln(w, x.toString()); - } - }; - } - }; + public static class FieldUsage extends FMUsage { + public final TypeRepr.AbstractType type; - final TypeRepr.ClassType type; - final Collection usedArguments; - final Collection usedTargets; - - public boolean satisfies(final Usage usage) { - if (usage instanceof AnnotationUsage) { - final AnnotationUsage annotationUsage = (AnnotationUsage) usage; - - if (!type.equals(annotationUsage.type)) { - return false; - } - - boolean argumentsSatisfy = false; - - if (usedArguments != null) { - final Collection arguments = new HashSet(usedArguments); - - arguments.removeAll(annotationUsage.usedArguments); - - argumentsSatisfy = !arguments.isEmpty(); - } - - boolean targetsSatisfy = false; - - if (usedTargets != null) { - final Collection targets = new HashSet(usedTargets); - - targets.retainAll(annotationUsage.usedTargets); - - targetsSatisfy = !targets.isEmpty(); - } - - return argumentsSatisfy || targetsSatisfy; - } - - return false; - } - - private AnnotationUsage(final TypeRepr.ClassType type, final Collection usedArguments, final Collection targets) { - this.type = type; - this.usedArguments = usedArguments; - this.usedTargets = targets; - } - - private AnnotationUsage(final BufferedReader r) { - type = (TypeRepr.ClassType) TypeRepr.reader.read(r); - usedArguments = RW.readMany(r, StringCache.reader, new HashSet()); - usedTargets = RW.readMany(r, elementTypeReader, new HashSet()); - } - - @Override - public StringCache.S getOwner() { - return type.className; - } - - public void write(final BufferedWriter w) { - RW.writeln(w, "annotationUsage"); - type.write(w); - RW.writeln(w, usedArguments); - RW.writeln(w, usedTargets, elementTypeToWritable); - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - AnnotationUsage that = (AnnotationUsage) o; - - if (usedArguments != null ? !usedArguments.equals(that.usedArguments) : that.usedArguments != null) - return false; - if (usedTargets != null ? !usedTargets.equals(that.usedTargets) : that.usedTargets != null) return false; - if (type != null ? !type.equals(that.type) : that.type != null) return false; - - return true; - } - - @Override - public int hashCode() { - int result = type != null ? type.hashCode() : 0; - result = 31 * result + (usedArguments != null ? usedArguments.hashCode() : 0); - result = 31 * result + (usedTargets != null ? usedTargets.hashCode() : 0); - return result; - } + private FieldUsage(final String n, final String o, final String d) { + super(n, o); + type = TypeRepr.getType(d); } - public static Usage createFieldUsage(final String name, final String owner, final String descr) { - return getUsage(new FieldUsage(name, owner, descr)); + private FieldUsage(final BufferedReader r) { + super(r); + type = TypeRepr.reader.read(r); } - public static Usage createFieldAssignUsage(final String name, final String owner, final String descr) { - return getUsage(new FieldAssignUsage(name, owner, descr)); + public void write(final BufferedWriter w) { + RW.writeln(w, "fieldUsage"); + RW.writeln(w, name.value); + RW.writeln(w, owner.value); + type.write(w); } - public static Usage createMethodUsage(final String name, final String owner, final String descr) { - return getUsage(new MethodUsage(name, owner, descr)); + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final FieldUsage that = (FieldUsage)o; + + return type.equals(that.type) && name.equals(that.name) && owner.equals(that.owner); } - public static Usage createClassUsage(final String name) { - return getUsage(new ClassUsage(name)); + @Override + public int hashCode() { + return 31 * (31 * type.hashCode() + (name.hashCode())) + owner.hashCode(); + } + } + + public static class FieldAssignUsage extends FieldUsage { + private FieldAssignUsage(final String n, final String o, final String d) { + super(n, o, d); } - public static Usage createClassUsage(final StringCache.S name) { - return getUsage(new ClassUsage(name)); + private FieldAssignUsage(final BufferedReader r) { + super(r); } - public static Usage createClassExtendsUsage(final StringCache.S name) { - return getUsage(new ClassExtendsUsage(name)); + public void write(final BufferedWriter w) { + RW.writeln(w, "fieldAssignUsage"); + RW.writeln(w, name.value); + RW.writeln(w, owner.value); + type.write(w); } - public static Usage createClassNewUsage(final StringCache.S name) { - return getUsage(new ClassNewUsage(name)); + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final FieldAssignUsage that = (FieldAssignUsage)o; + + return type.equals(that.type) && name.equals(that.name) && owner.equals(that.owner); } - public static Usage createAnnotationUsage(final TypeRepr.ClassType type, final Collection usedArguments, final Collection targets) { - return getUsage(new AnnotationUsage(type, usedArguments, targets)); + @Override + public int hashCode() { + return super.hashCode() + 1; + } + } + + public static class MethodUsage extends FMUsage { + public final TypeRepr.AbstractType[] argumentTypes; + public final TypeRepr.AbstractType returnType; + + private MethodUsage(final String n, final String o, final String d) { + super(n, o); + argumentTypes = TypeRepr.getType(Type.getArgumentTypes(d)); + returnType = TypeRepr.getType(Type.getReturnType(d)); } - public static RW.Reader reader = new RW.Reader() { - public Usage read(final BufferedReader r) { - final String tag = RW.readString(r); + private MethodUsage(final BufferedReader r) { + super(r); + argumentTypes = RW.readMany(r, TypeRepr.reader, new ArrayList()).toArray(dummyAbstractType); + returnType = TypeRepr.reader.read(r); + } - if (tag.equals("classUsage")) { - return getUsage(new ClassUsage(r)); - } else if (tag.equals("fieldUsage")) { - return getUsage(new FieldUsage(r)); - } else if (tag.equals("fieldAssignUsage")) { - return getUsage(new FieldAssignUsage(r)); - } else if (tag.equals("methodUsage")) { - return getUsage(new MethodUsage(r)); - } else if (tag.equals("classExtendsUsage")) { - return getUsage(new ClassExtendsUsage(r)); - } else if (tag.equals("classNewUsage")) { - return getUsage(new ClassNewUsage(r)); - } else return getUsage(new AnnotationUsage(r)); - } + public void write(final BufferedWriter w) { + RW.writeln(w, "methodUsage"); + RW.writeln(w, name.value); + RW.writeln(w, owner.value); + RW.writeln(w, argumentTypes, TypeRepr.fromAbstractType); + returnType.write(w); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final MethodUsage that = (MethodUsage)o; + + if (!Arrays.equals(argumentTypes, that.argumentTypes)) return false; + if (returnType != null ? !returnType.equals(that.returnType) : that.returnType != null) return false; + if (name != null ? !name.equals(that.name) : that.name != null) return false; + if (owner != null ? !owner.equals(that.owner) : that.owner != null) return false; + + return Arrays.equals(argumentTypes, that.argumentTypes) && + returnType.equals(that.returnType) && + name.equals(that.name) && + owner.equals(that.owner); + } + + @Override + public int hashCode() { + return ((31 * Arrays.hashCode(argumentTypes) + (returnType.hashCode())) * 31 + (name.hashCode())) * 31 + (owner.hashCode()); + } + } + + public static class ClassUsage extends Usage { + final StringCache.S className; + + @Override + public StringCache.S getOwner() { + return className; + } + + private ClassUsage(final String n) { + className = StringCache.get(n); + } + + private ClassUsage(final StringCache.S n) { + className = n; + } + + private ClassUsage(final BufferedReader r) { + className = StringCache.get(RW.readString(r)); + } + + private ClassUsage(final BufferedReader r, boolean b) { + super(); + className = StringCache.get(RW.readString(r)); + } + + public void write(final BufferedWriter w) { + RW.writeln(w, "classUsage"); + RW.writeln(w, className.value); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final ClassUsage that = (ClassUsage)o; + + return className.equals(that.className); + } + + @Override + public int hashCode() { + return className.hashCode(); + } + } + + public static class ClassExtendsUsage extends Usage { + protected final StringCache.S className; + + @Override + public StringCache.S getOwner() { + return className; + } + + public ClassExtendsUsage(final StringCache.S n) { + className = n; + } + + public ClassExtendsUsage(final BufferedReader r) { + className = StringCache.get(RW.readString(r)); + } + + public void write(final BufferedWriter w) { + RW.writeln(w, "classExtendsUsage"); + RW.writeln(w, className.value); + } + + @Override + public int hashCode() { + return className.hashCode() + 1; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ClassExtendsUsage that = (ClassExtendsUsage)o; + + if (!className.equals(that.className)) return false; + + return true; + } + } + + public static class ClassNewUsage extends ClassExtendsUsage { + public ClassNewUsage(StringCache.S n) { + super(n); + } + + public ClassNewUsage(BufferedReader r) { + super(r); + } + + public void write(final BufferedWriter w) { + RW.writeln(w, "classNewUsage"); + RW.writeln(w, className.value); + } + + @Override + public int hashCode() { + return className.hashCode() + 2; + } + } + + public static class AnnotationUsage extends Usage { + public static final RW.Reader elementTypeReader = new RW.Reader() { + public ElementType read(final BufferedReader r) { + return ElementType.valueOf(RW.readString(r)); + } }; + + public static final RW.ToWritable elementTypeToWritable = new RW.ToWritable() { + public RW.Writable convert(final ElementType x) { + return new RW.Writable() { + public void write(final BufferedWriter w) { + RW.writeln(w, x.toString()); + } + }; + } + }; + + final TypeRepr.ClassType type; + final Collection usedArguments; + final Collection usedTargets; + + public boolean satisfies(final Usage usage) { + if (usage instanceof AnnotationUsage) { + final AnnotationUsage annotationUsage = (AnnotationUsage)usage; + + if (!type.equals(annotationUsage.type)) { + return false; + } + + boolean argumentsSatisfy = false; + + if (usedArguments != null) { + final Collection arguments = new HashSet(usedArguments); + + arguments.removeAll(annotationUsage.usedArguments); + + argumentsSatisfy = !arguments.isEmpty(); + } + + boolean targetsSatisfy = false; + + if (usedTargets != null) { + final Collection targets = new HashSet(usedTargets); + + targets.retainAll(annotationUsage.usedTargets); + + targetsSatisfy = !targets.isEmpty(); + } + + return argumentsSatisfy || targetsSatisfy; + } + + return false; + } + + private AnnotationUsage(final TypeRepr.ClassType type, + final Collection usedArguments, + final Collection targets) { + this.type = type; + this.usedArguments = usedArguments; + this.usedTargets = targets; + } + + private AnnotationUsage(final BufferedReader r) { + type = (TypeRepr.ClassType)TypeRepr.reader.read(r); + usedArguments = RW.readMany(r, StringCache.reader, new HashSet()); + usedTargets = RW.readMany(r, elementTypeReader, new HashSet()); + } + + @Override + public StringCache.S getOwner() { + return type.className; + } + + public void write(final BufferedWriter w) { + RW.writeln(w, "annotationUsage"); + type.write(w); + RW.writeln(w, usedArguments); + RW.writeln(w, usedTargets, elementTypeToWritable); + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AnnotationUsage that = (AnnotationUsage)o; + + if (usedArguments != null ? !usedArguments.equals(that.usedArguments) : that.usedArguments != null) return false; + if (usedTargets != null ? !usedTargets.equals(that.usedTargets) : that.usedTargets != null) return false; + if (type != null ? !type.equals(that.type) : that.type != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = type != null ? type.hashCode() : 0; + result = 31 * result + (usedArguments != null ? usedArguments.hashCode() : 0); + result = 31 * result + (usedTargets != null ? usedTargets.hashCode() : 0); + return result; + } + } + + public static Usage createFieldUsage(final String name, final String owner, final String descr) { + return getUsage(new FieldUsage(name, owner, descr)); + } + + public static Usage createFieldAssignUsage(final String name, final String owner, final String descr) { + return getUsage(new FieldAssignUsage(name, owner, descr)); + } + + public static Usage createMethodUsage(final String name, final String owner, final String descr) { + return getUsage(new MethodUsage(name, owner, descr)); + } + + public static Usage createClassUsage(final String name) { + return getUsage(new ClassUsage(name)); + } + + public static Usage createClassUsage(final StringCache.S name) { + return getUsage(new ClassUsage(name)); + } + + public static Usage createClassExtendsUsage(final StringCache.S name) { + return getUsage(new ClassExtendsUsage(name)); + } + + public static Usage createClassNewUsage(final StringCache.S name) { + return getUsage(new ClassNewUsage(name)); + } + + public static Usage createAnnotationUsage(final TypeRepr.ClassType type, + final Collection usedArguments, + final Collection targets) { + return getUsage(new AnnotationUsage(type, usedArguments, targets)); + } + + public static RW.Reader reader = new RW.Reader() { + public Usage read(final BufferedReader r) { + final String tag = RW.readString(r); + + if (tag.equals("classUsage")) { + return getUsage(new ClassUsage(r)); + } + else if (tag.equals("fieldUsage")) { + return getUsage(new FieldUsage(r)); + } + else if (tag.equals("fieldAssignUsage")) { + return getUsage(new FieldAssignUsage(r)); + } + else if (tag.equals("methodUsage")) { + return getUsage(new MethodUsage(r)); + } + else if (tag.equals("classExtendsUsage")) { + return getUsage(new ClassExtendsUsage(r)); + } + else if (tag.equals("classNewUsage")) { + return getUsage(new ClassNewUsage(r)); + } + else { + return getUsage(new AnnotationUsage(r)); + } + } + }; } From f30b6670bc0ff924842e23300d511553cc3b6bf8 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Wed, 19 Oct 2011 19:03:10 +0400 Subject: [PATCH 032/128] NPE --- .../hint/api/impls/AnnotationParameterInfoHandler.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java index 79f9ba5297f2..5c6be31a1c7d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java @@ -120,7 +120,8 @@ public class AnnotationParameterInfoHandler implements ParameterInfoHandler Date: Wed, 19 Oct 2011 12:51:09 +0200 Subject: [PATCH 033/128] junit tests view: fix selection stealing when test was selected from keyboard --- .../junit2/ui/actions/RunningTestTracker.java | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/actions/RunningTestTracker.java b/plugins/junit/src/com/intellij/execution/junit2/ui/actions/RunningTestTracker.java index 2a1e4704db1c..16bf572bdab2 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/ui/actions/RunningTestTracker.java +++ b/plugins/junit/src/com/intellij/execution/junit2/ui/actions/RunningTestTracker.java @@ -33,6 +33,8 @@ import com.intellij.rt.execution.junit.states.PoolOfTestStates; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; @@ -49,29 +51,43 @@ class RunningTestTracker extends JUnitAdapter implements TestFrameworkPropertyLi final JTree tree = myModel.getTree(); final MouseAdapter userSelectionListener = new MouseAdapter() { @Override - public void mousePressed(MouseEvent e) { - final TreePath treePath = tree.getPathForLocation(e.getX(), e.getY()); - if (treePath != null) { - final Object component = treePath.getLastPathComponent(); - if (component instanceof DefaultMutableTreeNode) { - final Object userObject = ((DefaultMutableTreeNode)component).getUserObject(); - if (userObject instanceof NodeDescriptor) { - myLastSelected = (TestProxy)((NodeDescriptor)userObject).getElement(); - } - } - } + public void mouseClicked(MouseEvent e) { + setUserSelection(tree.getPathForLocation(e.getX(), e.getY())); } }; tree.addMouseListener(userSelectionListener); + final KeyAdapter keyAdapter = new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + final int keyCode = e.getKeyCode(); + if (keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_RIGHT) { + setUserSelection(tree.getSelectionPath()); + } + } + }; + tree.addKeyListener(keyAdapter); Disposer.register(myModel, new Disposable() { @Override public void dispose() { tree.removeMouseListener(userSelectionListener); + tree.removeKeyListener(keyAdapter); } }); choosePolicy(); } + private void setUserSelection(TreePath treePath) { + if (treePath != null) { + final Object component = treePath.getLastPathComponent(); + if (component instanceof DefaultMutableTreeNode) { + final Object userObject = ((DefaultMutableTreeNode)component).getUserObject(); + if (userObject instanceof NodeDescriptor) { + myLastSelected = (TestProxy)((NodeDescriptor)userObject).getElement(); + } + } + } + } + public void onChanged(final Boolean value) { choosePolicy(); myTrackingPolicy.apply(); From cc05aaca72079794921f08f655d6e7879126cb5d Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 19 Oct 2011 16:05:27 +0200 Subject: [PATCH 034/128] EA-30662 - read access --- .../groovy/findUsages/AnnotatedMembersSearcher.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/AnnotatedMembersSearcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/AnnotatedMembersSearcher.java index 4f7b5aa6f739..89a15e699fa3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/AnnotatedMembersSearcher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/AnnotatedMembersSearcher.java @@ -16,7 +16,9 @@ package org.jetbrains.plugins.groovy.findUsages; import com.intellij.openapi.application.AccessToken; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ReadAction; +import com.intellij.openapi.util.Computable; import com.intellij.psi.*; import com.intellij.psi.impl.search.AnnotatedElementsSearcher; import com.intellij.psi.search.GlobalSearchScope; @@ -45,10 +47,15 @@ import java.util.List; public class AnnotatedMembersSearcher implements QueryExecutor { @NotNull - private static List getAnnotatedMemberCandidates(PsiClass clazz, GlobalSearchScope scope) { + private static List getAnnotatedMemberCandidates(final PsiClass clazz, final GlobalSearchScope scope) { final String name = clazz.getName(); if (name == null) return Collections.emptyList(); - final Collection members = StubIndex.getInstance().get(GrAnnotatedMemberIndex.KEY, name, clazz.getProject(), scope); + final Collection members = ApplicationManager.getApplication().runReadAction(new Computable>() { + @Override + public Collection compute() { + return StubIndex.getInstance().get(GrAnnotatedMemberIndex.KEY, name, clazz.getProject(), scope); + } + }); if (members.isEmpty()) { return Collections.emptyList(); } From b01dc9dbad840bf6b6be929728af265295cce336 Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 19 Oct 2011 16:26:33 +0200 Subject: [PATCH 035/128] testng tests view: fix selection stealing (IDEA-75569) --- .../testframework/TrackRunningTestUtil.java | 80 +++++++++++++++++++ .../junit2/ui/actions/RunningTestTracker.java | 48 ++--------- .../testng/ui/TestNGResults.java | 17 +++- 3 files changed, 100 insertions(+), 45 deletions(-) create mode 100644 platform/testRunner/src/com/intellij/execution/testframework/TrackRunningTestUtil.java diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TrackRunningTestUtil.java b/platform/testRunner/src/com/intellij/execution/testframework/TrackRunningTestUtil.java new file mode 100644 index 000000000000..6714d22ccdc8 --- /dev/null +++ b/platform/testRunner/src/com/intellij/execution/testframework/TrackRunningTestUtil.java @@ -0,0 +1,80 @@ +/* + * Copyright 2000-2011 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.execution.testframework; + +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Pass; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreePath; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/** + * User: anna + * Date: 10/19/11 + */ +public class TrackRunningTestUtil { + private TrackRunningTestUtil() { + } + + public static void installStopListeners(final JTree tree, final Disposable parentDisposable, final Pass setSelection) { + final MouseAdapter userSelectionListener = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + setSelection.pass(setUserSelection(tree.getPathForLocation(e.getX(), e.getY()))); + } + }; + tree.addMouseListener(userSelectionListener); + final KeyAdapter keyAdapter = new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + final int keyCode = e.getKeyCode(); + if (keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_RIGHT) { + setSelection.pass(setUserSelection(tree.getSelectionPath())); + } + } + }; + tree.addKeyListener(keyAdapter); + Disposer.register(parentDisposable, new Disposable() { + @Override + public void dispose() { + tree.removeMouseListener(userSelectionListener); + tree.removeKeyListener(keyAdapter); + } + }); + } + + @Nullable + private static AbstractTestProxy setUserSelection(TreePath treePath) { + if (treePath != null) { + final Object component = treePath.getLastPathComponent(); + if (component instanceof DefaultMutableTreeNode) { + final Object userObject = ((DefaultMutableTreeNode)component).getUserObject(); + if (userObject instanceof NodeDescriptor) { + return (AbstractTestProxy)((NodeDescriptor)userObject).getElement(); + } + } + } + return null; + } +} diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/actions/RunningTestTracker.java b/plugins/junit/src/com/intellij/execution/junit2/ui/actions/RunningTestTracker.java index 16bf572bdab2..5c4e5f6ce0cf 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/ui/actions/RunningTestTracker.java +++ b/plugins/junit/src/com/intellij/execution/junit2/ui/actions/RunningTestTracker.java @@ -22,21 +22,15 @@ import com.intellij.execution.junit2.events.TestEvent; import com.intellij.execution.junit2.ui.model.JUnitAdapter; import com.intellij.execution.junit2.ui.model.JUnitRunningModel; import com.intellij.execution.junit2.ui.properties.JUnitConsoleProperties; +import com.intellij.execution.testframework.AbstractTestProxy; import com.intellij.execution.testframework.TestFrameworkPropertyListener; +import com.intellij.execution.testframework.TrackRunningTestUtil; import com.intellij.execution.testframework.actions.TestFrameworkActions; -import com.intellij.ide.util.treeView.NodeDescriptor; -import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Pass; import com.intellij.rt.execution.junit.states.PoolOfTestStates; import javax.swing.*; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.TreePath; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; class RunningTestTracker extends JUnitAdapter implements TestFrameworkPropertyListener { private static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit2.ui.actions.TrackRunningTestAction"); @@ -49,45 +43,15 @@ class RunningTestTracker extends JUnitAdapter implements TestFrameworkPropertyLi private RunningTestTracker(final JUnitRunningModel model) { myModel = model; final JTree tree = myModel.getTree(); - final MouseAdapter userSelectionListener = new MouseAdapter() { + TrackRunningTestUtil.installStopListeners(tree, myModel, new Pass() { @Override - public void mouseClicked(MouseEvent e) { - setUserSelection(tree.getPathForLocation(e.getX(), e.getY())); - } - }; - tree.addMouseListener(userSelectionListener); - final KeyAdapter keyAdapter = new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - final int keyCode = e.getKeyCode(); - if (keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_RIGHT) { - setUserSelection(tree.getSelectionPath()); - } - } - }; - tree.addKeyListener(keyAdapter); - Disposer.register(myModel, new Disposable() { - @Override - public void dispose() { - tree.removeMouseListener(userSelectionListener); - tree.removeKeyListener(keyAdapter); + public void pass(AbstractTestProxy testProxy) { + myLastSelected = (TestProxy)testProxy; } }); choosePolicy(); } - private void setUserSelection(TreePath treePath) { - if (treePath != null) { - final Object component = treePath.getLastPathComponent(); - if (component instanceof DefaultMutableTreeNode) { - final Object userObject = ((DefaultMutableTreeNode)component).getUserObject(); - if (userObject instanceof NodeDescriptor) { - myLastSelected = (TestProxy)((NodeDescriptor)userObject).getElement(); - } - } - } - } - public void onChanged(final Boolean value) { choosePolicy(); myTrackingPolicy.apply(); diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java index d446f9c311c4..a6c33689e7b5 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java @@ -33,13 +33,13 @@ import com.intellij.openapi.progress.util.ColorProgressBar; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Pass; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.util.ClassUtil; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.table.TableView; import com.intellij.util.OpenSourceUtil; -import com.intellij.util.ui.tree.TreeUtil; import com.theoryinpractice.testng.configuration.TestNGConfiguration; import com.theoryinpractice.testng.model.*; import com.theoryinpractice.testng.util.TestNGUtil; @@ -83,6 +83,7 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn private TestNGResults.OpenSourceSelectionListener openSourceListener; private int myStatus = MessageHelper.PASSED_TEST; private Set startedMethods = new HashSet(); + private TestProxy myLastSelected; public TestNGResults(final JComponent component, final TestNGConfiguration configuration, @@ -134,6 +135,13 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn openSourceListener = new OpenSourceSelectionListener(); tree.getSelectionModel().addTreeSelectionListener(openSourceListener); + TrackRunningTestUtil.installStopListeners(tree, this, new Pass() { + @Override + public void pass(AbstractTestProxy abstractTestProxy) { + myLastSelected = (TestProxy)abstractTestProxy; + } + }); + return tree; } @@ -214,7 +222,10 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn treeBuilder.repaintWithParents(proxy); count++; if (count > total) total = count; - if (TestNGConsoleProperties.TRACK_RUNNING_TEST.value(myProperties)) { + if (myLastSelected == proxy) { + myLastSelected = null; + } + if (myLastSelected == null && TestConsoleProperties.TRACK_RUNNING_TEST.value(myProperties)) { selectTest(proxy); } return proxy; @@ -360,7 +371,7 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn } else { final DefaultMutableTreeNode node = treeBuilder.getNodeForElement(rootNode); - if (node != null) { + if (node != null && myLastSelected == null) { tree.getSelectionModel().setSelectionPath(new TreePath(node)); } } From 756e2be8673f2371718a2c6171c253fd0abc60fd Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 19 Oct 2011 16:42:58 +0200 Subject: [PATCH 036/128] testng: transitive dependencies between tests via dependsOn (IDEA-75661 ) --- .../configuration/SearchingForTestsTask.java | 60 +++++++++++++++---- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/SearchingForTestsTask.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/SearchingForTestsTask.java index f1843a740b65..44922e193601 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/configuration/SearchingForTestsTask.java +++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/SearchingForTestsTask.java @@ -292,7 +292,7 @@ public class SearchingForTestsTask extends Task.Backgroundable { TestClassFilter projectFilter = new TestClassFilter(scope.getSourceScope(myConfig).getGlobalSearchScope(), myProject, true, true); TestClassFilter filter = projectFilter.intersectionWith(PackageScope.packageScope(psiPackage, true)); - classes.putAll(calculateDependencies(null, TestNGUtil.getAllTestClasses(filter, false))); + calculateDependencies(null, classes, TestNGUtil.getAllTestClasses(filter, false)); if (classes.size() == 0) { throw new CantRunException("No tests found in the package \"" + packageName + '\"'); } @@ -319,7 +319,7 @@ public class SearchingForTestsTask extends Task.Backgroundable { })) { throw new CantRunException("Cannot test anonymous or local class \"" + data.getMainClassName() + '\"'); } - classes.putAll(calculateDependencies(null, psiClass)); + calculateDependencies(null, classes, psiClass); } else if (data.TEST_OBJECT.equals(TestType.METHOD.getType())) { //it's a method @@ -351,7 +351,7 @@ public class SearchingForTestsTask extends Task.Backgroundable { } } ); - classes.putAll(calculateDependencies(methods, psiClass)); + calculateDependencies(methods, classes, psiClass); Collection psiMethods = classes.get(psiClass); if (psiMethods == null) { psiMethods = new LinkedHashSet(); @@ -404,10 +404,16 @@ public class SearchingForTestsTask extends Task.Backgroundable { return params; } - private Map> calculateDependencies(PsiMethod[] methods, - @Nullable final PsiClass... classes) { - //we build up a list of dependencies - final Map> results = new HashMap>(); + private void calculateDependencies(PsiMethod[] methods, + final Map> results, + @Nullable final PsiClass... classes) { + calculateDependencies(methods, results, new LinkedHashSet(), classes); + } + + private void calculateDependencies(final PsiMethod[] methods, + final Map> results, + final Set alreadyMarkedToBeChecked, + @Nullable final PsiClass... classes) { if (classes != null && classes.length > 0) { final Set groupDependencies = new HashSet(); TestNGUtil.collectAnnotationValues(groupDependencies, "dependsOnGroups", methods, classes); @@ -415,6 +421,7 @@ public class SearchingForTestsTask extends Task.Backgroundable { final Set testMethodDependencies = new HashSet(); TestNGUtil.collectAnnotationValues(testMethodDependencies, "dependsOnMethods", methods, classes); + final Set membersToCheckNow = new LinkedHashSet(); if (!groupDependencies.isEmpty() || !testMethodDependencies.isEmpty()) { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { @@ -424,11 +431,15 @@ public class SearchingForTestsTask extends Task.Backgroundable { LOG.assertTrue(testAnnotation != null); for (PsiMember psiMember : AnnotatedMembersSearch.search(testAnnotation, getSearchScope())) { if (psiMember instanceof PsiMethod && testMethodDependencies.contains(psiMember.getName())) { - appendMember(psiMember, results); + if (appendMember(psiMember, alreadyMarkedToBeChecked, results)) { + membersToCheckNow.add(psiMember); + } } else if (!groupDependencies.isEmpty()) { final PsiAnnotation annotation = AnnotationUtil.findAnnotation(psiMember, TestNGUtil.TEST_ANNOTATION_FQN); if (TestNGUtil.isAnnotatedWithParameter(annotation, "groups", groupDependencies)) { - appendMember(psiMember, results); + if (appendMember(psiMember, alreadyMarkedToBeChecked, results)) { + membersToCheckNow.add(psiMember); + } } } } @@ -438,23 +449,46 @@ public class SearchingForTestsTask extends Task.Backgroundable { if (methods == null) { for (PsiClass c : classes) { - results.put(c, new LinkedHashSet()); + if (!results.containsKey(c)) { + results.put(c, new LinkedHashSet()); + } } } + for (PsiMember psiMember : membersToCheckNow) { + PsiClass psiClass; + PsiMethod[] meths = null; + if (psiMember instanceof PsiMethod) { + psiClass = psiMember.getContainingClass(); + meths = new PsiMethod[] {(PsiMethod)psiMember}; + } else { + psiClass = (PsiClass)psiMember; + } + calculateDependencies(meths, results, alreadyMarkedToBeChecked, psiClass); + } } - return results; } - private static void appendMember(final PsiMember psiMember, final Map> results) { + private static boolean appendMember(final PsiMember psiMember, + final Set underConsideration, + final Map> results) { + boolean result = false; final PsiClass psiClass = psiMember instanceof PsiClass ? ((PsiClass)psiMember) : psiMember.getContainingClass(); Collection psiMethods = results.get(psiClass); if (psiMethods == null) { psiMethods = new LinkedHashSet(); results.put(psiClass, psiMethods); + if (psiMember instanceof PsiClass) { + result = underConsideration.add(psiMember); + } } if (psiMember instanceof PsiMethod) { - psiMethods.add((PsiMethod)psiMember); + final boolean add = psiMethods.add((PsiMethod)psiMember); + if (add) { + return underConsideration.add(psiMember); + } + return false; } + return result; } private GlobalSearchScope getSearchScope() { From bc93c0c4eb5eab923b883bb89917ff047b5b7eb2 Mon Sep 17 00:00:00 2001 From: "kirill.safonov" Date: Wed, 19 Oct 2011 19:28:32 +0400 Subject: [PATCH 037/128] Astella: remove 'analyze dependencies' actions until we provide correct replacement for Java implementation (AS-44, IDEA-71243) --- resources/src/idea/JavaActions.xml | 15 +++++++++++++++ resources/src/idea/RichPlatformActions.xml | 11 +++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/resources/src/idea/JavaActions.xml b/resources/src/idea/JavaActions.xml index 7f71914a9f0a..46a184c19c13 100644 --- a/resources/src/idea/JavaActions.xml +++ b/resources/src/idea/JavaActions.xml @@ -292,5 +292,20 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/src/idea/RichPlatformActions.xml b/resources/src/idea/RichPlatformActions.xml index 04767ef2cc87..4207fa66bb1f 100644 --- a/resources/src/idea/RichPlatformActions.xml +++ b/resources/src/idea/RichPlatformActions.xml @@ -71,9 +71,6 @@ - - - @@ -90,10 +87,6 @@ - - - - @@ -316,6 +309,8 @@ + + @@ -327,7 +322,7 @@ - + From 56cd646fdfbb95c53150872abd7c3cb873cca580 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 19 Oct 2011 17:32:50 +0200 Subject: [PATCH 038/128] correct focus component --- .../JavaChangeSignatureDialog.java | 33 +++++++++++++++---- .../intellij/util/ui/table/JBListTable.java | 14 ++++++-- .../util/ui/table/JBTableRowEditor.java | 11 +------ 3 files changed, 39 insertions(+), 19 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java index fb65d00834af..deacf9a42bd6 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java @@ -59,9 +59,7 @@ import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; import javax.swing.table.TableColumn; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseEvent; +import java.awt.event.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -243,10 +241,28 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase item : myParametersTableModel.getItems()) { + final String text = item.parameter.getName(); + len = Math.max(len, text == null ? 0 : text.length()); + } + return len; + } + + private int getColumnWidth(int index) { + int letters = getTypesMaxLength() + (index == 0 ? 1 : getNamesMaxLength() + 2); Font font = EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.PLAIN); font = new Font(font.getFontName(), font.getStyle(), 12); - return (getTypesMaxLength() + 1)* Toolkit.getDefaultToolkit().getFontMetrics(font).stringWidth("W"); + return letters * Toolkit.getDefaultToolkit().getFontMetrics(font).stringWidth("W"); + } + + private int getTypesColumnWidth() { + return getColumnWidth(0); + } + + private int getNamesColumnWidth() { + return getColumnWidth(1); } @Override @@ -351,7 +367,12 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase table.getRowHeight(row)) { - new RowResizeAnimator(table, row, height).start(); + new RowResizeAnimator(table, row, height, editor).start(); } } public void removeNotify() { super.removeNotify(); - new RowResizeAnimator(table, row, table.getRowHeight()).start(); + new RowResizeAnimator(table, row, table.getRowHeight(), null).start(); } }; p.add(editor, BorderLayout.CENTER); @@ -239,14 +239,16 @@ public abstract class JBListTable extends JPanel { private final JTable myTable; private final int myRow; private int neededHeight; + private final JBTableRowEditor myEditor; private int step = 5; private int currentHeight; - private RowResizeAnimator(JTable table, int row, int height) { + private RowResizeAnimator(JTable table, int row, int height, JBTableRowEditor editor) { super("Row Animator"); myTable = table; myRow = row; neededHeight = height; + myEditor = editor; currentHeight = myTable.getRowHeight(myRow); } @@ -268,6 +270,12 @@ public abstract class JBListTable extends JPanel { }); sleep(15); } + if (myEditor != null) { + final JComponent focus = myEditor.getPreferredFocusedComponent(); + if (focus != null) { + focus.requestFocus(); + } + } } catch (InterruptedException e) { } diff --git a/platform/platform-impl/src/com/intellij/util/ui/table/JBTableRowEditor.java b/platform/platform-impl/src/com/intellij/util/ui/table/JBTableRowEditor.java index 4e7758624009..e67d01d70e8c 100644 --- a/platform/platform-impl/src/com/intellij/util/ui/table/JBTableRowEditor.java +++ b/platform/platform-impl/src/com/intellij/util/ui/table/JBTableRowEditor.java @@ -16,7 +16,6 @@ package com.intellij.util.ui.table; import com.intellij.openapi.editor.event.DocumentEvent; -import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.Nullable; @@ -47,15 +46,6 @@ public abstract class JBTableRowEditor extends JPanel { myListeners.add(listener); } - @Override - public void addNotify() { - super.addNotify(); - final JComponent c = getPreferredFocusedComponent(); - if (c != null && c.isVisible()) { - IdeFocusManager.getGlobalInstance().requestFocus(c, true); - } - } - public void fireDocumentChanged(DocumentEvent e, int column) { for (RowDocumentListener listener : myListeners) { listener.documentChanged(e, column); @@ -64,6 +54,7 @@ public abstract class JBTableRowEditor extends JPanel { @Nullable public final MouseEvent getMouseEvent() { + if (myMouseEvent != null && myMouseEvent.getClickCount() == 0) return null; return myMouseEvent; } From fcdb6c1df0719e993b05b7a062f730e66fdb3883 Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Wed, 19 Oct 2011 19:52:02 +0400 Subject: [PATCH 039/128] Fixed ugly bug in update dependencies (incremental jps). --- jps/testData/incremental/common/dependencyUpdate/.idea/.name | 1 + 1 file changed, 1 insertion(+) create mode 100644 jps/testData/incremental/common/dependencyUpdate/.idea/.name diff --git a/jps/testData/incremental/common/dependencyUpdate/.idea/.name b/jps/testData/incremental/common/dependencyUpdate/.idea/.name new file mode 100644 index 000000000000..af2bb9611b76 --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/.idea/.name @@ -0,0 +1 @@ +dependencyUpdate \ No newline at end of file From a6097bd640063dd711e86449458dc774b679433c Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Wed, 19 Oct 2011 19:56:24 +0400 Subject: [PATCH 040/128] Fixed ugly bug in update dependencies (incremental jps). --- .../org/jetbrains/ether/ProjectWrapper.java | 7 +- .../ether/dependencyView/Mappings.java | 37 ++- .../incremental/common/dependencyUpdate.log | 26 ++ .../dependencyUpdate/.idea/compiler.xml | 21 ++ .../.idea/copyright/profiles_settings.xml | 5 + .../dependencyUpdate/.idea/encodings.xml | 5 + .../common/dependencyUpdate/.idea/misc.xml | 70 +++++ .../common/dependencyUpdate/.idea/modules.xml | 9 + .../.idea/scopes/scope_settings.xml | 5 + .../dependencyUpdate/.idea/uiDesigner.xml | 125 +++++++++ .../common/dependencyUpdate/.idea/vcs.xml | 7 + .../dependencyUpdate/.idea/workspace.xml | 257 +++++++++++++++++ .../common/dependencyUpdate/A.java.new | 3 + .../dependencyUpdate/DependencyUpdate.iml | 12 + .../common/dependencyUpdate/E.java.new | 5 + .../common/dependencyUpdate/src/A.java | 3 + .../common/dependencyUpdate/src/B.java | 3 + .../common/dependencyUpdate/src/E.java | 5 + .../jetbrains/ether/IncrementalTestCase.java | 261 +++++++++--------- .../org/jetbrains/ether/TestAnnotations.java | 128 ++++----- .../jetbrains/ether/TestClassModifiers.java | 48 ++-- .../jetbrains/ether/TestClassProperties.java | 48 ++-- .../org/jetbrains/ether/TestClassRename.java | 12 +- .../org/jetbrains/ether/TestCommon.java | 76 ++--- .../jetbrains/ether/TestFieldModifiers.java | 42 +-- .../jetbrains/ether/TestFieldProperties.java | 102 +++---- .../org/jetbrains/ether/TestGenerics.java | 180 ++++++------ .../org/jetbrains/ether/TestMarkDirty.java | 12 +- .../jetbrains/ether/TestMembersChange.java | 228 +++++++-------- .../jetbrains/ether/TestMethodModifiers.java | 60 ++-- .../jetbrains/ether/TestMethodProperties.java | 36 +-- .../org/jetbrains/ether/TestPackageInfo.java | 24 +- 32 files changed, 1230 insertions(+), 632 deletions(-) create mode 100644 jps/testData/incremental/common/dependencyUpdate.log create mode 100644 jps/testData/incremental/common/dependencyUpdate/.idea/compiler.xml create mode 100644 jps/testData/incremental/common/dependencyUpdate/.idea/copyright/profiles_settings.xml create mode 100644 jps/testData/incremental/common/dependencyUpdate/.idea/encodings.xml create mode 100644 jps/testData/incremental/common/dependencyUpdate/.idea/misc.xml create mode 100644 jps/testData/incremental/common/dependencyUpdate/.idea/modules.xml create mode 100644 jps/testData/incremental/common/dependencyUpdate/.idea/scopes/scope_settings.xml create mode 100644 jps/testData/incremental/common/dependencyUpdate/.idea/uiDesigner.xml create mode 100644 jps/testData/incremental/common/dependencyUpdate/.idea/vcs.xml create mode 100644 jps/testData/incremental/common/dependencyUpdate/.idea/workspace.xml create mode 100644 jps/testData/incremental/common/dependencyUpdate/A.java.new create mode 100644 jps/testData/incremental/common/dependencyUpdate/DependencyUpdate.iml create mode 100644 jps/testData/incremental/common/dependencyUpdate/E.java.new create mode 100644 jps/testData/incremental/common/dependencyUpdate/src/A.java create mode 100644 jps/testData/incremental/common/dependencyUpdate/src/B.java create mode 100644 jps/testData/incremental/common/dependencyUpdate/src/E.java diff --git a/jps/src/org/jetbrains/ether/ProjectWrapper.java b/jps/src/org/jetbrains/ether/ProjectWrapper.java index b277658e6152..b323a7a96765 100644 --- a/jps/src/org/jetbrains/ether/ProjectWrapper.java +++ b/jps/src/org/jetbrains/ether/ProjectWrapper.java @@ -1189,7 +1189,7 @@ public class ProjectWrapper { final boolean incremental = dependencyMapping.differentiate(delta, removed, filesToCompile, compiledFiles, affectedFiles, safeFiles); - dependencyMapping.integrate(delta, removed); + dependencyMapping.integrate(delta, filesToCompile, removed); if (!incremental) { affectedFiles.addAll(sources); @@ -1286,12 +1286,15 @@ public class ProjectWrapper { return BuildStatus.FAILURE; } + final Set allFiles = new HashSet(); + for (Module m : c.getElements()) { final ModuleWrapper module = getModule(m.getName()); affectedFiles.removeAll(module.getSources(flags.tests())); + allFiles.addAll(module.getSources(flags.tests())); } - dependencyMapping.integrate(delta, removedSources); + dependencyMapping.integrate(delta, allFiles, removedSources); for (Module m : chunkModules) { Reporter.reportBuildSuccess(m, flags.tests()); diff --git a/jps/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/src/org/jetbrains/ether/dependencyView/Mappings.java index 635fdcc19e63..b6a0b45570a7 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -418,7 +418,14 @@ public class Mappings { final Set classes = (Set)delta.sourceFileToClasses.foxyGet(fileName); final Set pastClasses = (Set)sourceFileToClasses.foxyGet(fileName); - final Set dependants = (Set)fileToFileDependency.foxyGet(fileName); + final Set dependants = new HashSet(); + + final Collection dep = (Set)fileToFileDependency.foxyGet(fileName); + + if (dep != null) { + dependants.addAll(dep); + } + final Set affectedUsages = new HashSet(); final Set annotationQuery = new HashSet(); final Map usageConstraints = new HashMap(); @@ -806,11 +813,11 @@ public class Mappings { return true; } - public void integrate(final Mappings delta, final Collection removed) { - integrate(delta, cache(removed)); + public void integrate(final Mappings delta, final Collection compiled, final Collection removed) { + integrate(delta, cache(compiled), cache(removed)); } - public void integrate(final Mappings delta, final Set removed) { + public void integrate(final Mappings delta, final Collection compiled, final Set removed) { if (removed != null) { for (StringCache.S file : removed) { final Set classes = (Set)sourceFileToClasses.foxyGet(file); @@ -834,7 +841,27 @@ public class Mappings { sourceFileToUsages.putAll(delta.sourceFileToUsages); sourceFileToAnnotationUsages.putAll(delta.sourceFileToAnnotationUsages); classToSourceFile.putAll(delta.classToSourceFile); - fileToFileDependency.putAll(delta.fileToFileDependency); + + for (StringCache.S file : delta.fileToFileDependency.keySet()) { + final Collection now = delta.fileToFileDependency.foxyGet(file); + final Collection past = fileToFileDependency.foxyGet(file); + + if (past == null) { + fileToFileDependency.put(file, now); + } + else { + final Collection addSet = now; + final Collection removeSet = new HashSet(compiled); + + removeSet.removeAll(now); + + past.addAll(now); + past.removeAll(removeSet); + + fileToFileDependency.remove(file); + fileToFileDependency.put(file, past); + } + } } private void updateFormToClass(final StringCache.S formName, final StringCache.S className) { diff --git a/jps/testData/incremental/common/dependencyUpdate.log b/jps/testData/incremental/common/dependencyUpdate.log new file mode 100644 index 000000000000..9b86a837c807 --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate.log @@ -0,0 +1,26 @@ +Request to make modules: +module DependencyUpdate +End of request +digraph X { + DependencyUpdate[label="DependencyUpdate"]; +} +digraph X { + DependencyUpdate[label="DependencyUpdate"]; +} +Propagated modules: +module DependencyUpdate +End of propagated +Cleaning output files: +out/production/DependencyUpdate/A.class +out/production/DependencyUpdate/E.class +End of files +Compiling files: +src/A.java +src/E.java +End of files +Cleaning output files: +out/production/DependencyUpdate/B.class +End of files +Compiling files: +src/B.java +End of files diff --git a/jps/testData/incremental/common/dependencyUpdate/.idea/compiler.xml b/jps/testData/incremental/common/dependencyUpdate/.idea/compiler.xml new file mode 100644 index 000000000000..a1b41c52c724 --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/.idea/compiler.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/jps/testData/incremental/common/dependencyUpdate/.idea/copyright/profiles_settings.xml b/jps/testData/incremental/common/dependencyUpdate/.idea/copyright/profiles_settings.xml new file mode 100644 index 000000000000..3572571ad83c --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/.idea/copyright/profiles_settings.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jps/testData/incremental/common/dependencyUpdate/.idea/encodings.xml b/jps/testData/incremental/common/dependencyUpdate/.idea/encodings.xml new file mode 100644 index 000000000000..e206d70d8595 --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/.idea/encodings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/jps/testData/incremental/common/dependencyUpdate/.idea/misc.xml b/jps/testData/incremental/common/dependencyUpdate/.idea/misc.xml new file mode 100644 index 000000000000..f22d96b8c6a5 --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/.idea/misc.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IDEA jdk + + + + + + + + + + + + + + diff --git a/jps/testData/incremental/common/dependencyUpdate/.idea/modules.xml b/jps/testData/incremental/common/dependencyUpdate/.idea/modules.xml new file mode 100644 index 000000000000..8525221665f5 --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/jps/testData/incremental/common/dependencyUpdate/.idea/scopes/scope_settings.xml b/jps/testData/incremental/common/dependencyUpdate/.idea/scopes/scope_settings.xml new file mode 100644 index 000000000000..922003b8433b --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/jps/testData/incremental/common/dependencyUpdate/.idea/uiDesigner.xml b/jps/testData/incremental/common/dependencyUpdate/.idea/uiDesigner.xml new file mode 100644 index 000000000000..3b0002030884 --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/.idea/uiDesigner.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jps/testData/incremental/common/dependencyUpdate/.idea/vcs.xml b/jps/testData/incremental/common/dependencyUpdate/.idea/vcs.xml new file mode 100644 index 000000000000..def6a6a18457 --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/jps/testData/incremental/common/dependencyUpdate/.idea/workspace.xml b/jps/testData/incremental/common/dependencyUpdate/.idea/workspace.xml new file mode 100644 index 000000000000..0b8a72b14e93 --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/.idea/workspace.xml @@ -0,0 +1,257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + localhost + 5050 + + + + + + + + 1319035689866 + 1319035689866 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jps/testData/incremental/common/dependencyUpdate/A.java.new b/jps/testData/incremental/common/dependencyUpdate/A.java.new new file mode 100644 index 000000000000..84e5f4303b8b --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/A.java.new @@ -0,0 +1,3 @@ +interface A { + +} \ No newline at end of file diff --git a/jps/testData/incremental/common/dependencyUpdate/DependencyUpdate.iml b/jps/testData/incremental/common/dependencyUpdate/DependencyUpdate.iml new file mode 100644 index 000000000000..d5c074327501 --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/DependencyUpdate.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/jps/testData/incremental/common/dependencyUpdate/E.java.new b/jps/testData/incremental/common/dependencyUpdate/E.java.new new file mode 100644 index 000000000000..f8262bcd9ce1 --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/E.java.new @@ -0,0 +1,5 @@ +class E { + A f () { + return new A(){}; + } +} \ No newline at end of file diff --git a/jps/testData/incremental/common/dependencyUpdate/src/A.java b/jps/testData/incremental/common/dependencyUpdate/src/A.java new file mode 100644 index 000000000000..1b4568a8f26b --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/src/A.java @@ -0,0 +1,3 @@ +class A { + +} \ No newline at end of file diff --git a/jps/testData/incremental/common/dependencyUpdate/src/B.java b/jps/testData/incremental/common/dependencyUpdate/src/B.java new file mode 100644 index 000000000000..268153907494 --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/src/B.java @@ -0,0 +1,3 @@ +class B{ + +} \ No newline at end of file diff --git a/jps/testData/incremental/common/dependencyUpdate/src/E.java b/jps/testData/incremental/common/dependencyUpdate/src/E.java new file mode 100644 index 000000000000..175699a0a488 --- /dev/null +++ b/jps/testData/incremental/common/dependencyUpdate/src/E.java @@ -0,0 +1,5 @@ +class E { + A f () { + return new A(); + } +} \ No newline at end of file diff --git a/jps/testSrc/org/jetbrains/ether/IncrementalTestCase.java b/jps/testSrc/org/jetbrains/ether/IncrementalTestCase.java index 271c458831af..4b74116baecf 100644 --- a/jps/testSrc/org/jetbrains/ether/IncrementalTestCase.java +++ b/jps/testSrc/org/jetbrains/ether/IncrementalTestCase.java @@ -13,154 +13,157 @@ import java.io.*; * To change this template use File | Settings | File Templates. */ public abstract class IncrementalTestCase extends TestCase { - private final String groupName; - private final String tempDir = System.getProperty("java.io.tmpdir"); + private final String groupName; + private final String tempDir = System.getProperty("java.io.tmpdir"); - private String baseDir; - private String workDir; + private String baseDir; + private String workDir; - protected IncrementalTestCase(final String name) throws Exception { - super(name); - groupName = name; + protected IncrementalTestCase(final String name) throws Exception { + super(name); + groupName = name; + } + + @Override + protected void setUp() throws Exception { + baseDir = "jps/testData" + File.separator + "incremental" + File.separator; + + for (int i = 0; ; i++) { + final File tmp = new File(tempDir + File.separator + "__temp__" + i); + if (tmp.mkdir()) { + workDir = tmp.getPath() + File.separator; + break; + } } - @Override - protected void setUp() throws Exception { - baseDir = "jps/testData" + File.separator + "incremental" + File.separator; + copy(new File(getBaseDir()), new File(getWorkDir())); + } - for (int i = 0; ; i++) { - final File tmp = new File(tempDir + File.separator + "__temp__" + i); - if (tmp.mkdir()) { - workDir = tmp.getPath() + File.separator; - break; - } - } - - copy(new File(getBaseDir()), new File(getWorkDir())); - } - - @Override - protected void tearDown() throws Exception { + @Override + protected void tearDown() throws Exception { // delete(new File(workDir)); + } + + private String getDir(final String prefix) { + final String name = getName(); + + assert (name.startsWith("test")); + + final String result = Character.toLowerCase(name.charAt("test".length())) + name.substring("test".length() + 1); + + return prefix + File.separator + groupName + File.separator + result; + } + + private String getBaseDir() { + return getDir(baseDir); + } + + private String getWorkDir() { + return getDir(workDir); + } + + private void delete(final File file) throws Exception { + if (file.isDirectory()) { + for (File f : file.listFiles()) { + delete(f); + } } - private String getDir(final String prefix) { - final String name = getName(); + if (!file.delete()) throw new IOException("could not delete file or directory " + file.getPath()); - assert (name.startsWith("test")); + } - final String result = Character.toLowerCase(name.charAt("test".length())) + name.substring("test".length() + 1); - - return prefix + File.separator + groupName + File.separator + result; + private void copy(final File input, final File output) throws Exception { + if (input.isDirectory()) { + if (output.mkdirs()) { + for (File f : input.listFiles()) { + copy(f, new File(output.getPath() + File.separator + f.getName())); + } + } + else { + throw new IOException("unable to create directory " + output.getPath()); + } } + else if (input.isFile()) { + final FileReader in = new FileReader(input); + final FileWriter out = new FileWriter(output); + int c; - private String getBaseDir() { - return getDir(baseDir); + while ((c = in.read()) != -1) out.write(c); + + in.close(); + out.close(); } + } - private String getWorkDir() { - return getDir(workDir); + private void modify() throws Exception { + final File dir = new File(getBaseDir()); + final File[] files = dir.listFiles(new FileFilter() { + public boolean accept(final File pathname) { + final String name = pathname.getName(); + + return name.endsWith(".java.new") || name.endsWith(".java.remove"); + } + }); + + for (File input : files) { + final String name = input.getName(); + + final boolean copy = name.endsWith(".java.new"); + final String postfix = name.substring(0, name.length() - (copy ? ".new" : ".remove").length()); + final int pathSep = postfix.indexOf("$"); + final String basename = pathSep == -1 ? postfix : postfix.substring(pathSep + 1); + final String path = + getWorkDir() + File.separator + (pathSep == -1 ? "src" : postfix.substring(0, pathSep).replace('-', File.separatorChar)); + final File output = new File(path + File.separator + basename); + + if (copy) { + copy(input, output); + } + else { + output.delete(); + } } + } - private void delete(final File file) throws Exception { - if (file.isDirectory()) { - for (File f : file.listFiles()) { - delete(f); - } + public void doTest() throws Exception { + final ProjectWrapper first = ProjectWrapper.load(getWorkDir(), "project.builder.useInProcessJavac=true", false); + + first.rebuild(); + first.save(); + + Thread.sleep(1000); + + modify(); + + final ProjectWrapper second = ProjectWrapper.load(getWorkDir(), "project.builder.useInProcessJavac=true", true); + + final PrintStream stream = new PrintStream(new FileOutputStream(getWorkDir() + ".log"), true); + + try { + second.makeModule(null, new ProjectWrapper.Flags() { + public boolean tests() { + return false; } - if (!file.delete()) - throw new IOException("could not delete file or directory " + file.getPath()); - - } - - private void copy(final File input, final File output) throws Exception { - if (input.isDirectory()) { - if (output.mkdirs()) { - for (File f : input.listFiles()) { - copy(f, new File(output.getPath() + File.separator + f.getName())); - } - } else throw new IOException("unable to create directory " + output.getPath()); - } else if (input.isFile()) { - final FileReader in = new FileReader(input); - final FileWriter out = new FileWriter(output); - int c; - - while ((c = in.read()) != -1) - out.write(c); - - in.close(); - out.close(); - } - } - - private void modify() throws Exception { - final File dir = new File(getBaseDir()); - final File[] files = dir.listFiles(new FileFilter() { - public boolean accept(final File pathname) { - final String name = pathname.getName(); - - return name.endsWith(".java.new") || name.endsWith(".java.remove"); - } - } - ); - - for (File input : files) { - final String name = input.getName(); - - final boolean copy = name.endsWith(".java.new"); - final String postfix = name.substring(0, name.length() - (copy ? ".new" : ".remove").length()); - final int pathSep = postfix.indexOf("$"); - final String basename = pathSep == -1 ? postfix : postfix.substring(pathSep+1); - final String path = getWorkDir() + File.separator + (pathSep == -1 ? "src" : postfix.substring(0, pathSep).replace('-', File.separatorChar)); - final File output = new File (path + File.separator + basename); - - if (copy) { - copy (input, output); - } - else { - output.delete(); - } - } - } - - public void doTest() throws Exception { - final ProjectWrapper first = ProjectWrapper.load(getWorkDir(), "project.builder.useInProcessJavac=true", false); - - first.rebuild(); - first.save(); - - Thread.sleep(1000); - - modify(); - - final ProjectWrapper second = ProjectWrapper.load(getWorkDir(), "project.builder.useInProcessJavac=true", true); - - final PrintStream stream = new PrintStream(new FileOutputStream(getWorkDir() + ".log"), true); - - try { - second.makeModule(null, new ProjectWrapper.Flags() { - public boolean tests() { - return false; - } - - public boolean incremental() { - return true; - } - - public boolean force() { - return false; - } - - public PrintStream logStream() { - return stream; - } - }); - - } finally { - stream.close(); + public boolean incremental() { + return true; } - FileAssert.assertEquals(new File(getBaseDir() + ".log"), new File(getWorkDir() + ".log")); + public boolean force() { + return false; + } + + public PrintStream logStream() { + return stream; + } + }); + } + finally { + stream.close(); + } + + FileAssert.assertEquals(new File(getBaseDir() + ".log"), new File(getWorkDir() + ".log")); + } } diff --git a/jps/testSrc/org/jetbrains/ether/TestAnnotations.java b/jps/testSrc/org/jetbrains/ether/TestAnnotations.java index 148ff0fcd85c..89470fbfede1 100644 --- a/jps/testSrc/org/jetbrains/ether/TestAnnotations.java +++ b/jps/testSrc/org/jetbrains/ether/TestAnnotations.java @@ -8,88 +8,88 @@ package org.jetbrains.ether; * To change this template use File | Settings | File Templates. */ public class TestAnnotations extends IncrementalTestCase { - public TestAnnotations() throws Exception { - super("annotations"); - } + public TestAnnotations() throws Exception { + super("annotations"); + } - public void testAddAnnotationTarget() throws Exception { - doTest(); - } + public void testAddAnnotationTarget() throws Exception { + doTest(); + } - public void testAddAnnotationTypeMemberWithDefaultValue() throws Exception { - doTest(); - } + public void testAddAnnotationTypeMemberWithDefaultValue() throws Exception { + doTest(); + } - public void testAddAnnotationTypeMemberWithDefaultValue2() throws Exception { - doTest(); - } + public void testAddAnnotationTypeMemberWithDefaultValue2() throws Exception { + doTest(); + } - public void testAddAnnotationTypeMemberWithoutDefaultValue() throws Exception { - doTest(); - } + public void testAddAnnotationTypeMemberWithoutDefaultValue() throws Exception { + doTest(); + } - public void testAddDefaultToAnnotationMember() throws Exception { - doTest(); - } + public void testAddDefaultToAnnotationMember() throws Exception { + doTest(); + } - public void testChangeAnnotationRetentionPolicy() throws Exception { - doTest(); - } + public void testChangeAnnotationRetentionPolicy() throws Exception { + doTest(); + } - public void testChangeAnnotationRetentionPolicy1() throws Exception { - doTest(); - } + public void testChangeAnnotationRetentionPolicy1() throws Exception { + doTest(); + } - public void testChangeAnnotationRetentionPolicy2() throws Exception { - doTest(); - } + public void testChangeAnnotationRetentionPolicy2() throws Exception { + doTest(); + } - public void testChangeAnnotationRetentionPolicy3() throws Exception { - doTest(); - } + public void testChangeAnnotationRetentionPolicy3() throws Exception { + doTest(); + } - public void testChangeAnnotationRetentionPolicy4() throws Exception { - doTest(); - } + public void testChangeAnnotationRetentionPolicy4() throws Exception { + doTest(); + } - public void testChangeAnnotationTypeMemberType() throws Exception { - doTest(); - } + public void testChangeAnnotationTypeMemberType() throws Exception { + doTest(); + } - /* Discussion is needed --- unnecessarily conservative - public void testMetaAnnotationChanged() throws Exception { - doTest(); - } + /* Discussion is needed --- unnecessarily conservative + public void testMetaAnnotationChanged() throws Exception { + doTest(); + } - public void testMetaAnnotationChangedCascade() throws Exception { - doTest(); - } + public void testMetaAnnotationChangedCascade() throws Exception { + doTest(); + } - public void testMetaAnnotationChangedCascade2() throws Exception { - doTest(); - } */ + public void testMetaAnnotationChangedCascade2() throws Exception { + doTest(); + } */ - public void testRemoveAnnotationTarget() throws Exception { - doTest(); - } + public void testRemoveAnnotationTarget() throws Exception { + doTest(); + } - public void testRemoveAnnotationTypeMember() throws Exception { - doTest(); - } + public void testRemoveAnnotationTypeMember() throws Exception { + doTest(); + } - public void testRemoveAnnotationTypeMember1() throws Exception { - doTest(); - } + public void testRemoveAnnotationTypeMember1() throws Exception { + doTest(); + } - public void testRemoveDefaultFromAnnotationMember() throws Exception { - doTest(); - } + public void testRemoveDefaultFromAnnotationMember() throws Exception { + doTest(); + } - public void testConservativeNonIncremental() throws Exception { - doTest(); - } + public void testConservativeNonIncremental() throws Exception { + doTest(); + } - public void testConservativeNonIncremental1() throws Exception { - doTest(); - } + public void testConservativeNonIncremental1() throws Exception { + doTest(); + } } diff --git a/jps/testSrc/org/jetbrains/ether/TestClassModifiers.java b/jps/testSrc/org/jetbrains/ether/TestClassModifiers.java index 5b0a4ce6d3c0..a29edb74f190 100644 --- a/jps/testSrc/org/jetbrains/ether/TestClassModifiers.java +++ b/jps/testSrc/org/jetbrains/ether/TestClassModifiers.java @@ -8,35 +8,35 @@ package org.jetbrains.ether; * To change this template use File | Settings | File Templates. */ public class TestClassModifiers extends IncrementalTestCase { - public TestClassModifiers() throws Exception { - super("classModifiers"); - } + public TestClassModifiers() throws Exception { + super("classModifiers"); + } - public void testAddStatic() throws Exception { - doTest(); - } + public void testAddStatic() throws Exception { + doTest(); + } - public void testRemoveStatic() throws Exception { - doTest(); - } + public void testRemoveStatic() throws Exception { + doTest(); + } - public void testDecAccess() throws Exception { - doTest(); - } + public void testDecAccess() throws Exception { + doTest(); + } - public void testSetAbstract() throws Exception { - doTest(); - } + public void testSetAbstract() throws Exception { + doTest(); + } - public void testDropAbstract() throws Exception { - doTest(); - } + public void testDropAbstract() throws Exception { + doTest(); + } - public void testSetFinal() throws Exception { - doTest(); - } + public void testSetFinal() throws Exception { + doTest(); + } - public void testSetFinal1() throws Exception { - doTest(); - } + public void testSetFinal1() throws Exception { + doTest(); + } } diff --git a/jps/testSrc/org/jetbrains/ether/TestClassProperties.java b/jps/testSrc/org/jetbrains/ether/TestClassProperties.java index 0fb90779912c..ed4da587ca25 100644 --- a/jps/testSrc/org/jetbrains/ether/TestClassProperties.java +++ b/jps/testSrc/org/jetbrains/ether/TestClassProperties.java @@ -8,35 +8,35 @@ package org.jetbrains.ether; * To change this template use File | Settings | File Templates. */ public class TestClassProperties extends IncrementalTestCase { - public TestClassProperties() throws Exception { - super("classProperties"); - } + public TestClassProperties() throws Exception { + super("classProperties"); + } - public void testAddExtends () throws Exception { - doTest(); - } + public void testAddExtends() throws Exception { + doTest(); + } - public void testAddImplements () throws Exception { - doTest(); - } + public void testAddImplements() throws Exception { + doTest(); + } - public void testChangeExtends () throws Exception { - doTest(); - } + public void testChangeExtends() throws Exception { + doTest(); + } - public void testRemoveExtends () throws Exception { - doTest(); - } + public void testRemoveExtends() throws Exception { + doTest(); + } - public void testRemoveImplements () throws Exception { - doTest(); - } + public void testRemoveImplements() throws Exception { + doTest(); + } - public void testRemoveImplements2 () throws Exception { - doTest(); - } + public void testRemoveImplements2() throws Exception { + doTest(); + } - public void testRemoveImplements3 () throws Exception { - doTest(); - } + public void testRemoveImplements3() throws Exception { + doTest(); + } } diff --git a/jps/testSrc/org/jetbrains/ether/TestClassRename.java b/jps/testSrc/org/jetbrains/ether/TestClassRename.java index 0d0489fd1618..85ededbae714 100644 --- a/jps/testSrc/org/jetbrains/ether/TestClassRename.java +++ b/jps/testSrc/org/jetbrains/ether/TestClassRename.java @@ -8,11 +8,11 @@ package org.jetbrains.ether; * To change this template use File | Settings | File Templates. */ public class TestClassRename extends IncrementalTestCase { - public TestClassRename() throws Exception { - super("changeName"); - } + public TestClassRename() throws Exception { + super("changeName"); + } - public void testChangeClassName() throws Exception { - doTest(); - } + public void testChangeClassName() throws Exception { + doTest(); + } } diff --git a/jps/testSrc/org/jetbrains/ether/TestCommon.java b/jps/testSrc/org/jetbrains/ether/TestCommon.java index a497a80714f6..eb1427811c3e 100644 --- a/jps/testSrc/org/jetbrains/ether/TestCommon.java +++ b/jps/testSrc/org/jetbrains/ether/TestCommon.java @@ -8,51 +8,55 @@ package org.jetbrains.ether; * To change this template use File | Settings | File Templates. */ public class TestCommon extends IncrementalTestCase { - public TestCommon() throws Exception { - super("common"); - } + public TestCommon() throws Exception { + super("common"); + } - public void testAnonymous() throws Exception { - doTest(); - } + public void testAnonymous() throws Exception { + doTest(); + } - public void testChangeDefinitionToClass() throws Exception { - doTest(); - } + public void testChangeDefinitionToClass() throws Exception { + doTest(); + } - public void testChangeDefinitionToClass2() throws Exception { - doTest(); - } + public void testChangeDefinitionToClass2() throws Exception { + doTest(); + } - public void testDeleteClass() throws Exception { - doTest(); - } + public void testDeleteClass() throws Exception { + doTest(); + } - public void testDeleteClass1() throws Exception { - doTest(); - } + public void testDeleteClass1() throws Exception { + doTest(); + } - public void testDeleteClass2() throws Exception { - doTest(); - } + public void testDeleteClass2() throws Exception { + doTest(); + } - public void testDeleteClassPackageDoesntMatchRoot() throws Exception { - doTest(); - } + public void testDeleteClassPackageDoesntMatchRoot() throws Exception { + doTest(); + } - public void testInner() throws Exception { - doTest(); - } + public void testInner() throws Exception { + doTest(); + } - public void testNoResourceDelete() throws Exception { - doTest(); - } + public void testNoResourceDelete() throws Exception { + doTest(); + } - public void testNoSecondFileCompile() throws Exception { - doTest(); - } + public void testNoSecondFileCompile() throws Exception { + doTest(); + } - public void testNoSecondFileCompile1() throws Exception { - doTest(); - } + public void testNoSecondFileCompile1() throws Exception { + doTest(); + } + + public void testDependencyUpdate() throws Exception { + doTest(); + } } diff --git a/jps/testSrc/org/jetbrains/ether/TestFieldModifiers.java b/jps/testSrc/org/jetbrains/ether/TestFieldModifiers.java index 3182ba30e780..dd2b873fe1b6 100644 --- a/jps/testSrc/org/jetbrains/ether/TestFieldModifiers.java +++ b/jps/testSrc/org/jetbrains/ether/TestFieldModifiers.java @@ -8,31 +8,31 @@ package org.jetbrains.ether; * To change this template use File | Settings | File Templates. */ public class TestFieldModifiers extends IncrementalTestCase { - public TestFieldModifiers() throws Exception { - super("fieldModifiers"); - } + public TestFieldModifiers() throws Exception { + super("fieldModifiers"); + } - public void testSetFinal() throws Exception { - doTest(); - } + public void testSetFinal() throws Exception { + doTest(); + } - public void testSetPrivate() throws Exception { - doTest(); - } + public void testSetPrivate() throws Exception { + doTest(); + } - public void testSetProtected() throws Exception { - doTest(); - } + public void testSetProtected() throws Exception { + doTest(); + } - public void testSetStatic() throws Exception { - doTest(); - } + public void testSetStatic() throws Exception { + doTest(); + } - public void testUnsetStatic() throws Exception { - doTest(); - } + public void testUnsetStatic() throws Exception { + doTest(); + } - public void testUnsetStaticFinal() throws Exception { - doTest(); - } + public void testUnsetStaticFinal() throws Exception { + doTest(); + } } diff --git a/jps/testSrc/org/jetbrains/ether/TestFieldProperties.java b/jps/testSrc/org/jetbrains/ether/TestFieldProperties.java index bff4393156fe..88cc35e89ad1 100644 --- a/jps/testSrc/org/jetbrains/ether/TestFieldProperties.java +++ b/jps/testSrc/org/jetbrains/ether/TestFieldProperties.java @@ -8,71 +8,71 @@ package org.jetbrains.ether; * To change this template use File | Settings | File Templates. */ public class TestFieldProperties extends IncrementalTestCase { - public TestFieldProperties() throws Exception { - super("fieldProperties"); - } + public TestFieldProperties() throws Exception { + super("fieldProperties"); + } - public void testConstantChain() throws Exception { - doTest(); - } + public void testConstantChain() throws Exception { + doTest(); + } - public void testConstantChain1() throws Exception { - doTest(); - } + public void testConstantChain1() throws Exception { + doTest(); + } - public void testConstantChain2() throws Exception { - doTest(); - } + public void testConstantChain2() throws Exception { + doTest(); + } - public void testConstantRemove() throws Exception { - doTest(); - } + public void testConstantRemove() throws Exception { + doTest(); + } - public void testConstantRemove1() throws Exception { - doTest(); - } + public void testConstantRemove1() throws Exception { + doTest(); + } - public void testDoubleConstantChange() throws Exception { - doTest(); - } + public void testDoubleConstantChange() throws Exception { + doTest(); + } - public void testFloatConstantChange() throws Exception { - doTest(); - } + public void testFloatConstantChange() throws Exception { + doTest(); + } - public void testInnerConstantChange() throws Exception { - doTest(); - } + public void testInnerConstantChange() throws Exception { + doTest(); + } - public void testIntConstantChange() throws Exception { - doTest(); - } + public void testIntConstantChange() throws Exception { + doTest(); + } - public void testLongConstantChange() throws Exception { - doTest(); - } + public void testLongConstantChange() throws Exception { + doTest(); + } - public void testNonCompileTimeConstant() throws Exception { - doTest(); - } + public void testNonCompileTimeConstant() throws Exception { + doTest(); + } - public void testStringConstantChange() throws Exception { - doTest(); - } + public void testStringConstantChange() throws Exception { + doTest(); + } - public void testStringConstantLessAccessible() throws Exception { - doTest(); - } + public void testStringConstantLessAccessible() throws Exception { + doTest(); + } - public void testTypeChange() throws Exception { - doTest(); - } + public void testTypeChange() throws Exception { + doTest(); + } - public void testTypeChange1() throws Exception { - doTest(); - } + public void testTypeChange1() throws Exception { + doTest(); + } - public void testTypeChange2() throws Exception { - doTest(); - } + public void testTypeChange2() throws Exception { + doTest(); + } } diff --git a/jps/testSrc/org/jetbrains/ether/TestGenerics.java b/jps/testSrc/org/jetbrains/ether/TestGenerics.java index 77e28931150f..2bdbcf22ec8e 100644 --- a/jps/testSrc/org/jetbrains/ether/TestGenerics.java +++ b/jps/testSrc/org/jetbrains/ether/TestGenerics.java @@ -8,123 +8,123 @@ package org.jetbrains.ether; * To change this template use File | Settings | File Templates. */ public class TestGenerics extends IncrementalTestCase { - public TestGenerics() throws Exception { - super("generics"); - } + public TestGenerics() throws Exception { + super("generics"); + } - public void testAddMethodToBase () throws Exception { - doTest (); - } + public void testAddMethodToBase() throws Exception { + doTest(); + } - public void testAddParameterizedMethodToBase () throws Exception { - doTest (); - } + public void testAddParameterizedMethodToBase() throws Exception { + doTest(); + } - public void testChangeBound () throws Exception { - doTest (); - } + public void testChangeBound() throws Exception { + doTest(); + } - public void testChangeBound1 () throws Exception { - doTest (); - } + public void testChangeBound1() throws Exception { + doTest(); + } - public void testChangeBoundClass1 () throws Exception { - doTest (); - } + public void testChangeBoundClass1() throws Exception { + doTest(); + } - public void testChangeBoundedClass () throws Exception { - doTest (); - } + public void testChangeBoundedClass() throws Exception { + doTest(); + } - public void testChangeBoundInterface1 () throws Exception { - doTest (); - } + public void testChangeBoundInterface1() throws Exception { + doTest(); + } - public void testChangeExtends () throws Exception { - doTest (); - } + public void testChangeExtends() throws Exception { + doTest(); + } - public void testChangeExtends1 () throws Exception { - doTest (); - } + public void testChangeExtends1() throws Exception { + doTest(); + } - public void testChangeExtends2 () throws Exception { - doTest (); - } + public void testChangeExtends2() throws Exception { + doTest(); + } - public void testChangeImplements () throws Exception { - doTest (); - } + public void testChangeImplements() throws Exception { + doTest(); + } - public void testChangeInterfaceTypeParameter () throws Exception { - doTest (); - } + public void testChangeInterfaceTypeParameter() throws Exception { + doTest(); + } - public void testChangeToCovariantMethodInBase () throws Exception { - doTest (); - } + public void testChangeToCovariantMethodInBase() throws Exception { + doTest(); + } - public void testChangeToCovariantMethodInBase2 () throws Exception { - doTest (); - } + public void testChangeToCovariantMethodInBase2() throws Exception { + doTest(); + } - public void testChangeToCovariantMethodInBase3 () throws Exception { - doTest (); - } + public void testChangeToCovariantMethodInBase3() throws Exception { + doTest(); + } - public void testChangeVarargSignature () throws Exception { - doTest (); - } + public void testChangeVarargSignature() throws Exception { + doTest(); + } - public void testChangeVarargSignature1 () throws Exception { - doTest (); - } + public void testChangeVarargSignature1() throws Exception { + doTest(); + } - public void testCovariance () throws Exception { - doTest (); - } + public void testCovariance() throws Exception { + doTest(); + } - public void testCovariance1 () throws Exception { - doTest (); - } + public void testCovariance1() throws Exception { + doTest(); + } - public void testCovariance2 () throws Exception { - doTest (); - } + public void testCovariance2() throws Exception { + doTest(); + } - public void testCovarianceNoChanges () throws Exception { - doTest (); - } + public void testCovarianceNoChanges() throws Exception { + doTest(); + } - public void testDegenerify () throws Exception { - doTest (); - } + public void testDegenerify() throws Exception { + doTest(); + } - public void testDegenerify1 () throws Exception { - doTest (); - } + public void testDegenerify1() throws Exception { + doTest(); + } - public void testFieldTypeChange () throws Exception { - doTest (); - } + public void testFieldTypeChange() throws Exception { + doTest(); + } - public void testOverrideAnnotatedAnonymous () throws Exception { - doTest (); - } + public void testOverrideAnnotatedAnonymous() throws Exception { + doTest(); + } - public void testOverrideAnnotatedAnonymousNotRecompile () throws Exception { - doTest (); - } + public void testOverrideAnnotatedAnonymousNotRecompile() throws Exception { + doTest(); + } - public void testOverrideAnnotatedInner () throws Exception { - doTest (); - } + public void testOverrideAnnotatedInner() throws Exception { + doTest(); + } - public void testParamTypes () throws Exception { - doTest (); - } + public void testParamTypes() throws Exception { + doTest(); + } - public void testReturnType () throws Exception { - doTest (); - } + public void testReturnType() throws Exception { + doTest(); + } } diff --git a/jps/testSrc/org/jetbrains/ether/TestMarkDirty.java b/jps/testSrc/org/jetbrains/ether/TestMarkDirty.java index 9caaf9c8bb45..e654c13c3530 100644 --- a/jps/testSrc/org/jetbrains/ether/TestMarkDirty.java +++ b/jps/testSrc/org/jetbrains/ether/TestMarkDirty.java @@ -8,11 +8,11 @@ package org.jetbrains.ether; * To change this template use File | Settings | File Templates. */ public class TestMarkDirty extends IncrementalTestCase { - public TestMarkDirty() throws Exception { - super("markDirty"); - } + public TestMarkDirty() throws Exception { + super("markDirty"); + } - public void testRecompileDependent () throws Exception { - doTest(); - } + public void testRecompileDependent() throws Exception { + doTest(); + } } diff --git a/jps/testSrc/org/jetbrains/ether/TestMembersChange.java b/jps/testSrc/org/jetbrains/ether/TestMembersChange.java index 9d637f423734..e3e09c588dad 100644 --- a/jps/testSrc/org/jetbrains/ether/TestMembersChange.java +++ b/jps/testSrc/org/jetbrains/ether/TestMembersChange.java @@ -8,155 +8,155 @@ package org.jetbrains.ether; * To change this template use File | Settings | File Templates. */ public class TestMembersChange extends IncrementalTestCase { - public TestMembersChange() throws Exception { - super("membersChange"); - } + public TestMembersChange() throws Exception { + super("membersChange"); + } - public void testAddAbstractMethod() throws Exception { - doTest(); - } + public void testAddAbstractMethod() throws Exception { + doTest(); + } - public void testAddConstructorParameter() throws Exception { - doTest(); - } + public void testAddConstructorParameter() throws Exception { + doTest(); + } - public void testAddFieldToBaseClass() throws Exception { - doTest(); - } + public void testAddFieldToBaseClass() throws Exception { + doTest(); + } - public void testAddFieldToDerived() throws Exception { - doTest(); - } + public void testAddFieldToDerived() throws Exception { + doTest(); + } - public void testAddFieldToInterface() throws Exception { - doTest(); - } + public void testAddFieldToInterface() throws Exception { + doTest(); + } - public void testAddFieldToInterface2() throws Exception { - doTest(); - } + public void testAddFieldToInterface2() throws Exception { + doTest(); + } - public void testAddFinalMethodHavingNonFinalMethodInSubclass() throws Exception { - doTest(); - } + public void testAddFinalMethodHavingNonFinalMethodInSubclass() throws Exception { + doTest(); + } - public void testAddHidingField() throws Exception { - doTest(); - } + public void testAddHidingField() throws Exception { + doTest(); + } - public void testAddHidingMethod() throws Exception { - doTest(); - } + public void testAddHidingMethod() throws Exception { + doTest(); + } - public void testAddInterfaceMethod() throws Exception { - doTest(); - } + public void testAddInterfaceMethod() throws Exception { + doTest(); + } - public void testAddInterfaceMethod2() throws Exception { - doTest(); - } + public void testAddInterfaceMethod2() throws Exception { + doTest(); + } - public void testAddLessAccessibleFieldToDerived() throws Exception { - doTest(); - } + public void testAddLessAccessibleFieldToDerived() throws Exception { + doTest(); + } - public void testAddMethodWithIncompatibleReturnType() throws Exception { - doTest(); - } + public void testAddMethodWithIncompatibleReturnType() throws Exception { + doTest(); + } - public void testAddMoreAccessibleMethodToBase() throws Exception { - doTest(); - } + public void testAddMoreAccessibleMethodToBase() throws Exception { + doTest(); + } - public void testAddMoreSpecific() throws Exception { - doTest(); - } + public void testAddMoreSpecific() throws Exception { + doTest(); + } - public void testAddMoreSpecific1() throws Exception { - doTest(); - } + public void testAddMoreSpecific1() throws Exception { + doTest(); + } - public void testAddMoreSpecific2() throws Exception { - doTest(); - } + public void testAddMoreSpecific2() throws Exception { + doTest(); + } - public void testAddNonStaticMethodHavingStaticMethodInSubclass() throws Exception { - doTest(); - } + public void testAddNonStaticMethodHavingStaticMethodInSubclass() throws Exception { + doTest(); + } - public void testAddStaticFieldToDerived() throws Exception { - doTest(); - } + public void testAddStaticFieldToDerived() throws Exception { + doTest(); + } - public void testChangeStaticMethodSignature() throws Exception { - doTest(); - } + public void testChangeStaticMethodSignature() throws Exception { + doTest(); + } - public void testDeleteConstructor() throws Exception { - doTest(); - } + public void testDeleteConstructor() throws Exception { + doTest(); + } - public void testDeleteInner() throws Exception { - doTest(); - } + public void testDeleteInner() throws Exception { + doTest(); + } - public void testDeleteMethod() throws Exception { - doTest(); - } + public void testDeleteMethod() throws Exception { + doTest(); + } - public void testDeleteMethodImplementation() throws Exception { - doTest(); - } + public void testDeleteMethodImplementation() throws Exception { + doTest(); + } - public void testDeleteMethodImplementation2() throws Exception { - doTest(); - } + public void testDeleteMethodImplementation2() throws Exception { + doTest(); + } - public void testDeleteMethodImplementation3() throws Exception { - doTest(); - } + public void testDeleteMethodImplementation3() throws Exception { + doTest(); + } - public void testDeleteMethodImplementation4() throws Exception { - doTest(); - } + public void testDeleteMethodImplementation4() throws Exception { + doTest(); + } - public void testDeleteMethodImplementation5() throws Exception { - doTest(); - } + public void testDeleteMethodImplementation5() throws Exception { + doTest(); + } - public void testDeleteMethodImplementation6() throws Exception { - doTest(); - } + public void testDeleteMethodImplementation6() throws Exception { + doTest(); + } - public void testDeleteMethodImplementation7() throws Exception { - doTest(); - } + public void testDeleteMethodImplementation7() throws Exception { + doTest(); + } - public void testHierarchy() throws Exception { - doTest(); - } + public void testHierarchy() throws Exception { + doTest(); + } - public void testHierarchy2() throws Exception { - doTest(); - } + public void testHierarchy2() throws Exception { + doTest(); + } - public void testRemoveBaseImplementation() throws Exception { - doTest(); - } + public void testRemoveBaseImplementation() throws Exception { + doTest(); + } - public void testRemoveHidingField() throws Exception { - doTest(); - } + public void testRemoveHidingField() throws Exception { + doTest(); + } - public void testRemoveHidingMethod() throws Exception { - doTest(); - } + public void testRemoveHidingMethod() throws Exception { + doTest(); + } - public void testRenameMethod() throws Exception { - doTest(); - } + public void testRenameMethod() throws Exception { + doTest(); + } - public void testThrowsListDiffersInBaseAndDerived() throws Exception { - doTest(); - } + public void testThrowsListDiffersInBaseAndDerived() throws Exception { + doTest(); + } } diff --git a/jps/testSrc/org/jetbrains/ether/TestMethodModifiers.java b/jps/testSrc/org/jetbrains/ether/TestMethodModifiers.java index ba0105d0a8f8..c644efbf4b76 100644 --- a/jps/testSrc/org/jetbrains/ether/TestMethodModifiers.java +++ b/jps/testSrc/org/jetbrains/ether/TestMethodModifiers.java @@ -8,44 +8,44 @@ package org.jetbrains.ether; * To change this template use File | Settings | File Templates. */ public class TestMethodModifiers extends IncrementalTestCase { - public TestMethodModifiers() throws Exception { - super("methodModifiers"); - } + public TestMethodModifiers() throws Exception { + super("methodModifiers"); + } - public void testDecConstructorAccess() throws Exception { - doTest(); - } + public void testDecConstructorAccess() throws Exception { + doTest(); + } - public void testIncAccess() throws Exception { - doTest(); - } + public void testIncAccess() throws Exception { + doTest(); + } - public void testSetAbstract() throws Exception { - doTest(); - } + public void testSetAbstract() throws Exception { + doTest(); + } - public void testSetFinal() throws Exception { - doTest(); - } + public void testSetFinal() throws Exception { + doTest(); + } - public void testSetPrivate() throws Exception { - doTest(); - } + public void testSetPrivate() throws Exception { + doTest(); + } - public void testSetProtected() throws Exception { - doTest(); - } + public void testSetProtected() throws Exception { + doTest(); + } - public void testUnsetFinal() throws Exception { - doTest(); - } + public void testUnsetFinal() throws Exception { + doTest(); + } - public void testUnsetStatic() throws Exception { - doTest(); - } + public void testUnsetStatic() throws Exception { + doTest(); + } - public void testSetStatic() throws Exception { - doTest(); - } + public void testSetStatic() throws Exception { + doTest(); + } } diff --git a/jps/testSrc/org/jetbrains/ether/TestMethodProperties.java b/jps/testSrc/org/jetbrains/ether/TestMethodProperties.java index 756f76ea2c2c..e44a31b42444 100644 --- a/jps/testSrc/org/jetbrains/ether/TestMethodProperties.java +++ b/jps/testSrc/org/jetbrains/ether/TestMethodProperties.java @@ -8,27 +8,27 @@ package org.jetbrains.ether; * To change this template use File | Settings | File Templates. */ public class TestMethodProperties extends IncrementalTestCase { - public TestMethodProperties() throws Exception { - super("methodProperties"); - } + public TestMethodProperties() throws Exception { + super("methodProperties"); + } - public void testAddThrows() throws Exception { - doTest(); - } + public void testAddThrows() throws Exception { + doTest(); + } - public void testChangeReturnType() throws Exception { - doTest(); - } + public void testChangeReturnType() throws Exception { + doTest(); + } - public void testChangeReturnType1() throws Exception { - doTest(); - } + public void testChangeReturnType1() throws Exception { + doTest(); + } - public void testChangeSignature() throws Exception { - doTest(); - } + public void testChangeSignature() throws Exception { + doTest(); + } - public void testChangeSignature1() throws Exception { - doTest(); - } + public void testChangeSignature1() throws Exception { + doTest(); + } } diff --git a/jps/testSrc/org/jetbrains/ether/TestPackageInfo.java b/jps/testSrc/org/jetbrains/ether/TestPackageInfo.java index 581bd3bef127..9515b96f85b3 100644 --- a/jps/testSrc/org/jetbrains/ether/TestPackageInfo.java +++ b/jps/testSrc/org/jetbrains/ether/TestPackageInfo.java @@ -8,19 +8,19 @@ package org.jetbrains.ether; * To change this template use File | Settings | File Templates. */ public class TestPackageInfo extends IncrementalTestCase { - public TestPackageInfo() throws Exception { - super("packageInfo"); - } + public TestPackageInfo() throws Exception { + super("packageInfo"); + } - public void testPackageInfoNoRecompile() throws Exception{ - doTest(); - } + public void testPackageInfoNoRecompile() throws Exception { + doTest(); + } - public void testPackageInfoNoRecompile2() throws Exception{ - doTest(); - } + public void testPackageInfoNoRecompile2() throws Exception { + doTest(); + } - public void testPackageInfoRecompileOnConstantChange() throws Exception{ - doTest(); - } + public void testPackageInfoRecompileOnConstantChange() throws Exception { + doTest(); + } } From 670d4cee6e27cf10a0185993e80ce857b0a9fc88 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Wed, 19 Oct 2011 20:07:28 +0400 Subject: [PATCH 041/128] funcTests: registry value command --- .../openapi/ui/playback/PlaybackContext.java | 1 + .../openapi/ui/playback/PlaybackRunner.java | 33 +++++++++++-- .../commands/RegistryValueCommand.java | 47 +++++++++++++++++++ 3 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/RegistryValueCommand.java diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/playback/PlaybackContext.java b/platform/platform-impl/src/com/intellij/openapi/ui/playback/PlaybackContext.java index 815422bd3567..771ff43ac355 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/playback/PlaybackContext.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/playback/PlaybackContext.java @@ -132,4 +132,5 @@ public abstract class PlaybackContext { public abstract boolean isDisposed(); + public abstract void storeRegistryValue(String key); } diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/playback/PlaybackRunner.java b/platform/platform-impl/src/com/intellij/openapi/ui/playback/PlaybackRunner.java index e9c30d47d634..4ad2a20dd595 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/playback/PlaybackRunner.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/playback/PlaybackRunner.java @@ -27,6 +27,7 @@ import com.intellij.openapi.ui.playback.commands.ActionCommand; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.IdeFrame; import com.intellij.util.text.StringTokenizer; import org.jetbrains.annotations.Nullable; @@ -35,9 +36,7 @@ import javax.swing.*; import java.awt.*; import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; +import java.util.*; public class PlaybackRunner { @@ -65,6 +64,8 @@ public class PlaybackRunner { private long myContextTimestamp; + private Map myRegistryValues = new HashMap(); + private Disposable myOnStop = new Disposable() { @Override public void dispose() { @@ -95,6 +96,7 @@ public class PlaybackRunner { public ActionCallback run() { myStopRequested = false; + myRegistryValues.clear(); UiActivityMonitor.getInstance().clear(); myCurrentStageDepth.clear(); myPassedStages.clear(); @@ -108,6 +110,13 @@ public class PlaybackRunner { @Override public void run() { stop(); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + restoreRegistryValues(); + } + }); } }); @@ -138,6 +147,13 @@ public class PlaybackRunner { return myActionCallback; } + private void restoreRegistryValues() { + final Set storedKeys = myRegistryValues.keySet(); + for (String each : storedKeys) { + Registry.get(each).setValue(myRegistryValues.get(each)); + } + } + private void executeFrom(final int cmdIndex, File baseDir) { if (cmdIndex < myCommands.size()) { final PlaybackCommand cmd = myCommands.get(cmdIndex); @@ -176,6 +192,13 @@ public class PlaybackRunner { public boolean isDisposed() { return myTimeStamp != myContextTimestamp; } + + @Override + public void storeRegistryValue(String key) { + if (!myRegistryValues.containsKey(key)) { + myRegistryValues.put(key, Registry.stringValue(key)); + } + } }; final ActionCallback cmdCallback = cmd.execute(context); cmdCallback.doWhenDone(new Runnable() { @@ -252,7 +275,9 @@ public class PlaybackRunner { AbstractCommand cmd; String actualString = string; - if (actualString.startsWith(AbstractCommand.CMD_PREFIX + AbstractCommand.CMD_PREFIX)) { + if (actualString.startsWith(RegistryValueCommand.PREFIX)) { + cmd = new RegistryValueCommand(string, line); + } else if (actualString.startsWith(AbstractCommand.CMD_PREFIX + AbstractCommand.CMD_PREFIX)) { cmd = new EmptyCommand(line); } else if (actualString.startsWith(KeyCodeTypeCommand.PREFIX)) { diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/RegistryValueCommand.java b/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/RegistryValueCommand.java new file mode 100644 index 000000000000..36c4d3f2c62c --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/RegistryValueCommand.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2011 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.openapi.ui.playback.commands; + +import com.intellij.openapi.ui.playback.PlaybackContext; +import com.intellij.openapi.util.ActionCallback; +import com.intellij.openapi.util.registry.Registry; + +public class RegistryValueCommand extends AbstractCommand { + + public static String PREFIX = CMD_PREFIX + "set"; + + public RegistryValueCommand(String text, int line) { + super(text, line); + } + + @Override + protected ActionCallback _execute(PlaybackContext context) { + final String[] keyValue = getText().substring(PREFIX.length()).trim().split("="); + if (keyValue.length != 2) { + context.error("Expected expresstion: " + PREFIX + " key=value", getLine()); + return new ActionCallback.Rejected(); + } + + final String key = keyValue[0]; + final String value = keyValue[1]; + + context.storeRegistryValue(key); + + Registry.get(key).setValue(value); + + return new ActionCallback.Done(); + } +} From 0ba63859c0248d561c17d7f7dcd5c3f428bf78a9 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Wed, 19 Oct 2011 20:14:51 +0400 Subject: [PATCH 042/128] Optimization of GSP parser. --- .../psi/impl/source/tree/TreeUtil.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/TreeUtil.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/TreeUtil.java index dc88b337b440..a19ff2cafc8f 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/TreeUtil.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/TreeUtil.java @@ -309,24 +309,32 @@ public class TreeUtil { final IElementType searchedType, final CommonParentState commonParent, final boolean expandChameleons) { - final TreeElement[] result = {null}; - element.acceptTree(new RecursiveTreeElementWalkingVisitor(expandChameleons) { + class MyVisitor extends RecursiveTreeElementWalkingVisitor { + TreeElement result; + + MyVisitor(boolean doTransform) { + super(doTransform); + } + @Override protected void visitNode(TreeElement node) { - if (result[0] != null) return; + if (result != null) return; if (commonParent != null) { initStrongWhitespaceHolder(commonParent, node, false); } if (!expandChameleons && isCollapsedChameleon(node) || node instanceof LeafElement || node.getElementType() == searchedType) { - result[0] = node; + result = node; return; } super.visitNode(node); } - }); - return result[0]; + } + + MyVisitor visitor = new MyVisitor(expandChameleons); + element.acceptTree(visitor); + return visitor.result; } @Nullable From a40bb1bb76c8ae184c45553c808501a8cbe4d094 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Wed, 19 Oct 2011 20:38:04 +0400 Subject: [PATCH 043/128] NPE when reading after close --- .../util/src/com/intellij/util/io/PagedFileStorage.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/platform/util/src/com/intellij/util/io/PagedFileStorage.java b/platform/util/src/com/intellij/util/io/PagedFileStorage.java index d6f98827b90e..f2a1054c92f4 100644 --- a/platform/util/src/com/intellij/util/io/PagedFileStorage.java +++ b/platform/util/src/com/intellij/util/io/PagedFileStorage.java @@ -63,7 +63,7 @@ public class PagedFileStorage implements Forceable { private MappedBufferWrapper myLastBuffer2; private int myLastChangeCount; private int myLastChangeCount2; - private final int myStorageIndex; + private int myStorageIndex; private static final int MAX_PAGES_COUNT = 0xFFFF; private static final int MAX_LIVE_STORAGES_COUNT = 0xFFFF; @@ -439,6 +439,7 @@ public class PagedFileStorage implements Forceable { finally { unmapAll(); myLock.myIndex2Storage.remove(myStorageIndex); + myStorageIndex = -1; } } @@ -519,6 +520,10 @@ public class PagedFileStorage implements Forceable { try { assert page <= MAX_PAGES_COUNT; + + if (myStorageIndex == -1) { + myStorageIndex = myLock.registerPagedFileStorage(this); + } MappedBufferWrapper mappedBufferWrapper = myLock.myBuffersCache.get(myStorageIndex | page); MappedByteBuffer buf = mappedBufferWrapper.buf(); From 928a31f49a6dff131426fb022cc6b09ad9a44c73 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 19 Oct 2011 18:40:29 +0200 Subject: [PATCH 044/128] make selection softer --- .../ide/navigationToolbar/NavBarItem.java | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarItem.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarItem.java index 941431ec302c..609672d557af 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarItem.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarItem.java @@ -146,12 +146,16 @@ class NavBarItem extends SimpleColoredComponent implements Disposable { private void doPaintDecorated(Graphics2D g) { Icon icon = myIcon; - final Color bg = getBackground(); - g.setPaint(bg); + final Color bg = isSelected() && isFocused() + ? UIUtil.getListSelectionBackground() + : (UIUtil.isUnderGTKLookAndFeel() ? Color.WHITE : UIUtil.getListBackground()); + final Color c = UIUtil.getListSelectionBackground(); + final Color selBg = new Color(c.getRed(), c.getGreen(), c.getBlue(), getAlpha()); int w = getWidth(); int h = getHeight(); if (!UIUtil.isUnderAquaLookAndFeel() || myPanel.isInFloatingMode() || (isSelected() && myPanel.hasFocus())) { - g.fillRect(0, 0, w - (isLastElement() || !UIUtil.isUnderAquaLookAndFeel() ? 0 : getDecorationOffset()), h); + g.setPaint(isSelected() && isFocused() ? selBg : bg); + g.fillRect(0, 0, w - (isLastElement() /*|| !UIUtil.isUnderAquaLookAndFeel()*/ ? 0 : getDecorationOffset()), h); } final int offset = isFirstElement() ? getFirstElementLeftOffset() : 0; final int iconOffset = myPadding.left + offset; @@ -166,14 +170,14 @@ class NavBarItem extends SimpleColoredComponent implements Disposable { if (isFocused()) { if (isSelected() && !isLastElement()) { path = new Path2D.Double(); - g.translate(1, 0); + g.translate(2, 0); path.moveTo(0, 0); path.lineTo(off, h / 2); // |\ path.lineTo(0, h); // |/ path.lineTo(0, 0); - g.setColor(UIUtil.getListSelectionBackground()); + g.setColor(selBg); g.fill(path); - g.translate(-1, 0); + g.translate(-2, 0); } if (!UIUtil.isUnderAquaLookAndFeel() || myPanel.isInFloatingMode() || isNextSelected()) { @@ -185,7 +189,7 @@ class NavBarItem extends SimpleColoredComponent implements Disposable { path.lineTo(off + 2, h); // /_| path.lineTo(off + 2, 0); path.lineTo(0, 0); - g.setColor(isNextSelected() ? UIUtil.getListSelectionBackground() : UIUtil.getListBackground()); + g.setColor(isNextSelected() ? selBg : UIUtil.getListBackground()); //if (UIUtil.isUnderAquaLookAndFeel() && isNextSelected() || !UIUtil.isUnderAquaLookAndFeel()) { g.fill(path); //} @@ -194,16 +198,20 @@ class NavBarItem extends SimpleColoredComponent implements Disposable { } if (! isLastElement() && ((!isSelected() && !isNextSelected()) || !myPanel.hasFocus())) { Image img; - if (UIUtil.isUnderAquaLookAndFeel()) { - //img = myPanel.isInFloatingMode() ? SEPARATOR_PASSIVE : SEPARATOR_ACTIVE; - img = SEPARATOR_PASSIVE; - } else { - img = myPanel.isInFloatingMode() && isFocused() ? SEPARATOR_ACTIVE : SEPARATOR_PASSIVE; - } - g.drawImage(img, null, null); + //if (UIUtil.isUnderAquaLookAndFeel()) { + // //img = myPanel.isInFloatingMode() ? SEPARATOR_PASSIVE : SEPARATOR_ACTIVE; + // img = SEPARATOR_PASSIVE; + //} else { + // img = myPanel.isInFloatingMode() && isFocused() ? SEPARATOR_ACTIVE : SEPARATOR_PASSIVE; + //} + g.drawImage(SEPARATOR_PASSIVE, null, null); } } - + + private static short getAlpha() { + return 150; + } + private static int getDecorationOffset() { return 11; } From 9a60094874a212eb4f063c73d1557cf4cf978ba7 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Wed, 19 Oct 2011 20:44:51 +0400 Subject: [PATCH 045/128] funcTests: typing threading + finding editor fixes --- .../openapi/ui/playback/commands/ActionCommand.java | 7 ++++++- .../openapi/ui/playback/util/EditorPlaybackCall.java | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/ActionCommand.java b/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/ActionCommand.java index 590575979b1d..f128fdef0adc 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/ActionCommand.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/ActionCommand.java @@ -101,7 +101,12 @@ public class ActionCommand extends TypeCommand { }); am.addAnActionListener(listener.get()); - type(context.getRobot(), finalStroke); + context.runPooledThread(new Runnable() { + @Override + public void run() { + type(context.getRobot(), finalStroke); + } + }); } }); diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/playback/util/EditorPlaybackCall.java b/platform/platform-impl/src/com/intellij/openapi/ui/playback/util/EditorPlaybackCall.java index 289b53ab5ba9..7094ff09d771 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/playback/util/EditorPlaybackCall.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/playback/util/EditorPlaybackCall.java @@ -37,7 +37,11 @@ public class EditorPlaybackCall { WindowSystemPlaybackCall.getUiReady(context).doWhenDone(new Runnable() { @Override public void run() { - final Editor editor = PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContextFromFocus().getResult()); + Editor editor = PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContextFromFocus().getResult()); + if (editor == null) { + editor = PlatformDataKeys.EDITOR_EVEN_IF_INACTIVE.getData(DataManager.getInstance().getDataContextFromFocus().getResult()); + } + if (editor == null) { result.setRejected("Cannot find editor"); return; From 40b7ec9f90813af1d31896f53b1bf65662b857e3 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Wed, 19 Oct 2011 20:45:24 +0400 Subject: [PATCH 046/128] funcTests: registry values presets --- platform/funcTests/project1/module1/scripts/include/init.ijs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/funcTests/project1/module1/scripts/include/init.ijs b/platform/funcTests/project1/module1/scripts/include/init.ijs index dda3c43493d9..c3f4f72bd3e5 100644 --- a/platform/funcTests/project1/module1/scripts/include/init.ijs +++ b/platform/funcTests/project1/module1/scripts/include/init.ijs @@ -2,4 +2,7 @@ %importCall com.intellij.openapi.ui.playback.util.ProjectPlaybackCall %importCall com.intellij.openapi.ui.playback.util.EditorPlaybackCall +%set ide.mac.message.dialogs.as.sheets=false +%set ide.mac.filechooser.native=false + %cd {script.dir}/../../../.. From 8b9ea12bc9fe7e1dcb34f3e6fd5becefbe27b383 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Wed, 19 Oct 2011 20:47:19 +0400 Subject: [PATCH 047/128] funcTests: keymap for the test project --- platform/funcTests/config/keymaps/Test keymap.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platform/funcTests/config/keymaps/Test keymap.xml b/platform/funcTests/config/keymaps/Test keymap.xml index 7d9e9e9b124a..fc695a5635c8 100644 --- a/platform/funcTests/config/keymaps/Test keymap.xml +++ b/platform/funcTests/config/keymaps/Test keymap.xml @@ -7,6 +7,12 @@ + + + + + + From 5556f6950923f1987a1a3c06c12bf760183253fb Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Wed, 19 Oct 2011 20:44:20 +0400 Subject: [PATCH 048/128] schedule rebuild on IOBE (from mapping) --- .../src/com/intellij/util/indexing/FileBasedIndex.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java index 2148c616cb92..a4634a01386e 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java @@ -897,7 +897,7 @@ public class FileBasedIndex implements ApplicationComponent { } catch (RuntimeException e) { final Throwable cause = e.getCause(); - if (cause instanceof StorageException || cause instanceof IOException) { + if (cause instanceof StorageException || cause instanceof IOException || cause instanceof IndexOutOfBoundsException) { scheduleRebuild(indexId, cause); } else { From 24485e75b8af2caf6432bdbf20fd5a00cc325c43 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 19 Oct 2011 18:49:29 +0200 Subject: [PATCH 049/128] dependency analyzer integrated, initial --- jps/jps-builders/jps-builders.iml | 1 + .../jps/incremental/CompileContext.java | 7 + .../jps/incremental/java/JavaBuilder.java | 131 +++++++++++++----- .../incremental/storage/TimestampStorage.java | 4 + .../jps/server/ClasspathBootstrap.java | 3 +- .../org/jetbrains/ether/ProjectWrapper.java | 6 +- .../ether/dependencyView/Mappings.java | 46 +++--- 7 files changed, 138 insertions(+), 60 deletions(-) diff --git a/jps/jps-builders/jps-builders.iml b/jps/jps-builders/jps-builders.iml index 23359c21edff..5d8c14df6b72 100644 --- a/jps/jps-builders/jps-builders.iml +++ b/jps/jps-builders/jps-builders.iml @@ -27,6 +27,7 @@ + diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java index c230743648b6..dd2dae9e0ed1 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java @@ -3,6 +3,7 @@ package org.jetbrains.jps.incremental; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.util.containers.SLRUCache; import org.jetbrains.annotations.NotNull; +import org.jetbrains.ether.dependencyView.Mappings; import org.jetbrains.jps.Module; import org.jetbrains.jps.ModuleChunk; import org.jetbrains.jps.Project; @@ -25,6 +26,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler private final MessageHandler myDelegateMessageHandler; private volatile boolean myCompilingTests = false; private final BuildDataManager myDataManager; + private final Mappings myMappings; private SLRUCache myFilesCache = new SLRUCache(10, 10) { @NotNull @@ -39,6 +41,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler myDelegateMessageHandler = delegateMessageHandler; final File buildDataRoot = new File(System.getProperty("user.home"), ".jps" + File.separator + projectName + File.separator + "build_data"); myDataManager = new BuildDataManager(buildDataRoot); + myMappings = new Mappings(); } public Project getProject() { @@ -49,6 +52,10 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler return myIsMake; } + public Mappings getMappings() { + return myMappings; + } + public boolean isCompilingTests() { return myCompilingTests; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index 877577d546b2..e569a36e25a9 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -2,6 +2,7 @@ package org.jetbrains.jps.incremental.java; import com.intellij.compiler.notNullVerification.NotNullVerifyingInstrumenter; import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.io.FileUtil; import com.intellij.uiDesigner.compiler.*; @@ -9,6 +10,8 @@ import com.intellij.uiDesigner.core.GridConstraints; import com.intellij.uiDesigner.lw.CompiledClassPropertiesProvider; import com.intellij.uiDesigner.lw.LwRootContainer; import org.jetbrains.annotations.Nullable; +import org.jetbrains.ether.dependencyView.Callbacks; +import org.jetbrains.ether.dependencyView.Mappings; import org.jetbrains.jps.Module; import org.jetbrains.jps.ModuleChunk; import org.jetbrains.jps.ProjectPaths; @@ -54,32 +57,34 @@ public class JavaBuilder extends Builder{ } }; - //private static final Key DELTA_MAPPINGS_CALLBACK_KEY = Key.create("_dependency_data_"); + private static final Key DELTA_MAPPINGS_CALLBACK_KEY = Key.create("_dependency_data_"); + private static final Key> ALL_AFFECTED_FILES_KEY = Key.create("_all_affected_files_"); + private static final Key> ALL_COMPILED_FILES_KEY = Key.create("_all_compiled_files_"); private final EmbeddedJavac myJavacCompiler; public JavaBuilder(ExecutorService tasksExecutor) { myJavacCompiler = new EmbeddedJavac(tasksExecutor); //add here class processors in the sequence they should be executed - //myJavacCompiler.addClassProcessor(new EmbeddedJavac.ClassPostProcessor() { - // public void process(CompileContext context, OutputFileObject out) { - // final Callbacks.Backend callback = DELTA_MAPPINGS_CALLBACK_KEY.get(context); - // if (callback != null) { - // final String className = out.getClassName(); - // final OutputFileObject.Content content = out.getContent(); - // final File srcFile = out.getSourceFile(); - // if (srcFile != null && content != null) { - // // todo: the callback is not thread-safe? - // final ClassReader reader = new ClassReader(content.getBuffer(), content.getOffset(), content.getLength()); - // //noinspection SynchronizationOnLocalVariableOrMethodParameter - // synchronized (callback) { - // // todo: parse class data out of synchronized block (move it from the 'associate' implementation) - // callback.associate(className, Callbacks.getDefaultLookup(srcFile.getPath()), reader); - // } - // } - // } - // } - //}); + myJavacCompiler.addClassProcessor(new EmbeddedJavac.ClassPostProcessor() { + public void process(CompileContext context, OutputFileObject out) { + final Callbacks.Backend callback = DELTA_MAPPINGS_CALLBACK_KEY.get(context); + if (callback != null) { + final String className = out.getClassName(); + final OutputFileObject.Content content = out.getContent(); + final File srcFile = out.getSourceFile(); + if (srcFile != null && content != null) { + // todo: the callback is not thread-safe? + final ClassReader reader = new ClassReader(content.getBuffer(), content.getOffset(), content.getLength()); + //noinspection SynchronizationOnLocalVariableOrMethodParameter + synchronized (callback) { + // todo: parse class data out of synchronized block (move it from the 'associate' implementation) + callback.associate(className, Callbacks.getDefaultLookup(srcFile.getPath()), reader); + } + } + } + } + }); } public String getDescription() { @@ -89,7 +94,8 @@ public class JavaBuilder extends Builder{ public ExitCode build(final CompileContext context, final ModuleChunk chunk) throws ProjectBuildException { try { final TimestampStorage tsStorage = context.getBuildDataManager().getTimestampStorage(BUILDER_NAME); - final Set filesToCompile = new HashSet(); + final Set filesToCompile = new LinkedHashSet(); + final Set removedPaths = new HashSet(); // only collect them in make mode final List formsToCompile = new ArrayList(); final List upToDatForms = new ArrayList(); final Set srcRoots = new HashSet(); @@ -138,7 +144,9 @@ public class JavaBuilder extends Builder{ } upToDatForms.clear(); - return compile(context, chunk, filesToCompile, formsToCompile); + // todo: collect removed stuff + + return compile(context, chunk, filesToCompile, formsToCompile, removedPaths); } catch (Exception e) { String message = e.getMessage(); @@ -171,9 +179,11 @@ public class JavaBuilder extends Builder{ } } - private ExitCode compile(final CompileContext context, ModuleChunk chunk, Collection files, Collection forms) throws Exception { + private ExitCode compile(final CompileContext context, ModuleChunk chunk, Collection files, Collection forms, Set removedSources) throws Exception { + ExitCode exitCode = ExitCode.OK; + if (files.isEmpty() && forms.isEmpty()) { - return ExitCode.OK; + return exitCode; } ProjectPaths paths = ProjectPaths.KEY.get(context); @@ -181,9 +191,8 @@ public class JavaBuilder extends Builder{ ProjectPaths.KEY.set(context, paths = new ProjectPaths(context.getProject())); } - //final Mappings delta = new Mappings(null); // todo - //final Callbacks.Backend callback = delta.getCallback(); - //DELTA_MAPPINGS_CALLBACK_KEY.set(context, callback); + final Mappings delta = new Mappings(); + DELTA_MAPPINGS_CALLBACK_KEY.set(context, delta.getCallback()); // todo: consider corresponding setting in CompilerWorkspaceConfiguration final boolean addNotNullAssertions = true; @@ -195,10 +204,21 @@ public class JavaBuilder extends Builder{ final TimestampStorage tsStorage = context.getBuildDataManager().getTimestampStorage(BUILDER_NAME); + Set allCompiledFiles = ALL_COMPILED_FILES_KEY.get(context); + if (allCompiledFiles == null) { + allCompiledFiles = new HashSet(); + ALL_COMPILED_FILES_KEY.set(context, allCompiledFiles); + } + Set allAffectedFiles = ALL_AFFECTED_FILES_KEY.get(context); + if (allAffectedFiles == null) { + allAffectedFiles = new HashSet(); + ALL_AFFECTED_FILES_KEY.set(context, allAffectedFiles); + } + + // begin compilation round final DiagnosticSink diagnosticSink = new DiagnosticSink(context); final OutputFilesSink outputSink = new OutputFilesSink(context); - Collection successfulForms = Collections.emptyList(); try { boolean compiledOk = myJavacCompiler.compile(options, files, classpath, platformCp, outs, context, diagnosticSink, outputSink); @@ -229,17 +249,46 @@ public class JavaBuilder extends Builder{ if (!compiledOk || diagnosticSink.getErrorCount() > 0) { throw new ProjectBuildException("Compilation failed: errors: " + diagnosticSink.getErrorCount() + "; warnings: " + diagnosticSink.getWarningCount()); } - - return ExitCode.OK; } finally { - //DELTA_MAPPINGS_CALLBACK_KEY.set(context, callback); outputSink.writePendingData(); final Set successfullyCompiled = outputSink.getSuccessfullyCompiled(); - //delta.compensateRemovedContent(successfullyCompiled); - //globalMappings.integrate(mappings, ); //todo + final Mappings globalMappings = context.getMappings(); + + if (context.isMake()) { + DELTA_MAPPINGS_CALLBACK_KEY.set(context, null); + + // mark as affected all files that were dirty before compilation + allAffectedFiles.addAll(files); + // accumulate all successfully compiled in this round + allCompiledFiles.addAll(successfullyCompiled); + // unmark as affected all successfully compiled + allAffectedFiles.removeAll(successfullyCompiled); + + final boolean incremental = globalMappings.differentiate( + delta, removedSources, successfullyCompiled, allCompiledFiles, allAffectedFiles + ); + + if (incremental) { + final Set newlyAffectedFiles = new HashSet(allAffectedFiles); + newlyAffectedFiles.removeAll(allCompiledFiles); + for (File file : newlyAffectedFiles) { + tsStorage.markDirty(file); + } + if (chunkContainsAffectedFiles(context, chunk, newlyAffectedFiles)) { + exitCode = ExitCode.ADDITIONAL_PASS_REQUIRED; + } + } + else { + // todo + // switching into non-incremental module for this module and all those that depend on this module recursively + } + } + + globalMappings.integrate(delta, successfullyCompiled, removedSources); + for (File file : successfullyCompiled) { tsStorage.saveStamp(file); } @@ -247,6 +296,22 @@ public class JavaBuilder extends Builder{ tsStorage.saveStamp(file); } } + + return exitCode; + } + + private static boolean chunkContainsAffectedFiles(CompileContext context, ModuleChunk chunk, final Set affected) throws Exception { + final Ref result = new Ref(false); + context.processFiles(chunk, new FileProcessor() { + public boolean apply(Module module, File file, String sourceRoot) throws Exception { + if (affected.contains(file)) { + result.set(true); + return false; + } + return true; + } + }); + return result.get(); } private static ClassLoader createInstrumentationClassLoader(Collection classpath, Collection platformCp, Collection chunkSourcePath, OutputFilesSink outputSink) diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/TimestampStorage.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/TimestampStorage.java index 961131bef728..2d5225e95f34 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/TimestampStorage.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/TimestampStorage.java @@ -32,6 +32,10 @@ public class TimestampStorage extends AbstractStateStorage { private final byte[] buffer = IOUtil.allocReadWriteUTFBuffer(); diff --git a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java index eeda2adecbd3..8e3cf790d673 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java +++ b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java @@ -25,6 +25,7 @@ import gnu.trove.TIntHash; import net.n3.nanoxml.IXMLBuilder; import org.codehaus.groovy.GroovyException; import org.jetbrains.annotations.Nullable; +import org.jetbrains.ether.dependencyView.Mappings; import org.jetbrains.jps.MacroExpander; import org.objectweb.asm.ClassWriter; @@ -86,7 +87,7 @@ public class ClasspathBootstrap { cp.add(getResourcePath(optimizedFileManagerClass)); // optimizedFileManager } - //cp.add(getResourcePath(Mappings.class)); // todo: temporary + cp.add(getResourcePath(Mappings.class)); // todo: temporary //final File jpsRuntime = new File(jpsFacadeJar.getParentFile(), JPS_RUNTIME_PATH); //final File[] files = jpsRuntime.listFiles(); diff --git a/jps/src/org/jetbrains/ether/ProjectWrapper.java b/jps/src/org/jetbrains/ether/ProjectWrapper.java index b323a7a96765..03127bdd7468 100644 --- a/jps/src/org/jetbrains/ether/ProjectWrapper.java +++ b/jps/src/org/jetbrains/ether/ProjectWrapper.java @@ -865,7 +865,7 @@ public class ProjectWrapper { final String setupScript, final Map pathVariables, final boolean loadHistory) { - dependencyMapping = new Mappings(this); + dependencyMapping = new Mappings(); backendCallback = dependencyMapping.getCallback(); affectedFiles = new HashSet(); @@ -1160,7 +1160,7 @@ public class ProjectWrapper { builder.clearChunk(chunk, outputFiles, ProjectWrapper.this); } - final Mappings delta = new Mappings(ProjectWrapper.this); + final Mappings delta = new Mappings(); final Callbacks.Backend deltaBackend = delta.getCallback(); new Logger(flags) { @@ -1275,7 +1275,7 @@ public class ProjectWrapper { cleared.addAll(toClean); } - final Mappings delta = new Mappings(ProjectWrapper.this); + final Mappings delta = new Mappings(); final Callbacks.Backend deltaCallback = delta.getCallback(); try { diff --git a/jps/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/src/org/jetbrains/ether/dependencyView/Mappings.java index b6a0b45570a7..37e1518e907f 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -1,11 +1,11 @@ package org.jetbrains.ether.dependencyView; -import org.jetbrains.annotations.Nullable; +import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.ether.Pair; -import org.jetbrains.ether.ProjectWrapper; import org.objectweb.asm.ClassReader; import org.objectweb.asm.Opcodes; +import java.io.File; import java.lang.annotation.ElementType; import java.lang.annotation.RetentionPolicy; import java.util.*; @@ -366,29 +366,33 @@ public class Mappings { } } - private Set cache(final Collection x) { + private static Set cachePaths(final Collection x) { final Set y = new HashSet(); - for (String s : x) { - y.add(StringCache.get(s)); + y.add(StringCache.get(FileUtil.toSystemIndependentName(s))); } + return y; + } + private static Set cacheFiles(final Collection x) { + final Set y = new HashSet(); + for (File s : x) { + y.add(StringCache.get(FileUtil.toSystemIndependentName(s.getAbsolutePath()))); + } return y; } public boolean differentiate(final Mappings delta, - final Collection removed, - final Collection filesToCompile, - final Collection compiledFiles, - final Collection affectedFiles, - final Collection safeFiles) { - final Set affectedCache = cache(affectedFiles); + final Collection removed, + final Collection successfullyCompiled, + final Collection allCompiledFiles, + final Collection allAffectedFiles) { + final Set affectedCache = cacheFiles(allAffectedFiles); - final boolean result = - differentiate(delta, cache(removed), cache(filesToCompile), cache(compiledFiles), affectedCache, cache(safeFiles)); + final boolean result = differentiate(delta, cachePaths(removed), cacheFiles(successfullyCompiled), cacheFiles(allCompiledFiles), affectedCache, Collections.emptySet()); for (StringCache.S a : affectedCache) { - affectedFiles.add(a.value); + allAffectedFiles.add(new File(a.value)); } return result; @@ -813,8 +817,8 @@ public class Mappings { return true; } - public void integrate(final Mappings delta, final Collection compiled, final Collection removed) { - integrate(delta, cache(compiled), cache(removed)); + public void integrate(final Mappings delta, final Collection compiled, final Collection removed) { + integrate(delta, cacheFiles(compiled), cachePaths(removed)); } public void integrate(final Mappings delta, final Collection compiled, final Set removed) { @@ -920,14 +924,14 @@ public class Mappings { } public void associate(final String classFileName, final Callbacks.SourceFileNameLookup sourceFileName, final ClassReader cr) { - final StringCache.S classFileNameS = StringCache.get(project != null ? project.getRelativePath(classFileName) : classFileName); + final StringCache.S classFileNameS = StringCache.get(classFileName); final Pair>> result = ClassfileAnalyzer.analyze(classFileNameS, cr); final ClassRepr repr = result.fst; final UsageRepr.Cluster localUsages = result.snd.fst; final Set localAnnotationUsages = result.snd.snd; final String srcFileName = sourceFileName.get(repr == null ? null : repr.getSourceFileName().value); - final StringCache.S sourceFileNameS = StringCache.get(project != null ? project.getRelativePath(srcFileName) : srcFileName); + final StringCache.S sourceFileNameS = StringCache.get(srcFileName); for (UsageRepr.Usage u : localUsages.getUsages()) { updateDependency(sourceFileNameS, u.getOwner()); @@ -982,11 +986,7 @@ public class Mappings { }; } - @Nullable - private final ProjectWrapper project; - - public Mappings(@Nullable final ProjectWrapper p) { - project = p; + public Mappings() { } public Set getClasses(final StringCache.S sourceFileName) { From 8fb554f2da94976e8303c2bee4325e34348b484e Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 19 Oct 2011 18:25:45 +0200 Subject: [PATCH 050/128] for map key, don't suggest PSI candidates in completion (it's a string, dude); suggest other map keys used in the file --- .../MapArgumentCompletionProvider.java | 101 ++++++++++++------ .../arguments/GrArgumentLabelImpl.java | 22 ++-- .../expressions/literals/GrLiteralImpl.java | 8 +- .../completion/GroovyCompletionTest.groovy | 10 ++ .../completion/MapKeysUsedInFile.groovy | 3 + .../completion/NamedArgsUsedInFile.groovy | 3 + 6 files changed, 102 insertions(+), 45 deletions(-) create mode 100644 plugins/groovy/testdata/groovy/completion/MapKeysUsedInFile.groovy create mode 100644 plugins/groovy/testdata/groovy/completion/NamedArgsUsedInFile.groovy diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java index b7199d30a61c..e0e41be09b1a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java @@ -19,12 +19,11 @@ import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.patterns.ElementPattern; -import com.intellij.patterns.InitialPatternCondition; import com.intellij.patterns.StandardPatterns; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiRecursiveElementWalkingVisitor; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyIcons; import org.jetbrains.plugins.groovy.extensions.GroovyNamedArgumentProvider; import org.jetbrains.plugins.groovy.lang.completion.handlers.NamedArgumentInsertHandler; @@ -35,13 +34,14 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgument import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.patterns.GroovyElementPattern; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; +import org.jetbrains.plugins.groovy.refactoring.GroovyNamesUtil; +import java.util.Collections; +import java.util.HashMap; import java.util.Map; import static com.intellij.patterns.PlatformPatterns.psiElement; -import static org.jetbrains.plugins.groovy.lang.psi.patterns.GroovyPatterns.namedArgument; /** * @author peter @@ -55,29 +55,10 @@ class MapArgumentCompletionProvider extends CompletionProvider inArgumentListOfCall = psiElement().withParent(psiElement(GrReferenceExpression.class).withParent( - StandardPatterns.or( - psiElement(GrArgumentList.class).withParent(GrCall.class), - new GroovyElementPattern.Capture(new InitialPatternCondition(GrListOrMap.class) { - @Override - public boolean accepts(@Nullable Object o, ProcessingContext context) { - if (!(o instanceof GrListOrMap)) return false; - PsiElement parent = ((GrListOrMap)o).getParent(); - if (!(parent instanceof GrArgumentList)) return false; + StandardPatterns.or(psiElement(GrArgumentList.class), psiElement(GrListOrMap.class))) + ); - GrArgumentList argumentList = (GrArgumentList)parent; - if (argumentList.getNamedArguments().length > 0) return false; - if (argumentList.getExpressionArgumentIndex((GrListOrMap)o) > 0) return false; - - if (!(argumentList.getParent() instanceof GrCall)) return false; - - return true; - } - }) - ) - )); - - ElementPattern inLabel = psiElement(GroovyTokenTypes.mIDENT).withParent(psiElement(GrArgumentLabel.class).withParent( - namedArgument().isParameterOfMethodCall(null))); + ElementPattern inLabel = psiElement(GroovyTokenTypes.mIDENT).withParent(GrArgumentLabel.class); contributor.extend(CompletionType.BASIC, inArgumentListOfCall, instance); contributor.extend(CompletionType.BASIC, inLabel, instance); @@ -101,14 +82,18 @@ class MapArgumentCompletionProvider extends CompletionProvider 0) { + result.stopHere(); + } + } - final GrCall call = (GrCall)argumentList.getParent(); - - Map map = - GroovyNamedArgumentProvider.getNamedArgumentsFromAllProviders(call, null, true); - - for (GrNamedArgument argument : PsiUtil.getFirstMapNamedArguments(call)) { + Map map = calcNamedArgumentsForCall(mapOrArgumentList); + if (map.isEmpty()) { + map = findOtherNamedArgumentsInFile(mapOrArgumentList); + } + + for (GrNamedArgument argument : getSiblingNamedArguments(mapOrArgumentList)) { map.remove(argument.getLabelName()); } @@ -120,5 +105,55 @@ class MapArgumentCompletionProvider extends CompletionProvider findOtherNamedArgumentsInFile(PsiElement mapOrArgumentList) { + final Map map = new HashMap(); + mapOrArgumentList.getContainingFile().accept(new PsiRecursiveElementWalkingVisitor() { + @Override + public void visitElement(PsiElement element) { + if (element instanceof GrArgumentLabel) { + final String name = ((GrArgumentLabel)element).getName(); + if (GroovyNamesUtil.isIdentifier(name)) { + map.put(name, new GroovyNamedArgumentProvider.ArgumentDescriptor()); + } + } + super.visitElement(element); + } + }); + return map; + } + + private static GrNamedArgument[] getSiblingNamedArguments(PsiElement mapOrArgumentList) { + if (mapOrArgumentList instanceof GrListOrMap) { + return ((GrListOrMap)mapOrArgumentList).getNamedArguments(); + } + + PsiElement argumentList = mapOrArgumentList instanceof GrArgumentList ? mapOrArgumentList : mapOrArgumentList.getParent(); + if (argumentList instanceof GrArgumentList) { + if (argumentList.getParent() instanceof GrCall) { + return PsiUtil.getFirstMapNamedArguments((GrCall)argumentList.getParent()); + } + } + + return GrNamedArgument.EMPTY_ARRAY; + } + + private static Map calcNamedArgumentsForCall(PsiElement mapOrArgumentList) { + PsiElement argumentList = mapOrArgumentList instanceof GrArgumentList ? mapOrArgumentList : mapOrArgumentList.getParent(); + if (argumentList instanceof GrArgumentList) { + if (mapOrArgumentList instanceof GrListOrMap) { + if (((GrArgumentList)argumentList).getNamedArguments().length > 0 || + ((GrArgumentList)argumentList).getExpressionArgumentIndex((GrListOrMap)mapOrArgumentList) > 0) { + return Collections.emptyMap(); + } + } + + if (argumentList.getParent() instanceof GrCall) { + return GroovyNamedArgumentProvider.getNamedArgumentsFromAllProviders((GrCall)argumentList.getParent(), null, true); + } + } + return Collections.emptyMap(); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelImpl.java index e4c3b3693cab..44142dddea42 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelImpl.java @@ -40,7 +40,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiElementImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.literals.GrLiteralImpl; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; /** @@ -142,14 +142,7 @@ public class GrArgumentLabelImpl extends GroovyPsiElementImpl implements GrArgum public String getName() { final PsiElement element = getNameElement(); if (element instanceof GrLiteral) { - final Object value = ((GrLiteral)element).getValue(); - if (value instanceof String) { - return (String)value; - } - - if (value instanceof Number) { - return value.toString(); - } + return convertToString(((GrLiteral)element).getValue()); } if (element instanceof GrExpression) { final Object value = JavaPsiFacade.getInstance(getProject()).getConstantEvaluationHelper().computeConstantExpression(element); @@ -163,10 +156,17 @@ public class GrArgumentLabelImpl extends GroovyPsiElementImpl implements GrArgum return element.getText(); } - if (CommonClassNames.JAVA_LANG_STRING.equals(TypesUtil.getBoxedTypeName(elemType))) { - return GrStringUtil.removeQuotes(element.getText()); + return convertToString(GrLiteralImpl.getLiteralValue(element)); + } + + private static String convertToString(Object value) { + if (value instanceof String) { + return (String)value; } + if (value instanceof Number) { + return value.toString(); + } return null; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrLiteralImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrLiteralImpl.java index 8bac3d4db2e3..690f8809ad51 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrLiteralImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrLiteralImpl.java @@ -69,7 +69,10 @@ public class GrLiteralImpl extends GrExpressionImpl implements GrLiteral, PsiLan } public Object getValue() { - final PsiElement child = getFirstChild(); + return getLiteralValue(getFirstChild()); + } + + public static Object getLiteralValue(PsiElement child) { IElementType elemType = child.getNode().getElementType(); String text = child.getText(); if (TokenSets.NUMBERS.contains(elemType)) { @@ -123,6 +126,9 @@ public class GrLiteralImpl extends GrExpressionImpl implements GrLiteral, PsiLan } return StringUtil.unescapeStringCharacters(text); } + else if (elemType == mREGEX_LITERAL) { + return StringUtil.trimStart(StringUtil.trimEnd(text, "/"), "/"); + } return null; //todo } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy index f6b0fb317951..4122897e55dd 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy @@ -798,6 +798,16 @@ return foo()""" checkCompletion("new Abcd", '<', "new AbcdClass<>()") } + public void testMapKeysUsedInFile() throws Exception { + CodeInsightSettings.instance.COMPLETION_CASE_SENSITIVE = CodeInsightSettings.NONE + doVariantableTest 'foo1', 'foo3', 'foo4', 'Foo5', 'Foo7' + } + + public void testNamedArgsUsedInFile() throws Exception { + myFixture.configureByFile(getTestName(false) + ".groovy"); + doVariantableTest 'foo1', 'foo2', 'foo3', 'foo4', 'foo5', 'false', 'float' + } + public void testSuggestMembersOfExpectedType() { myFixture.addClass("enum Foo { aaaaaaaaaaaaaaaaaaaaaa, bbbbbb }") checkCompletion("Foo f = aaaaaaaa", '\n', "Foo f = Foo.aaaaaaaaaaaaaaaaaaaaaa") diff --git a/plugins/groovy/testdata/groovy/completion/MapKeysUsedInFile.groovy b/plugins/groovy/testdata/groovy/completion/MapKeysUsedInFile.groovy new file mode 100644 index 000000000000..489e2e794c1f --- /dev/null +++ b/plugins/groovy/testdata/groovy/completion/MapKeysUsedInFile.groovy @@ -0,0 +1,3 @@ +def foo2 +def map1 = [foo1:'aaa', (foo2):'bbb', 'foo3':'ccc', "foo4":'ddd', /Foo5/:'eee', foo6:'fff', (/Foo7/):'ggg'] +def map2 = [foo6:'aaa', f] diff --git a/plugins/groovy/testdata/groovy/completion/NamedArgsUsedInFile.groovy b/plugins/groovy/testdata/groovy/completion/NamedArgsUsedInFile.groovy new file mode 100644 index 000000000000..8470369d00b2 --- /dev/null +++ b/plugins/groovy/testdata/groovy/completion/NamedArgsUsedInFile.groovy @@ -0,0 +1,3 @@ +def foo2 +bar(foo1:'aaa', (foo2):'bbb', 'foo3':'ccc', "foo4":'ddd', /foo5/:2, foo6:'fff') +doo(foo6:'aaa', f) From d487353cbe6e14477a035a03ed10b50cd4622a37 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 19 Oct 2011 18:40:49 +0200 Subject: [PATCH 051/128] some groovy keyword applicability tweaks (IDEA-59627) --- .../lang/completion/GroovyCompletionData.java | 9 ++++++-- .../completion/GroovyCompletionTest.groovy | 23 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java index fc83bfcb618b..d861ebbaed2c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java @@ -70,6 +70,10 @@ public class GroovyCompletionData { public static void addGroovyKeywords(CompletionParameters parameters, CompletionResultSet result) { PsiElement position = parameters.getPosition(); PsiElement parent = position.getParent(); + if (parent instanceof GrLiteral) { + return; + } + if (!PlatformPatterns.psiElement().afterLeaf(".", ".&").accepts(position)) { if (suggestPackage(position)) { result.addElement(keyword(PsiKeyword.PACKAGE, TailType.SPACE)); @@ -82,7 +86,7 @@ public class GroovyCompletionData { addExtendsImplements(position, result); registerControlCompletion(position, result); - if (parent instanceof GrExpression && !(parent instanceof GrLiteral)) { + if (parent instanceof GrExpression) { addKeywords(result, false, PsiKeyword.TRUE, PsiKeyword.FALSE, PsiKeyword.NULL, PsiKeyword.SUPER, PsiKeyword.NEW, PsiKeyword.THIS, "as"); } @@ -523,7 +527,8 @@ public class GroovyCompletionData { if (GroovyCompletionUtil.asSimpleVariable(context) || GroovyCompletionUtil.asTypedMethod(context)) { return true; } - if (GroovyCompletionUtil.isFirstElementAfterPossibleModifiersInVariableDeclaration(context, false)) { + if (GroovyCompletionUtil.isFirstElementAfterPossibleModifiersInVariableDeclaration(context, false) && + !psiElement().afterLeaf("def").accepts(context)) { return true; } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy index 4122897e55dd..3bbbd24099bc 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy @@ -898,6 +898,29 @@ class Fopppp { public void testWordCompletionInLiterals() { checkSingleItemCompletion('def foo = "fo"', 'def foo = "foo"') } + public void testWordCompletionInLiterals2() { + checkSingleItemCompletion(''' +println "abcd" +"a" +''', ''' +println "abcd" +"abcd" +''') + } + + public void testWordCompletionInComments() { + checkSingleItemCompletion(''' +println "abcd" +// a" +''', ''' +println "abcd" +// abcd" +''') + } + + public void testNoModifiersAfterDef() throws Exception { + checkSingleItemCompletion 'def priv', 'def priv' + } public void testIfSpace() { checkCompletion 'int iff; if', ' ', "int iff; if " } From 8d71010ca58cd2de1eed7cd043652149562a455d Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 19 Oct 2011 17:57:19 +0200 Subject: [PATCH 052/128] search for colors by display name instead of types (mostly they are the same though) --- .../application/options/colors/OptionsPanelImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/OptionsPanelImpl.java b/platform/lang-impl/src/com/intellij/application/options/colors/OptionsPanelImpl.java index 0d45e1e1d5d6..48364d7d419e 100644 --- a/platform/lang-impl/src/com/intellij/application/options/colors/OptionsPanelImpl.java +++ b/platform/lang-impl/src/com/intellij/application/options/colors/OptionsPanelImpl.java @@ -136,14 +136,15 @@ public class OptionsPanelImpl extends JPanel implements OptionsPanel { } public Runnable showOption(final String option) { - + final String lowerCaseOption = option.toLowerCase(); DefaultListModel model = (DefaultListModel)myOptionsList.getModel(); for (int i = 0; i < model.size(); i++) { Object o = model.get(i); if (o instanceof EditorSchemeAttributeDescriptor) { String type = ((EditorSchemeAttributeDescriptor)o).getType(); - if (type.toLowerCase().contains(option.toLowerCase())) { + if (type.toLowerCase().contains(lowerCaseOption) || + o.toString().toLowerCase().contains(lowerCaseOption)) { final int i1 = i; return new Runnable() { public void run() { From 6b3b49817e20c4fd93d38b3f1a35c2061214057b Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 19 Oct 2011 18:09:44 +0200 Subject: [PATCH 053/128] layout --- .../com/intellij/application/options/colors/SchemesPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/SchemesPanel.java b/platform/lang-impl/src/com/intellij/application/options/colors/SchemesPanel.java index 7f06129a8085..eb83084c7790 100644 --- a/platform/lang-impl/src/com/intellij/application/options/colors/SchemesPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/colors/SchemesPanel.java @@ -134,7 +134,7 @@ public class SchemesPanel extends JPanel { } }); panel.add(myDeleteButton, - new GridBagConstraints(3, 0, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0)); + new GridBagConstraints(3, 0, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); SchemesManager schemesManager = ((EditorColorsManagerImpl)EditorColorsManager.getInstance()).getSchemesManager(); From e29f998eac6356a880139b1bdf61ac5d78ed4cc8 Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 19 Oct 2011 18:44:48 +0200 Subject: [PATCH 054/128] coverage: provide ability to quickly edit coverage colors (IDEA-75337); --- .../application/options/colors/ColorAndFontOptions.java | 2 +- .../openapi/options/colors/pages/GeneralColorsPage.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java b/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java index a3f59fd481ae..9ee900a9a06c 100644 --- a/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java +++ b/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java @@ -294,7 +294,7 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract return true; } - protected Configurable[] buildConfigurables() { + public Configurable[] buildConfigurables() { myDisposeCompleted = false; initAll(); diff --git a/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java b/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java index 997524c66c2a..9c00557dfbc4 100644 --- a/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java +++ b/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java @@ -121,6 +121,7 @@ public class GeneralColorsPage implements ColorSettingsPage, InspectionColorSett }; private static final Map ADDITIONAL_HIGHLIGHT_DESCRIPTORS = new HashMap(); + public static final String DISPLAY_NAME = OptionsBundle.message("options.general.display.name"); static{ ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("folded_text", EditorColors.FOLDED_TEXT_ATTRIBUTES); @@ -156,7 +157,7 @@ public class GeneralColorsPage implements ColorSettingsPage, InspectionColorSett @NotNull public String getDisplayName() { - return OptionsBundle.message("options.general.display.name"); + return DISPLAY_NAME; } public Icon getIcon() { From 47dbcf7a66cb62ecc04ad0b469bec3ddc006762c Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 19 Oct 2011 18:59:51 +0200 Subject: [PATCH 055/128] edit inspections colors from analyse action: correct dispose --- .../codeInspection/ex/SeverityEditorDialog.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java index b04e8c95788d..e5bebd79afbb 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java @@ -33,6 +33,7 @@ import com.intellij.openapi.editor.colors.CodeInsightColors; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.options.newEditor.OptionsEditor; @@ -152,10 +153,18 @@ public class SeverityEditorDialog extends DialogWrapper { }); } else { ColorAndFontOptions colorAndFontOptions = new ColorAndFontOptions(); - final SearchableConfigurable javaPage = colorAndFontOptions.findSubConfigurable(InspectionColorSettingsPage.class); - LOG.assertTrue(javaPage != null); - ShowSettingsUtil.getInstance().editConfigurable(PlatformDataKeys.PROJECT.getData(dataContext), javaPage); - colorAndFontOptions.disposeUIResources(); + final Configurable[] configurables = colorAndFontOptions.buildConfigurables(); + try { + final SearchableConfigurable javaPage = colorAndFontOptions.findSubConfigurable(InspectionColorSettingsPage.class); + LOG.assertTrue(javaPage != null); + ShowSettingsUtil.getInstance().editConfigurable(PlatformDataKeys.PROJECT.getData(dataContext), javaPage); + } + finally { + for (Configurable configurable : configurables) { + configurable.disposeUIResources(); + } + colorAndFontOptions.disposeUIResources(); + } } } From 1a27b1b5ce743d5322871e652d80eb1e9b3cd046 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 19 Oct 2011 20:22:22 +0200 Subject: [PATCH 056/128] move dependency logic to model --- jps/jps-builders/jps-builders.iml | 1 - jps/model/jps-model.iml | 1 + jps/{ => model}/src/org/jetbrains/ether/Pair.java | 0 jps/{ => model}/src/org/jetbrains/ether/RW.java | 0 .../src/org/jetbrains/ether/dependencyView/Callbacks.java | 0 .../src/org/jetbrains/ether/dependencyView/ClassRepr.java | 0 .../org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java | 0 .../src/org/jetbrains/ether/dependencyView/Difference.java | 0 .../src/org/jetbrains/ether/dependencyView/FieldRepr.java | 0 .../src/org/jetbrains/ether/dependencyView/FoxyMap.java | 0 .../src/org/jetbrains/ether/dependencyView/Mappings.java | 0 .../src/org/jetbrains/ether/dependencyView/MethodRepr.java | 0 .../org/jetbrains/ether/dependencyView/PackageNameSelector.java | 0 .../src/org/jetbrains/ether/dependencyView/Proto.java | 2 +- .../src/org/jetbrains/ether/dependencyView/ProtoMember.java | 2 +- .../src/org/jetbrains/ether/dependencyView/StringCache.java | 0 .../src/org/jetbrains/ether/dependencyView/TypeRepr.java | 0 .../src/org/jetbrains/ether/dependencyView/UsageRepr.java | 0 18 files changed, 3 insertions(+), 3 deletions(-) rename jps/{ => model}/src/org/jetbrains/ether/Pair.java (100%) rename jps/{ => model}/src/org/jetbrains/ether/RW.java (100%) rename jps/{ => model}/src/org/jetbrains/ether/dependencyView/Callbacks.java (100%) rename jps/{ => model}/src/org/jetbrains/ether/dependencyView/ClassRepr.java (100%) rename jps/{ => model}/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java (100%) rename jps/{ => model}/src/org/jetbrains/ether/dependencyView/Difference.java (100%) rename jps/{ => model}/src/org/jetbrains/ether/dependencyView/FieldRepr.java (100%) rename jps/{ => model}/src/org/jetbrains/ether/dependencyView/FoxyMap.java (100%) rename jps/{ => model}/src/org/jetbrains/ether/dependencyView/Mappings.java (100%) rename jps/{ => model}/src/org/jetbrains/ether/dependencyView/MethodRepr.java (100%) rename jps/{ => model}/src/org/jetbrains/ether/dependencyView/PackageNameSelector.java (100%) rename jps/{ => model}/src/org/jetbrains/ether/dependencyView/Proto.java (98%) rename jps/{ => model}/src/org/jetbrains/ether/dependencyView/ProtoMember.java (98%) rename jps/{ => model}/src/org/jetbrains/ether/dependencyView/StringCache.java (100%) rename jps/{ => model}/src/org/jetbrains/ether/dependencyView/TypeRepr.java (100%) rename jps/{ => model}/src/org/jetbrains/ether/dependencyView/UsageRepr.java (100%) diff --git a/jps/jps-builders/jps-builders.iml b/jps/jps-builders/jps-builders.iml index 5d8c14df6b72..23359c21edff 100644 --- a/jps/jps-builders/jps-builders.iml +++ b/jps/jps-builders/jps-builders.iml @@ -27,7 +27,6 @@ - diff --git a/jps/model/jps-model.iml b/jps/model/jps-model.iml index 221b97f15383..f09e08520e8b 100644 --- a/jps/model/jps-model.iml +++ b/jps/model/jps-model.iml @@ -9,6 +9,7 @@ + diff --git a/jps/src/org/jetbrains/ether/Pair.java b/jps/model/src/org/jetbrains/ether/Pair.java similarity index 100% rename from jps/src/org/jetbrains/ether/Pair.java rename to jps/model/src/org/jetbrains/ether/Pair.java diff --git a/jps/src/org/jetbrains/ether/RW.java b/jps/model/src/org/jetbrains/ether/RW.java similarity index 100% rename from jps/src/org/jetbrains/ether/RW.java rename to jps/model/src/org/jetbrains/ether/RW.java diff --git a/jps/src/org/jetbrains/ether/dependencyView/Callbacks.java b/jps/model/src/org/jetbrains/ether/dependencyView/Callbacks.java similarity index 100% rename from jps/src/org/jetbrains/ether/dependencyView/Callbacks.java rename to jps/model/src/org/jetbrains/ether/dependencyView/Callbacks.java diff --git a/jps/src/org/jetbrains/ether/dependencyView/ClassRepr.java b/jps/model/src/org/jetbrains/ether/dependencyView/ClassRepr.java similarity index 100% rename from jps/src/org/jetbrains/ether/dependencyView/ClassRepr.java rename to jps/model/src/org/jetbrains/ether/dependencyView/ClassRepr.java diff --git a/jps/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java b/jps/model/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java similarity index 100% rename from jps/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java rename to jps/model/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java diff --git a/jps/src/org/jetbrains/ether/dependencyView/Difference.java b/jps/model/src/org/jetbrains/ether/dependencyView/Difference.java similarity index 100% rename from jps/src/org/jetbrains/ether/dependencyView/Difference.java rename to jps/model/src/org/jetbrains/ether/dependencyView/Difference.java diff --git a/jps/src/org/jetbrains/ether/dependencyView/FieldRepr.java b/jps/model/src/org/jetbrains/ether/dependencyView/FieldRepr.java similarity index 100% rename from jps/src/org/jetbrains/ether/dependencyView/FieldRepr.java rename to jps/model/src/org/jetbrains/ether/dependencyView/FieldRepr.java diff --git a/jps/src/org/jetbrains/ether/dependencyView/FoxyMap.java b/jps/model/src/org/jetbrains/ether/dependencyView/FoxyMap.java similarity index 100% rename from jps/src/org/jetbrains/ether/dependencyView/FoxyMap.java rename to jps/model/src/org/jetbrains/ether/dependencyView/FoxyMap.java diff --git a/jps/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java similarity index 100% rename from jps/src/org/jetbrains/ether/dependencyView/Mappings.java rename to jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java diff --git a/jps/src/org/jetbrains/ether/dependencyView/MethodRepr.java b/jps/model/src/org/jetbrains/ether/dependencyView/MethodRepr.java similarity index 100% rename from jps/src/org/jetbrains/ether/dependencyView/MethodRepr.java rename to jps/model/src/org/jetbrains/ether/dependencyView/MethodRepr.java diff --git a/jps/src/org/jetbrains/ether/dependencyView/PackageNameSelector.java b/jps/model/src/org/jetbrains/ether/dependencyView/PackageNameSelector.java similarity index 100% rename from jps/src/org/jetbrains/ether/dependencyView/PackageNameSelector.java rename to jps/model/src/org/jetbrains/ether/dependencyView/PackageNameSelector.java diff --git a/jps/src/org/jetbrains/ether/dependencyView/Proto.java b/jps/model/src/org/jetbrains/ether/dependencyView/Proto.java similarity index 98% rename from jps/src/org/jetbrains/ether/dependencyView/Proto.java rename to jps/model/src/org/jetbrains/ether/dependencyView/Proto.java index aea00fcab802..62d5aaf45914 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/Proto.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Proto.java @@ -57,7 +57,7 @@ public abstract class Proto implements RW.Writable { @Override public boolean no() { - return base == Difference.NONE; + return base == NONE; } @Override diff --git a/jps/src/org/jetbrains/ether/dependencyView/ProtoMember.java b/jps/model/src/org/jetbrains/ether/dependencyView/ProtoMember.java similarity index 98% rename from jps/src/org/jetbrains/ether/dependencyView/ProtoMember.java rename to jps/model/src/org/jetbrains/ether/dependencyView/ProtoMember.java index f0b35cd934a9..f6d4a67759e8 100644 --- a/jps/src/org/jetbrains/ether/dependencyView/ProtoMember.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/ProtoMember.java @@ -125,7 +125,7 @@ public abstract class ProtoMember extends Proto { @Override public boolean no() { - return newBase == Difference.NONE && diff.no(); + return newBase == NONE && diff.no(); } @Override diff --git a/jps/src/org/jetbrains/ether/dependencyView/StringCache.java b/jps/model/src/org/jetbrains/ether/dependencyView/StringCache.java similarity index 100% rename from jps/src/org/jetbrains/ether/dependencyView/StringCache.java rename to jps/model/src/org/jetbrains/ether/dependencyView/StringCache.java diff --git a/jps/src/org/jetbrains/ether/dependencyView/TypeRepr.java b/jps/model/src/org/jetbrains/ether/dependencyView/TypeRepr.java similarity index 100% rename from jps/src/org/jetbrains/ether/dependencyView/TypeRepr.java rename to jps/model/src/org/jetbrains/ether/dependencyView/TypeRepr.java diff --git a/jps/src/org/jetbrains/ether/dependencyView/UsageRepr.java b/jps/model/src/org/jetbrains/ether/dependencyView/UsageRepr.java similarity index 100% rename from jps/src/org/jetbrains/ether/dependencyView/UsageRepr.java rename to jps/model/src/org/jetbrains/ether/dependencyView/UsageRepr.java From 4819536bba2405f1cf1a6a9ab4b359f7d3c63dc0 Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Thu, 20 Oct 2011 00:01:55 +0400 Subject: [PATCH 057/128] Fixed NPE in Mappings; got rid of relative paths and custom Pairs. --- jps/model/src/org/jetbrains/ether/Pair.java | 38 ------------- .../ether/dependencyView/Callbacks.java | 2 +- .../dependencyView/ClassfileAnalyzer.java | 2 +- .../ether/dependencyView/Difference.java | 2 +- .../ether/dependencyView/Mappings.java | 54 ++++++++++--------- .../org/jetbrains/ether/DirectoryScanner.java | 2 +- .../org/jetbrains/ether/ProjectWrapper.java | 37 ++++--------- 7 files changed, 43 insertions(+), 94 deletions(-) delete mode 100644 jps/model/src/org/jetbrains/ether/Pair.java diff --git a/jps/model/src/org/jetbrains/ether/Pair.java b/jps/model/src/org/jetbrains/ether/Pair.java deleted file mode 100644 index 0baef4fd92bc..000000000000 --- a/jps/model/src/org/jetbrains/ether/Pair.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.jetbrains.ether; - -/** - * Created by IntelliJ IDEA. - * User: db - * Date: 19.06.11 - * Time: 16:48 - * To change this template use File | Settings | File Templates. - */ -public class Pair { - public final X fst; - public final Y snd; - - public Pair(final X fst, final Y snd) { - this.fst = fst; - this.snd = snd; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Pair pair = (Pair)o; - - if (!fst.equals(pair.fst)) return false; - if (!snd.equals(pair.snd)) return false; - - return true; - } - - @Override - public int hashCode() { - int result = fst.hashCode(); - result = 31 * result + snd.hashCode(); - return result; - } -} diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Callbacks.java b/jps/model/src/org/jetbrains/ether/dependencyView/Callbacks.java index f89f05e6514a..e0f7c4604b44 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Callbacks.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Callbacks.java @@ -1,6 +1,6 @@ package org.jetbrains.ether.dependencyView; -import org.jetbrains.ether.Pair; +import com.intellij.openapi.util.Pair; import org.objectweb.asm.ClassReader; import java.util.Collection; diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java b/jps/model/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java index 57e01c94dd92..8b5ddf2c4bf4 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java @@ -1,6 +1,6 @@ package org.jetbrains.ether.dependencyView; -import org.jetbrains.ether.Pair; +import com.intellij.openapi.util.Pair; import org.objectweb.asm.*; import org.objectweb.asm.commons.EmptyVisitor; import org.objectweb.asm.signature.SignatureReader; diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Difference.java b/jps/model/src/org/jetbrains/ether/dependencyView/Difference.java index 4746cf7c0aca..23d672fc9037 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Difference.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Difference.java @@ -1,6 +1,6 @@ package org.jetbrains.ether.dependencyView; -import org.jetbrains.ether.Pair; +import com.intellij.openapi.util.Pair; import java.util.*; diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java index 37e1518e907f..eea73dbb2e54 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -1,7 +1,7 @@ package org.jetbrains.ether.dependencyView; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; -import org.jetbrains.ether.Pair; import org.objectweb.asm.ClassReader; import org.objectweb.asm.Opcodes; @@ -50,9 +50,7 @@ public class Mappings { private void compensateRemovedContent(final Collection compiled) { for (StringCache.S name : compiled) { - final Collection classes = sourceFileToClasses.foxyGet(name); - - if (classes == null) { + if (!sourceFileToClasses.containsKey(name)) { sourceFileToClasses.put(name, new HashSet()); } } @@ -424,7 +422,7 @@ public class Mappings { final Set pastClasses = (Set)sourceFileToClasses.foxyGet(fileName); final Set dependants = new HashSet(); - final Collection dep = (Set)fileToFileDependency.foxyGet(fileName); + final Collection dep = fileToFileDependency.foxyGet(fileName); if (dep != null) { dependants.addAll(dep); @@ -437,8 +435,8 @@ public class Mappings { final Difference.Specifier classDiff = Difference.make(pastClasses, classes); for (Pair changed : classDiff.changed()) { - final ClassRepr it = changed.fst; - final ClassRepr.Diff diff = (ClassRepr.Diff)changed.snd; + final ClassRepr it = changed.first; + final ClassRepr.Diff diff = (ClassRepr.Diff)changed.second; final int addedModifiers = diff.addedModifiers(); final int removedModifiers = diff.removedModifiers(); @@ -541,12 +539,12 @@ public class Mappings { boolean visited = false; for (Pair pp : overridenInS) { - if (pp.snd.name.equals(it.name)) { + if (pp.second.name.equals(it.name)) { continue; } visited = true; - allAbstract = ((pp.fst.access & Opcodes.ACC_ABSTRACT) > 0) || ((pp.snd.access & Opcodes.ACC_INTERFACE) > 0); + allAbstract = ((pp.first.access & Opcodes.ACC_ABSTRACT) > 0) || ((pp.second.access & Opcodes.ACC_INTERFACE) > 0); if (!allAbstract) { break; @@ -562,8 +560,8 @@ public class Mappings { } for (Pair mr : diff.methods().changed()) { - final MethodRepr m = mr.fst; - final MethodRepr.Diff d = (MethodRepr.Diff)mr.snd; + final MethodRepr m = mr.first; + final MethodRepr.Diff d = (MethodRepr.Diff)mr.second; final boolean throwsChanged = (d.exceptions().added().size() > 0) || (d.exceptions().changed().size() > 0); if (it.isAnnotation()) { @@ -652,7 +650,12 @@ public class Mappings { final Collection propagated = u.propagateFieldAccess(f.name, subClass); u.affectFieldUsages(f, propagated, f.createUsage(subClass), affectedUsages, dependants); - dependants.addAll(fileToFileDependency.foxyGet(classToSourceFile.get(subClass))); + + final Collection deps = fileToFileDependency.foxyGet(classToSourceFile.get(subClass)); + + if (deps != null) { + dependants.addAll(deps); + } } } } @@ -660,8 +663,8 @@ public class Mappings { final Collection> overriden = u.findOverridenFields(f, it); for (Pair p : overriden) { - final FieldRepr ff = p.fst; - final ClassRepr cc = p.snd; + final FieldRepr ff = p.first; + final ClassRepr cc = p.second; final boolean ffPrivate = (ff.access & Opcodes.ACC_PRIVATE) > 0; final boolean ffProtected = (ff.access & Opcodes.ACC_PROTECTED) > 0; @@ -712,8 +715,8 @@ public class Mappings { } for (Pair f : diff.fields().changed()) { - final Difference d = f.snd; - final FieldRepr field = f.fst; + final Difference d = f.second; + final FieldRepr field = f.first; if ((field.access & mask) == mask) { if ((d.base() & Difference.ACCESS) > 0 || (d.base() & Difference.VALUE) > 0) { @@ -854,7 +857,6 @@ public class Mappings { fileToFileDependency.put(file, now); } else { - final Collection addSet = now; final Collection removeSet = new HashSet(compiled); removeSet.removeAll(now); @@ -926,9 +928,9 @@ public class Mappings { public void associate(final String classFileName, final Callbacks.SourceFileNameLookup sourceFileName, final ClassReader cr) { final StringCache.S classFileNameS = StringCache.get(classFileName); final Pair>> result = ClassfileAnalyzer.analyze(classFileNameS, cr); - final ClassRepr repr = result.fst; - final UsageRepr.Cluster localUsages = result.snd.fst; - final Set localAnnotationUsages = result.snd.snd; + final ClassRepr repr = result.first; + final UsageRepr.Cluster localUsages = result.second.first; + final Set localAnnotationUsages = result.second.second; final String srcFileName = sourceFileName.get(repr == null ? null : repr.getSourceFileName().value); final StringCache.S sourceFileNameS = StringCache.get(srcFileName); @@ -960,22 +962,22 @@ public class Mappings { final String sourceFileName) { final StringCache.S sourceFileNameS = StringCache.get(sourceFileName); - updateSourceToUsages(sourceFileNameS, usages.fst); - sourceFileToAnnotationUsages.put(sourceFileNameS, usages.snd); + updateSourceToUsages(sourceFileNameS, usages.first); + sourceFileToAnnotationUsages.put(sourceFileNameS, usages.second); for (Pair> c : classes) { - final ClassRepr r = c.fst; - final Set s = c.snd; + final ClassRepr r = c.first; + final Set s = c.second; updateClassToSource(r.name, sourceFileNameS); classToSubclasses.put(r.name, s); sourceFileToClasses.put(sourceFileNameS, r); } - for (UsageRepr.Usage u : usages.fst.getUsages()) { + for (UsageRepr.Usage u : usages.first.getUsages()) { updateDependency(sourceFileNameS, u.getOwner()); } - for (UsageRepr.Usage u : usages.snd) { + for (UsageRepr.Usage u : usages.second) { updateDependency(sourceFileNameS, u.getOwner()); } } diff --git a/jps/src/org/jetbrains/ether/DirectoryScanner.java b/jps/src/org/jetbrains/ether/DirectoryScanner.java index 92cfedbe3a96..8afed0ba5fe0 100644 --- a/jps/src/org/jetbrains/ether/DirectoryScanner.java +++ b/jps/src/org/jetbrains/ether/DirectoryScanner.java @@ -166,7 +166,7 @@ public class DirectoryScanner { final Crawler cw = new Crawler(createFilter(excludes), pw); for (String root : roots) { - cw.run(new File(pw.getAbsolutePath(root))); + cw.run(new File(root)); } return cw.getResult(); diff --git a/jps/src/org/jetbrains/ether/ProjectWrapper.java b/jps/src/org/jetbrains/ether/ProjectWrapper.java index 03127bdd7468..bc4fae47358a 100644 --- a/jps/src/org/jetbrains/ether/ProjectWrapper.java +++ b/jps/src/org/jetbrains/ether/ProjectWrapper.java @@ -1,5 +1,6 @@ package org.jetbrains.ether; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import org.codehaus.gant.GantBinding; import org.codehaus.groovy.runtime.DefaultGroovyMethods; @@ -58,7 +59,7 @@ public class ProjectWrapper { public void logFilePaths(PrintStream stream, Collection paths) { List strings = new ArrayList(paths.size()); for (StringCache.S path : paths) { - strings.add(FileUtil.toSystemIndependentName(path.toString())); + strings.add(FileUtil.toSystemIndependentName(getRelativePath(path.toString()))); } logMany(stream, strings); } @@ -148,7 +149,7 @@ public class ProjectWrapper { public LibraryWrapper(final Library lib) { lib.forceInit(); myName = lib.getName(); - myClassPath = (List)getRelativePaths(lib.getClasspath(), new ArrayList()); + myClassPath = lib.getClasspath(); } public String getName() { @@ -246,7 +247,7 @@ public class ProjectWrapper { myType = null; } - myClassPath = (List)getRelativePaths(item.getClasspathRoots(null), new ArrayList()); + myClassPath = item.getClasspathRoots(null); } public GenericClasspathItemWrapper(final BufferedReader r) { @@ -282,7 +283,7 @@ public class ProjectWrapper { final long myModificationTime; FileWrapper(final File f) { - myName = StringCache.get(getRelativePath(f.getAbsolutePath())); + myName = StringCache.get(f.getAbsolutePath()); myModificationTime = f.lastModified(); } @@ -446,7 +447,7 @@ public class ProjectWrapper { } public Properties(final List sources, final String output, final Set excludes) { - myRoots = (Set)getRelativePaths(sources, new HashSet()); + myRoots = new HashSet(sources); final DirectoryScanner.Result result = DirectoryScanner.getFiles(myRoots, excludes, ProjectWrapper.this); mySources = new HashMap(); @@ -455,12 +456,12 @@ public class ProjectWrapper { mySources.put(fw, fw); } - myOutput = getRelativePath(output); + myOutput = output; updateOutputStatus(); } public void updateOutputStatus() { - final String path = getAbsolutePath(myOutput); + final String path = myOutput; final File ok = new File(path + File.separator + Reporter.myOkFlag); final File fail = new File(path + File.separator + Reporter.myFailFlag); @@ -611,7 +612,7 @@ public class ProjectWrapper { myDependsOn = null; myTestDependsOn = null; myName = m.getName(); - myExcludes = (Set)getRelativePaths(m.getExcludes(), new HashSet()); + myExcludes = new HashSet (m.getExcludes()); mySource = new Properties(m.getSourceRoots(), m.getOutputPath(), myExcludes); myTest = new Properties(m.getTestRoots(), m.getTestOutputPath(), myExcludes); @@ -925,7 +926,7 @@ public class ProjectWrapper { RW.readMany(r, StringCache.reader, affectedFiles); } - public String getAbsolutePath(final String relative) { + private String getAbsolutePath(final String relative) { if (relative == null) return relative; if (new File(relative).isAbsolute()) return relative; @@ -933,7 +934,7 @@ public class ProjectWrapper { return myRoot + File.separator + relative; } - public String getRelativePath(final String absolute) { + private String getRelativePath(final String absolute) { if (absolute == null) return absolute; if (absolute.startsWith(myRoot)) { @@ -943,22 +944,6 @@ public class ProjectWrapper { return absolute; } - public Collection getAbsolutePaths(final Collection paths, final Collection result) { - for (String path : paths) { - if (path != null) result.add(getAbsolutePath(path)); - } - - return result; - } - - public Collection getRelativePaths(final Collection paths, final Collection result) { - for (String path : paths) { - if (path != null) result.add(getRelativePath(path)); - } - - return result; - } - private boolean isHistory() { return myProject == null; } From 75815d06819aa4201fea3c40e3889075c5f3ac84 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 19 Oct 2011 21:56:43 +0200 Subject: [PATCH 058/128] cache dependency information in ServerState --- .../jetbrains/jps/incremental/CompileContext.java | 4 ++-- .../jetbrains/jps/incremental/IncProjectBuilder.java | 7 +++++-- .../jetbrains/jps/incremental/java/JavaBuilder.java | 9 +++++---- .../org/jetbrains/jps/server/ClasspathBootstrap.java | 3 --- .../src/org/jetbrains/jps/server/ServerState.java | 12 +++++++++++- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java index dd2dae9e0ed1..1f3c6fd0645b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java @@ -35,13 +35,13 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler } }; - public CompileContext(CompileScope scope, String projectName, boolean isMake, MessageHandler delegateMessageHandler) { + public CompileContext(CompileScope scope, String projectName, boolean isMake, final Mappings mappings, MessageHandler delegateMessageHandler) { myScope = scope; myIsMake = isMake; myDelegateMessageHandler = delegateMessageHandler; final File buildDataRoot = new File(System.getProperty("user.home"), ".jps" + File.separator + projectName + File.separator + "build_data"); myDataManager = new BuildDataManager(buildDataRoot); - myMappings = new Mappings(); + myMappings = mappings; } public Project getProject() { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index 3c89c2aa3811..80052589dc3d 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -1,5 +1,6 @@ package org.jetbrains.jps.incremental; +import org.jetbrains.ether.dependencyView.Mappings; import org.jetbrains.jps.*; import org.jetbrains.jps.incremental.messages.BuildMessage; import org.jetbrains.jps.incremental.messages.ProgressMessage; @@ -19,13 +20,15 @@ public class IncProjectBuilder { private ProjectChunks myProductionChunks; private ProjectChunks myTestChunks; private final List myMessageHandlers = new ArrayList(); + private final Mappings myMappings; - public IncProjectBuilder(Project project, String projectName, BuilderRegistry builderRegistry) { + public IncProjectBuilder(Project project, String projectName, final Mappings mappings, BuilderRegistry builderRegistry) { myProject = project; myProjectName = projectName; myBuilderRegistry = builderRegistry; myProductionChunks = new ProjectChunks(project, ClasspathKind.PRODUCTION_COMPILE); myTestChunks = new ProjectChunks(project, ClasspathKind.TEST_COMPILE); + myMappings = mappings; } public void addMessageHandler(MessageHandler handler) { @@ -33,7 +36,7 @@ public class IncProjectBuilder { } public void build(CompileScope scope, final boolean isMake) { - final CompileContext context = new CompileContext(scope, myProjectName, isMake, new MessageHandler() { + final CompileContext context = new CompileContext(scope, myProjectName, isMake, myMappings, new MessageHandler() { public void processMessage(BuildMessage msg) { for (MessageHandler h : myMessageHandlers) { h.processMessage(msg); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index e569a36e25a9..761b3d2bbc65 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -97,7 +97,7 @@ public class JavaBuilder extends Builder{ final Set filesToCompile = new LinkedHashSet(); final Set removedPaths = new HashSet(); // only collect them in make mode final List formsToCompile = new ArrayList(); - final List upToDatForms = new ArrayList(); + final List upToDateForms = new ArrayList(); final Set srcRoots = new HashSet(); context.processFiles(chunk, new FileProcessor() { @@ -113,7 +113,7 @@ public class JavaBuilder extends Builder{ formsToCompile.add(file); } else { - upToDatForms.add(file); + upToDateForms.add(file); } } return true; @@ -133,7 +133,7 @@ public class JavaBuilder extends Builder{ } // form should be considered dirty if the class it is bound to is also dirty! - for (File form : upToDatForms) { + for (File form : upToDateForms) { for (String root : srcRoots) { final File boundSource = getBoundSource(root, form); if (boundSource != null && filesToCompile.contains(boundSource)) { @@ -142,7 +142,7 @@ public class JavaBuilder extends Builder{ } } } - upToDatForms.clear(); + upToDateForms.clear(); // todo: collect removed stuff @@ -155,6 +155,7 @@ public class JavaBuilder extends Builder{ e.printStackTrace(new PrintStream(out)); message = "Internal error: \n" + out.toString(); } + context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, message)); throw new ProjectBuildException(message, e); } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java index 8e3cf790d673..fb83afd7c333 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java +++ b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java @@ -25,7 +25,6 @@ import gnu.trove.TIntHash; import net.n3.nanoxml.IXMLBuilder; import org.codehaus.groovy.GroovyException; import org.jetbrains.annotations.Nullable; -import org.jetbrains.ether.dependencyView.Mappings; import org.jetbrains.jps.MacroExpander; import org.objectweb.asm.ClassWriter; @@ -87,8 +86,6 @@ public class ClasspathBootstrap { cp.add(getResourcePath(optimizedFileManagerClass)); // optimizedFileManager } - cp.add(getResourcePath(Mappings.class)); // todo: temporary - //final File jpsRuntime = new File(jpsFacadeJar.getParentFile(), JPS_RUNTIME_PATH); //final File[] files = jpsRuntime.listFiles(); //if (files != null) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/server/ServerState.java b/jps/jps-builders/src/org/jetbrains/jps/server/ServerState.java index 879c5b8e1bf0..4283ce0f65b4 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/server/ServerState.java +++ b/jps/jps-builders/src/org/jetbrains/jps/server/ServerState.java @@ -1,6 +1,7 @@ package org.jetbrains.jps.server; import org.codehaus.groovy.runtime.MethodClosure; +import org.jetbrains.ether.dependencyView.Mappings; import org.jetbrains.jps.JavaSdk; import org.jetbrains.jps.Library; import org.jetbrains.jps.Module; @@ -26,6 +27,8 @@ class ServerState { public static final String IDEA_PROJECT_DIRNAME = ".idea"; private final Map myProjects = new HashMap(); + private final Map myProjectMappings = new HashMap(); + private final Object myConfigurationLock = new Object(); private final Map myPathVariables = new HashMap(); private final List myGlobalLibraries = new ArrayList(); @@ -43,11 +46,13 @@ class ServerState { public void clearProjectCache(Collection projectPaths) { synchronized (myConfigurationLock) { myProjects.keySet().removeAll(projectPaths); + myProjectMappings.keySet().removeAll(projectPaths); } } public void startBuild(String projectPath, Set modules, final BuildParameters params, final MessageHandler msgHandler) throws Throwable{ Project project; + Mappings mappings; synchronized (myConfigurationLock) { project = myProjects.get(projectPath); @@ -55,6 +60,11 @@ class ServerState { project = loadProject(projectPath, params); myProjects.put(projectPath, project); } + mappings = myProjectMappings.get(projectPath); + if (mappings == null) { + mappings = new Mappings(); + myProjectMappings.put(projectPath, mappings); + } } final List toCompile = new ArrayList(); @@ -75,7 +85,7 @@ class ServerState { } }; - final IncProjectBuilder builder = new IncProjectBuilder(project, getProjectName(projectPath), BuilderRegistry.getInstance()); + final IncProjectBuilder builder = new IncProjectBuilder(project, getProjectName(projectPath), mappings, BuilderRegistry.getInstance()); if (msgHandler != null) { builder.addMessageHandler(msgHandler); } From 6f6c2f286c069d5a933d171a7dd32212d5227d53 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Wed, 19 Oct 2011 15:30:57 +0400 Subject: [PATCH 059/128] 1. OSProcessHandler & Python process handlers were refactored (code duplication, etc.) 2. RubyProcessHandler - Kill process tree recursively 3. "soft-kill' feature for Python & Ruby process handlers --- .../process/ColoredProcessHandler.java | 4 +- .../execution/process/OSProcessHandler.java | 42 ++++++++++-- .../execution/process/OSProcessManager.java | 0 .../intellij/execution/KillableProcess.java | 0 .../KillableColoredProcessHandler.java | 67 +++++++++++++++++++ .../execution/process/RunnerMediator.java | 4 +- 6 files changed, 106 insertions(+), 11 deletions(-) rename platform/{platform-impl => platform-api}/src/com/intellij/execution/process/OSProcessManager.java (100%) rename platform/{lang-impl => platform-impl}/src/com/intellij/execution/KillableProcess.java (100%) create mode 100644 platform/platform-impl/src/com/intellij/execution/process/KillableColoredProcessHandler.java diff --git a/platform/platform-api/src/com/intellij/execution/process/ColoredProcessHandler.java b/platform/platform-api/src/com/intellij/execution/process/ColoredProcessHandler.java index fea53e6bb3f5..5d19ac93fde1 100644 --- a/platform/platform-api/src/com/intellij/execution/process/ColoredProcessHandler.java +++ b/platform/platform-api/src/com/intellij/execution/process/ColoredProcessHandler.java @@ -27,8 +27,6 @@ import org.jetbrains.annotations.Nullable; import java.nio.charset.Charset; /** - * Created by IntelliJ IDEA. - * * @author Roman Chernyatchik * @date Oct 17, 2007 */ @@ -67,7 +65,7 @@ public class ColoredProcessHandler extends OSProcessHandler { if (myCharset != null) { return myCharset; } - // Charset wan't specified - use default one + // Charset wasn't specified - use default one return super.getCharset(); } diff --git a/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java b/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java index 043b6519080a..790997889aa3 100644 --- a/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java +++ b/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java @@ -187,15 +187,28 @@ public class OSProcessHandler extends ProcessHandler { } protected void destroyProcessImpl() { - closeStreamsAndDestroyProcess(); - } - - protected void closeStreamsAndDestroyProcess() { try { closeStreams(); } finally { - myProcess.destroy(); + doDestroyProcess(); + } + } + + protected boolean shouldDestroyProcessRecursively(){ + // Override this method if you want to kill process recursively (whole process try) by default + // such behaviour is better than default java one, which doesn't kill children processes + return false; + } + + protected void doDestroyProcess() { + // Override this method if you want to customize default destroy behaviour, e.g. + // if you want use some soft-kill. + final Process process = getProcess(); + if (shouldDestroyProcessRecursively()) { + killProcessTree(process); + } else { + process.destroy(); } } @@ -212,7 +225,7 @@ public class OSProcessHandler extends ProcessHandler { executeOnPooledThread(runnable); } - private void closeStreams() { + protected void closeStreams() { try { myProcess.getOutputStream().close(); } @@ -328,4 +341,21 @@ public class OSProcessHandler extends ProcessHandler { protected abstract void textAvailable(final String s); } + + /** + * Kill whole process tree. + * @param process Process + * @param forceKill If failed to kill process tree - try to kill it using Java API + * @return True if process tree has been successfully killed. + */ + protected boolean killProcessTree(final Process process) { + LOG.debug("killing process tree"); + final boolean destroyed = OSProcessManager.getInstance().killProcessTree(process); + if (!destroyed) { + LOG.warn("Cannot kill process tree. Trying to destroy process using Java API. Cmdline:\n" + myCommandLine); + process.destroy(); + } + return destroyed; + } + } diff --git a/platform/platform-impl/src/com/intellij/execution/process/OSProcessManager.java b/platform/platform-api/src/com/intellij/execution/process/OSProcessManager.java similarity index 100% rename from platform/platform-impl/src/com/intellij/execution/process/OSProcessManager.java rename to platform/platform-api/src/com/intellij/execution/process/OSProcessManager.java diff --git a/platform/lang-impl/src/com/intellij/execution/KillableProcess.java b/platform/platform-impl/src/com/intellij/execution/KillableProcess.java similarity index 100% rename from platform/lang-impl/src/com/intellij/execution/KillableProcess.java rename to platform/platform-impl/src/com/intellij/execution/KillableProcess.java diff --git a/platform/platform-impl/src/com/intellij/execution/process/KillableColoredProcessHandler.java b/platform/platform-impl/src/com/intellij/execution/process/KillableColoredProcessHandler.java new file mode 100644 index 000000000000..0b55423f24d7 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/execution/process/KillableColoredProcessHandler.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2011 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.execution.process; + +import com.intellij.execution.KillableProcess; +import com.intellij.openapi.util.SystemInfo; +import org.jetbrains.annotations.Nullable; + +import java.nio.charset.Charset; + +/** + * @author Roman.Chernyatchik + * + * This process handler supports ANSI coloring and soft-kill feature. Soft kill works only on Unix. + * At first "stop" button send SIGINT signal to process, if it still hangs user can termintate it recursively with SIGKILL signal. + * + * P.S: probably OSProcessHandler is better place for this feature but it can affect other run configurations and should be tested + */ +public class KillableColoredProcessHandler extends ColoredProcessHandler implements KillableProcess { + public KillableColoredProcessHandler(final Process process, final String commandLine, @Nullable final Charset charset) { + super(process, commandLine, charset); + } + + public KillableColoredProcessHandler(Process process, String commandLine) { + super(process, commandLine); + } + + @Override + public boolean canKillProcess() { + // soft-kill works on Unix systems + return SystemInfo.isUnix; + } + + @Override + protected void doDestroyProcess() { + if (!canKillProcess()) { + // if soft kill isn't supported - use default implementation + super.doDestroyProcess(); + return; + } + + // Unix: [soft-kill] at first send INT signal: + final Process process = getProcess(); + UnixProcessManager.sendSigIntToProcessTree(process); + + // else IDE will suggest 'terminate dialog' + } + + @Override + public void killProcess() { + // kill -9 + killProcessTree(getProcess()); + } +} diff --git a/platform/platform-impl/src/com/intellij/execution/process/RunnerMediator.java b/platform/platform-impl/src/com/intellij/execution/process/RunnerMediator.java index 87f8af1ca40f..de56defeb3a6 100644 --- a/platform/platform-impl/src/com/intellij/execution/process/RunnerMediator.java +++ b/platform/platform-impl/src/com/intellij/execution/process/RunnerMediator.java @@ -157,9 +157,9 @@ public class RunnerMediator { } @Override - protected void destroyProcessImpl() { + protected void doDestroyProcess() { if (!RunnerMediator.destroyProcess(getProcess())) { - super.destroyProcessImpl(); + super.doDestroyProcess(); } } } From 5495b993df1f5f89e5cd30ddde52f941215c563c Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Wed, 19 Oct 2011 22:26:19 +0400 Subject: [PATCH 060/128] Launch Rails server using Runner mediator --- .../intellij/execution/ExecutionHelper.java | 23 ++++++++++++++----- .../KillableColoredProcessHandler.java | 2 +- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/ExecutionHelper.java b/platform/lang-impl/src/com/intellij/execution/ExecutionHelper.java index d8c25d9f1df1..b2a71281935a 100644 --- a/platform/lang-impl/src/com/intellij/execution/ExecutionHelper.java +++ b/platform/lang-impl/src/com/intellij/execution/ExecutionHelper.java @@ -17,6 +17,7 @@ package com.intellij.execution; import com.google.common.collect.Lists; +import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.executors.DefaultRunExecutor; import com.intellij.execution.process.OSProcessHandler; import com.intellij.execution.process.ProcessHandler; @@ -281,8 +282,16 @@ public class ExecutionHelper { public static void executeExternalProcess(@Nullable final Project myProject, - @NotNull final OSProcessHandler processHandler, - @NotNull final ExecutionMode mode) { + @NotNull final ProcessHandler processHandler, + @NotNull final ExecutionMode mode, + @NotNull final GeneralCommandLine cmdline) { + executeExternalProcess(myProject, processHandler, mode, cmdline.getCommandLineString()); + } + + public static void executeExternalProcess(@Nullable final Project myProject, + @NotNull final ProcessHandler processHandler, + @NotNull final ExecutionMode mode, + @NotNull final String presentableCmdline) { final String title = mode.getTitle() != null ? mode.getTitle() : "Please wait..."; assert title != null; @@ -299,7 +308,7 @@ public class ExecutionHelper { }; } else { - process = createTimelimitedExecutionProcess(processHandler, mode.getTimeout()); + process = createTimelimitedExecutionProcess(processHandler, mode.getTimeout(), presentableCmdline); } } if (mode.withModalProgress()) { @@ -388,8 +397,9 @@ public class ExecutionHelper { }; } - private static Runnable createTimelimitedExecutionProcess(final OSProcessHandler processHandler, - final int timeout) { + private static Runnable createTimelimitedExecutionProcess(final ProcessHandler processHandler, + final int timeout, + @NotNull final String presentableCmdline) { return new Runnable() { private final Semaphore mySemaphore = new Semaphore(); @@ -398,7 +408,8 @@ public class ExecutionHelper { try { final boolean finished = processHandler.waitFor(1000 * timeout); if (!finished) { - LOG.error("Timeout (" + timeout + " sec) on executing: " + processHandler.getCommandLine()); + final String msg = "Timeout (" + timeout + " sec) on executing: " + presentableCmdline; + LOG.error(msg); processHandler.destroyProcess(); } } diff --git a/platform/platform-impl/src/com/intellij/execution/process/KillableColoredProcessHandler.java b/platform/platform-impl/src/com/intellij/execution/process/KillableColoredProcessHandler.java index 0b55423f24d7..1bebb4a56c9d 100644 --- a/platform/platform-impl/src/com/intellij/execution/process/KillableColoredProcessHandler.java +++ b/platform/platform-impl/src/com/intellij/execution/process/KillableColoredProcessHandler.java @@ -34,7 +34,7 @@ public class KillableColoredProcessHandler extends ColoredProcessHandler impleme super(process, commandLine, charset); } - public KillableColoredProcessHandler(Process process, String commandLine) { + public KillableColoredProcessHandler(final Process process, final String commandLine) { super(process, commandLine); } From 30a80c0ed4b8d4027ccad9dcd6d131515a9f8a1c Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Thu, 20 Oct 2011 00:18:59 +0400 Subject: [PATCH 061/128] Yet another potential NPEs worked around. --- .../jetbrains/ether/dependencyView/Mappings.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java index eea73dbb2e54..e62e50a3f41f 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -250,6 +250,8 @@ public class Mappings { final boolean usages) { final StringCache.S fileName = classToSourceFile.get(className); + assert (fileName != null); + if (usages) { affectedUsages.add(reprByName(className).createUsage()); } @@ -279,7 +281,12 @@ public class Mappings { affectedUsages.add(rootUsage); for (StringCache.S p : subclasses) { - dependents.addAll(fileToFileDependency.foxyGet(classToSourceFile.get(p))); + final Collection deps = fileToFileDependency.foxyGet(classToSourceFile.get(p)); + + if (deps != null) { + dependents.addAll(deps); + } + affectedUsages.add(rootUsage instanceof UsageRepr.FieldAssignUsage ? field.createAssignUsage(p) : field.createUsage(p)); } } @@ -292,7 +299,12 @@ public class Mappings { affectedUsages.add(rootUsage); for (StringCache.S p : subclasses) { - dependents.addAll(fileToFileDependency.foxyGet(classToSourceFile.get(p))); + final Collection deps = fileToFileDependency.foxyGet(classToSourceFile.get(p)); + + if (deps != null) { + dependents.addAll(deps); + } + affectedUsages.add(method.createUsage(p)); } } From 0e24e92be760fd164ddd62763ae1c9671a7b0a37 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 19 Oct 2011 22:27:06 +0200 Subject: [PATCH 062/128] assertions --- .../impl/src/com/intellij/compiler/JpsServerManager.java | 1 + .../src/org/jetbrains/ether/dependencyView/Mappings.java | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java b/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java index 5bbd264e418f..030467761b44 100644 --- a/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java @@ -279,6 +279,7 @@ public class JpsServerManager implements ApplicationComponent{ final Sdk projectJdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk(); final GeneralCommandLine cmdLine = new GeneralCommandLine(); cmdLine.setExePath(((JavaSdkType)projectJdk.getSdkType()).getVMExecutablePath(projectJdk)); + cmdLine.addParameter("-ea"); cmdLine.addParameter("-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5008"); cmdLine.addParameter("-Xmx256m"); // todo: get this value from settings cmdLine.addParameter("-classpath"); diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java index e62e50a3f41f..df14c0a0a66d 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -640,11 +640,12 @@ public class Mappings { final Collection subClasses = getSubClasses(it.name); if (subClasses != null) { - for (StringCache.S subClass : subClasses) { + for (final StringCache.S subClass : subClasses) { final ClassRepr r = u.reprByName(subClass); + final StringCache.S sourceFileName = classToSourceFile.get(subClass); + assert sourceFileName != null; if (r != null) { - final StringCache.S sourceFileName = classToSourceFile.get(subClass); if (r.isLocal) { affectedFiles.add(sourceFileName); @@ -663,7 +664,7 @@ public class Mappings { final Collection propagated = u.propagateFieldAccess(f.name, subClass); u.affectFieldUsages(f, propagated, f.createUsage(subClass), affectedUsages, dependants); - final Collection deps = fileToFileDependency.foxyGet(classToSourceFile.get(subClass)); + final Collection deps = fileToFileDependency.foxyGet(sourceFileName); if (deps != null) { dependants.addAll(deps); From 008dd1d132a1a01e517ec82e4d56f9a53db79c7b Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 19 Oct 2011 22:31:25 +0200 Subject: [PATCH 063/128] assertions --- .../src/org/jetbrains/ether/dependencyView/Mappings.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java index df14c0a0a66d..ca335264812c 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -2,6 +2,7 @@ package org.jetbrains.ether.dependencyView; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; +import org.jetbrains.annotations.NotNull; import org.objectweb.asm.ClassReader; import org.objectweb.asm.Opcodes; @@ -918,7 +919,7 @@ public class Mappings { } } - private void updateClassToSource(final StringCache.S className, final StringCache.S sourceName) { + private void updateClassToSource(@NotNull final StringCache.S className, @NotNull final StringCache.S sourceName) { classToSourceFile.put(className, sourceName); final Set waiting = (Set)waitingForResolve.foxyGet(className); @@ -1039,6 +1040,9 @@ public class Mappings { public StringCache.S getJavaByForm(final StringCache.S formFileName) { final StringCache.S classFileName = formToClass.get(formFileName); + + assert classFileName != null; + return classToSourceFile.get(classFileName); } From f480c21b15cc82f2a87b49716b056fbdd30206df Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 19 Oct 2011 23:00:13 +0200 Subject: [PATCH 064/128] basic support for 'incremental== false' case --- .../jps/incremental/CompileContext.java | 20 +++++++++++++++++++ .../jps/incremental/java/JavaBuilder.java | 12 +++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java index 1f3c6fd0645b..f4ccdd1fbc3b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java @@ -27,6 +27,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler private volatile boolean myCompilingTests = false; private final BuildDataManager myDataManager; private final Mappings myMappings; + private final Set myDirtyModules = new HashSet(); private SLRUCache myFilesCache = new SLRUCache(10, 10) { @NotNull @@ -52,6 +53,25 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler return myIsMake; } + public boolean isDirty(ModuleChunk chunk) { + for (Module module : chunk.getModules()) { + if (myDirtyModules.contains(module)) { + return true; + } + } + return false; + } + + public void setDirty(ModuleChunk chunk, boolean isDirty) { + final Set modules = chunk.getModules(); + if (isDirty) { + myDirtyModules.addAll(modules); + } + else { + myDirtyModules.removeAll(modules); + } + } + public Mappings getMappings() { return myMappings; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index 761b3d2bbc65..5494e3150053 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -100,16 +100,18 @@ public class JavaBuilder extends Builder{ final List upToDateForms = new ArrayList(); final Set srcRoots = new HashSet(); + final boolean wholeModuleRebuildRequired = context.isDirty(chunk); + context.processFiles(chunk, new FileProcessor() { public boolean apply(Module module, File file, String sourceRoot) throws Exception { if (JAVA_SOURCES_FILTER.accept(file)) { srcRoots.add(sourceRoot); - if (isFileDirty(file, context, tsStorage)) { + if (wholeModuleRebuildRequired || isFileDirty(file, context, tsStorage)) { filesToCompile.add(file); } } else if (FORM_SOURCES_FILTER.accept(file)){ - if (isFileDirty(file, context, tsStorage)) { + if (wholeModuleRebuildRequired || isFileDirty(file, context, tsStorage)) { formsToCompile.add(file); } else { @@ -252,6 +254,7 @@ public class JavaBuilder extends Builder{ } } finally { + context.setDirty(chunk, false); // no matter what result was, we should clear this flag outputSink.writePendingData(); @@ -283,8 +286,9 @@ public class JavaBuilder extends Builder{ } } else { - // todo - // switching into non-incremental module for this module and all those that depend on this module recursively + exitCode = ExitCode.ADDITIONAL_PASS_REQUIRED; + // todo: mark as dirty also all those that depend on this module recursively + context.setDirty(chunk, true); } } From fb7b3be5132f9d08255591f51aabe3cfbb775518 Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Thu, 20 Oct 2011 01:26:04 +0400 Subject: [PATCH 065/128] Reading/writing the mappings --- raw version. --- jps/model/src/org/jetbrains/ether/RW.java | 27 ++++++++++++ .../ether/dependencyView/FoxyMap.java | 44 ++++++++++++++++++- .../ether/dependencyView/Mappings.java | 13 ++---- .../ether/dependencyView/UsageRepr.java | 7 +++ 4 files changed, 81 insertions(+), 10 deletions(-) diff --git a/jps/model/src/org/jetbrains/ether/RW.java b/jps/model/src/org/jetbrains/ether/RW.java index aaf2faf84688..c713d07ae73e 100644 --- a/jps/model/src/org/jetbrains/ether/RW.java +++ b/jps/model/src/org/jetbrains/ether/RW.java @@ -1,9 +1,12 @@ package org.jetbrains.ether; +import com.intellij.util.xmlb.XmlSerializationException; + import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.util.Collection; +import java.util.Map; /** * Created by IntelliJ IDEA. @@ -99,6 +102,17 @@ public class RW { } } + public static void writeMap (final BufferedWriter w, final Map m) { + final int size = m.size(); + + writeln(w, Integer.toString(size)); + + for (Map.Entry e : m.entrySet()) { + e.getKey().write(w); + e.getValue().write(w); + } + } + public interface Reader { public T read(BufferedReader r); } @@ -228,4 +242,17 @@ public class RW { return null; } } + + public static Map readMap (final BufferedReader r, final Reader xr, final Reader yr, final Map acc) { + final int size = RW.readInt(r); + + for (int i = 0; i implements Map { + public static void write (final BufferedWriter w, final FoxyMap m){ + RW.writeln(w, Integer.toString(m.size())); + + for (Entry e : m.entrySet()) { + e.getKey().write(w); + + final Object value = e.getValue(); + + if (value instanceof Collection) { + RW.writeln(w, "many"); + RW.writeln(w, (Collection) value); + } else { + RW.writeln(w, "single"); + ((Y) value).write(w); + } + } + } + + public static FoxyMap read (final BufferedReader r, final RW.Reader xr, final RW.Reader yr, final CollectionConstructor cc){ + final FoxyMap result = new FoxyMap(cc); + + final int size = RW.readInt(r); + + for (int i=0; i { - public Collection create(); + Collection create(); } private final Map map = new HashMap(); diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java index ca335264812c..e62e50a3f41f 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -2,7 +2,6 @@ package org.jetbrains.ether.dependencyView; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; -import org.jetbrains.annotations.NotNull; import org.objectweb.asm.ClassReader; import org.objectweb.asm.Opcodes; @@ -641,12 +640,11 @@ public class Mappings { final Collection subClasses = getSubClasses(it.name); if (subClasses != null) { - for (final StringCache.S subClass : subClasses) { + for (StringCache.S subClass : subClasses) { final ClassRepr r = u.reprByName(subClass); - final StringCache.S sourceFileName = classToSourceFile.get(subClass); - assert sourceFileName != null; if (r != null) { + final StringCache.S sourceFileName = classToSourceFile.get(subClass); if (r.isLocal) { affectedFiles.add(sourceFileName); @@ -665,7 +663,7 @@ public class Mappings { final Collection propagated = u.propagateFieldAccess(f.name, subClass); u.affectFieldUsages(f, propagated, f.createUsage(subClass), affectedUsages, dependants); - final Collection deps = fileToFileDependency.foxyGet(sourceFileName); + final Collection deps = fileToFileDependency.foxyGet(classToSourceFile.get(subClass)); if (deps != null) { dependants.addAll(deps); @@ -919,7 +917,7 @@ public class Mappings { } } - private void updateClassToSource(@NotNull final StringCache.S className, @NotNull final StringCache.S sourceName) { + private void updateClassToSource(final StringCache.S className, final StringCache.S sourceName) { classToSourceFile.put(className, sourceName); final Set waiting = (Set)waitingForResolve.foxyGet(className); @@ -1040,9 +1038,6 @@ public class Mappings { public StringCache.S getJavaByForm(final StringCache.S formFileName) { final StringCache.S classFileName = formToClass.get(formFileName); - - assert classFileName != null; - return classToSourceFile.get(classFileName); } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/UsageRepr.java b/jps/model/src/org/jetbrains/ether/dependencyView/UsageRepr.java index ee4df5db872e..1ca7aeba8f46 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/UsageRepr.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/UsageRepr.java @@ -512,4 +512,11 @@ public class UsageRepr { } } }; + + public static RW.Reader clusterReader = new RW.Reader() { + @Override + public Cluster read(BufferedReader r) { + return new Cluster(r); + } + }; } From f468e5ec618880db94b06df188e6756477397c6f Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Thu, 20 Oct 2011 01:32:09 +0400 Subject: [PATCH 066/128] Reading/writing the mappings --- raw version. --- .../ether/dependencyView/Mappings.java | 74 ++++++++++++++----- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java index e62e50a3f41f..a5e43b9099e3 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -2,9 +2,13 @@ package org.jetbrains.ether.dependencyView; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.ether.RW; import org.objectweb.asm.ClassReader; import org.objectweb.asm.Opcodes; +import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.File; import java.lang.annotation.ElementType; import java.lang.annotation.RetentionPolicy; @@ -17,7 +21,7 @@ import java.util.*; * Time: 16:20 * To change this template use File | Settings | File Templates. */ -public class Mappings { +public class Mappings implements RW.Writable { private static FoxyMap.CollectionConstructor classSetConstructor = new FoxyMap.CollectionConstructor() { public Collection create() { @@ -37,16 +41,49 @@ public class Mappings { } }; - private FoxyMap classToSubclasses = new FoxyMap(stringSetConstructor); - private FoxyMap sourceFileToClasses = new FoxyMap(classSetConstructor); - private Map sourceFileToUsages = new HashMap(); - private FoxyMap sourceFileToAnnotationUsages = - new FoxyMap(usageSetConstructor); - private Map classToSourceFile = new HashMap(); - private FoxyMap fileToFileDependency = new FoxyMap(stringSetConstructor); - private FoxyMap waitingForResolve = new FoxyMap(stringSetConstructor); - private Map formToClass = new HashMap(); - private Map classToForm = new HashMap(); + private final FoxyMap classToSubclasses; + private final FoxyMap sourceFileToClasses; + private final Map sourceFileToUsages; + private final FoxyMap sourceFileToAnnotationUsages; + private final Map classToSourceFile; + private final FoxyMap fileToFileDependency; + private final FoxyMap waitingForResolve; + private final Map formToClass; + private final Map classToForm; + + @Override + public void write(BufferedWriter w) { + FoxyMap.write(w, classToSubclasses); + FoxyMap.write(w, sourceFileToClasses); + RW.writeMap(w, sourceFileToUsages); + FoxyMap.write(w, sourceFileToAnnotationUsages); + RW.writeMap(w, classToSourceFile); + FoxyMap.write(w, fileToFileDependency); + } + + public Mappings () { + classToSubclasses = new FoxyMap(stringSetConstructor); + sourceFileToClasses = new FoxyMap(classSetConstructor); + sourceFileToUsages = new HashMap(); + sourceFileToAnnotationUsages = new FoxyMap(usageSetConstructor); + classToSourceFile = new HashMap(); + fileToFileDependency = new FoxyMap(stringSetConstructor); + waitingForResolve = new FoxyMap(stringSetConstructor); + formToClass = new HashMap(); + classToForm = new HashMap(); + } + + public Mappings (final BufferedReader r) { + classToSubclasses = FoxyMap.read(r, StringCache.reader, StringCache.reader, stringSetConstructor); + sourceFileToClasses = FoxyMap.read(r, StringCache.reader, ClassRepr.reader, classSetConstructor); + sourceFileToUsages = RW.readMap(r, StringCache.reader, UsageRepr.clusterReader, new HashMap()); + sourceFileToAnnotationUsages = FoxyMap.read(r, StringCache.reader, UsageRepr.reader, usageSetConstructor); + classToSourceFile = RW.readMap(r, StringCache.reader, StringCache.reader, new HashMap()); + fileToFileDependency = FoxyMap.read(r, StringCache.reader, StringCache.reader, stringSetConstructor); + waitingForResolve = new FoxyMap(stringSetConstructor); + formToClass = new HashMap(); + classToForm = new HashMap(); + } private void compensateRemovedContent(final Collection compiled) { for (StringCache.S name : compiled) { @@ -640,11 +677,12 @@ public class Mappings { final Collection subClasses = getSubClasses(it.name); if (subClasses != null) { - for (StringCache.S subClass : subClasses) { + for (final StringCache.S subClass : subClasses) { final ClassRepr r = u.reprByName(subClass); + final StringCache.S sourceFileName = classToSourceFile.get(subClass); + assert sourceFileName != null; if (r != null) { - final StringCache.S sourceFileName = classToSourceFile.get(subClass); if (r.isLocal) { affectedFiles.add(sourceFileName); @@ -663,7 +701,7 @@ public class Mappings { final Collection propagated = u.propagateFieldAccess(f.name, subClass); u.affectFieldUsages(f, propagated, f.createUsage(subClass), affectedUsages, dependants); - final Collection deps = fileToFileDependency.foxyGet(classToSourceFile.get(subClass)); + final Collection deps = fileToFileDependency.foxyGet(sourceFileName); if (deps != null) { dependants.addAll(deps); @@ -917,7 +955,7 @@ public class Mappings { } } - private void updateClassToSource(final StringCache.S className, final StringCache.S sourceName) { + private void updateClassToSource(@NotNull final StringCache.S className, @NotNull final StringCache.S sourceName) { classToSourceFile.put(className, sourceName); final Set waiting = (Set)waitingForResolve.foxyGet(className); @@ -1000,9 +1038,6 @@ public class Mappings { }; } - public Mappings() { - } - public Set getClasses(final StringCache.S sourceFileName) { return (Set)sourceFileToClasses.foxyGet(sourceFileName); } @@ -1038,6 +1073,9 @@ public class Mappings { public StringCache.S getJavaByForm(final StringCache.S formFileName) { final StringCache.S classFileName = formToClass.get(formFileName); + + assert classFileName != null; + return classToSourceFile.get(classFileName); } From a739a24bba97d0967045d57566e1730538cfc66c Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Thu, 20 Oct 2011 01:42:54 +0400 Subject: [PATCH 067/128] Reading/writing the mappings --- tested version. --- jps/testSrc/org/jetbrains/ether/IncrementalTestCase.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jps/testSrc/org/jetbrains/ether/IncrementalTestCase.java b/jps/testSrc/org/jetbrains/ether/IncrementalTestCase.java index 4b74116baecf..4ba1e8b395ee 100644 --- a/jps/testSrc/org/jetbrains/ether/IncrementalTestCase.java +++ b/jps/testSrc/org/jetbrains/ether/IncrementalTestCase.java @@ -2,6 +2,7 @@ package org.jetbrains.ether; import junit.framework.TestCase; import junitx.framework.FileAssert; +import org.jetbrains.ether.dependencyView.Mappings; import java.io.*; From 6a1ee8f0f72cf087381125a487fc34afed7914b9 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Thu, 20 Oct 2011 08:30:38 +0400 Subject: [PATCH 068/128] IDEA-75680 Editor: make 'select whole line on triple click' default behavior 1. 'Honor camel humps on triple click' option is removed; 2. Whole line is selected by triple click by default, camel case is honored only if the target system property is set; --- .../options/editor/EditorOptionsPanel.form | 16 ++++---------- .../options/editor/EditorOptionsPanel.java | 12 ++++------- .../openapi/editor/EditorSettings.java | 5 +++-- .../ex/EditorSettingsExternalizable.java | 16 ++++---------- .../openapi/editor/impl/EditorImpl.java | 6 ++++-- .../openapi/editor/impl/SettingsImpl.java | 21 +++++++------------ .../src/messages/ApplicationBundle.properties | 3 +-- 7 files changed, 28 insertions(+), 51 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form index 797ffafcb413..2721f16caa1c 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form @@ -23,7 +23,7 @@ - + @@ -34,7 +34,7 @@ - + @@ -44,7 +44,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -62,14 +62,6 @@ - - - - - - - - diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java index b7164f14ab2e..f5f26f91487b 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java @@ -67,8 +67,7 @@ public class EditorOptionsPanel { private JCheckBox myCbVirtualPageAtBottom; private JCheckBox myCbEnableDnD; private JCheckBox myCbEnableWheelFontChange; - private JCheckBox myCbHonorCamelHumpsWhenSelectingByDoubleClick; - private JCheckBox myCbHonorCamelHumpsWhenSelectingByTripleClick; + private JCheckBox myCbHonorCamelHumpsWhenSelectingByClicking; private JPanel myHighlightSettingsPanel; private JRadioButton myRbPreferScrolling; @@ -160,8 +159,7 @@ public class EditorOptionsPanel { // Advanced mouse myCbEnableDnD.setSelected(editorSettings.isDndEnabled()); myCbEnableWheelFontChange.setSelected(editorSettings.isWheelFontChangeEnabled()); - myCbHonorCamelHumpsWhenSelectingByDoubleClick.setSelected(editorSettings.isMouseClickSelectionHonorsCamelWords(2)); - myCbHonorCamelHumpsWhenSelectingByTripleClick.setSelected(editorSettings.isMouseClickSelectionHonorsCamelWords(3)); + myCbHonorCamelHumpsWhenSelectingByClicking.setSelected(editorSettings.isMouseClickSelectionHonorsCamelWords()); myRbPreferMovingCaret.setSelected(editorSettings.isRefrainFromScrolling()); myRbPreferScrolling.setSelected(!editorSettings.isRefrainFromScrolling()); @@ -238,8 +236,7 @@ public class EditorOptionsPanel { editorSettings.setDndEnabled(myCbEnableDnD.isSelected()); editorSettings.setWheelFontChangeEnabled(myCbEnableWheelFontChange.isSelected()); - editorSettings.setMouseClickSelectionHonorsCamelWords(2, myCbHonorCamelHumpsWhenSelectingByDoubleClick.isSelected()); - editorSettings.setMouseClickSelectionHonorsCamelWords(3, myCbHonorCamelHumpsWhenSelectingByTripleClick.isSelected()); + editorSettings.setMouseClickSelectionHonorsCamelWords(myCbHonorCamelHumpsWhenSelectingByClicking.isSelected()); editorSettings.setRefrainFromScrolling(myRbPreferMovingCaret.isSelected()); editorSettings.setVariableInplaceRenameEnabled(myCbRenameLocalVariablesInplace.isSelected()); @@ -345,8 +342,7 @@ public class EditorOptionsPanel { // advanced mouse isModified |= isModified(myCbEnableDnD, editorSettings.isDndEnabled()); isModified |= isModified(myCbEnableWheelFontChange, editorSettings.isWheelFontChangeEnabled()); - isModified |= isModified(myCbHonorCamelHumpsWhenSelectingByDoubleClick, editorSettings.isMouseClickSelectionHonorsCamelWords(2)); - isModified |= isModified(myCbHonorCamelHumpsWhenSelectingByTripleClick, editorSettings.isMouseClickSelectionHonorsCamelWords(3)); + isModified |= isModified(myCbHonorCamelHumpsWhenSelectingByClicking, editorSettings.isMouseClickSelectionHonorsCamelWords()); isModified |= myRbPreferMovingCaret.isSelected() != editorSettings.isRefrainFromScrolling(); diff --git a/platform/platform-api/src/com/intellij/openapi/editor/EditorSettings.java b/platform/platform-api/src/com/intellij/openapi/editor/EditorSettings.java index 69128fd75c75..580137106bbd 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/EditorSettings.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/EditorSettings.java @@ -88,8 +88,9 @@ public interface EditorSettings { boolean isWheelFontChangeEnabled(); void setWheelFontChangeEnabled(boolean val); - boolean isMouseClickSelectionHonorsCamelWords(int clicksCount); - void setMouseClickSelectionHonorsCamelWords(int clicksCount, boolean val); + boolean isMouseClickSelectionHonorsCamelWords(); + void setMouseClickSelectionHonorsCamelWords(boolean val); + boolean isVariableInplaceRenameEnabled(); void setVariableInplaceRenameEnabled(boolean val); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java index 42e7e3ab7553..0125d61de1bc 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java @@ -69,7 +69,6 @@ public class EditorSettingsExternalizable implements NamedJDOMExternalizable, Ex public boolean IS_DND_ENABLED = true; public boolean IS_WHEEL_FONTCHANGE_ENABLED = true; public boolean IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS = true; - public boolean IS_TRIPLE_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS = false; @Deprecated public boolean IS_NATIVE2ASCII_FOR_PROPERTIES_FILES; @Deprecated @@ -458,19 +457,12 @@ public class EditorSettingsExternalizable implements NamedJDOMExternalizable, Ex myOptions.IS_WHEEL_FONTCHANGE_ENABLED = val; } - public boolean isMouseClickSelectionHonorsCamelWords(int clicksCount) { - switch (clicksCount) { - case 2: return myOptions.IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS; - case 3: return myOptions.IS_TRIPLE_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS; - default: return false; - } + public boolean isMouseClickSelectionHonorsCamelWords() { + return myOptions.IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS; } - public void setMouseClickSelectionHonorsCamelWords(int clicksCount, boolean val) { - switch (clicksCount) { - case 2: myOptions.IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS = val; break; - case 3: myOptions.IS_TRIPLE_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS = val; - } + public void setMouseClickSelectionHonorsCamelWords(boolean val) { + myOptions.IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS = val; } public boolean isVariableInplaceRenameEnabled() { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index f76448fefa14..a13e8b6c374b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -122,6 +122,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi private static final Key DND_COMMAND_KEY = Key.create("DndCommand"); public static final Key DO_DOCUMENT_UPDATE_TEST = Key.create("DoDocumentUpdateTest"); public static final Key> EDITABLE_AREA_MARKER = Key.create("editable.area.marker"); + private static final boolean HONOR_CAMEL_HUMPS_ON_TRIPLE_CLICK + = Boolean.parseBoolean(System.getProperty("idea.honor.camel.humps.on.triple.click")); private final DocumentImpl myDocument; private final JPanel myPanel; @@ -4920,11 +4922,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi if (!e.isPopupTrigger()) { switch (e.getClickCount()) { case 2: - selectWordAtCaret(mySettings.isMouseClickSelectionHonorsCamelWords(2) && mySettings.isCamelWords()); + selectWordAtCaret(mySettings.isMouseClickSelectionHonorsCamelWords() && mySettings.isCamelWords()); break; case 3: - if (mySettings.isMouseClickSelectionHonorsCamelWords(3) && mySettings.isCamelWords()) { + if (HONOR_CAMEL_HUMPS_ON_TRIPLE_CLICK && mySettings.isCamelWords()) { // We want to differentiate between triple and quadruple clicks when 'select by camel humps' is on. The former // is assumed to select 'hump' while the later points to the whole word. selectWordAtCaret(false); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java index 9da0dd70002f..486a79bd9222 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java @@ -32,11 +32,9 @@ import com.intellij.openapi.editor.impl.softwrap.SoftWrapAppliancePlaces; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; -import gnu.trove.TIntIntHashMap; import org.jetbrains.annotations.Nullable; public class SettingsImpl implements EditorSettings { - private TIntIntHashMap myHonorCamelHumpsOnClicks; @Nullable private final EditorEx myEditor; private Boolean myIsCamelWords; @@ -70,6 +68,7 @@ public class SettingsImpl implements EditorSettings { private Boolean myIsAdditionalPageAtBottom = null; private Boolean myIsDndEnabled = null; private Boolean myIsWheelFontChangeEnabled = null; + private Boolean myIsMouseClickSelectionHonorsCamelWords = null; private Boolean myIsRenameVariablesInplace = null; private Boolean myIsRefrainFromScrolling = null; private Boolean myUseSoftWraps = null; @@ -374,19 +373,15 @@ public class SettingsImpl implements EditorSettings { public void setWheelFontChangeEnabled(boolean val) { myIsWheelFontChangeEnabled = val ? Boolean.TRUE : Boolean.FALSE; } - - public boolean isMouseClickSelectionHonorsCamelWords(int clicksCount) { - if (myHonorCamelHumpsOnClicks != null && myHonorCamelHumpsOnClicks.containsKey(clicksCount)) { - return myHonorCamelHumpsOnClicks.get(clicksCount) > 0; - } - return EditorSettingsExternalizable.getInstance().isMouseClickSelectionHonorsCamelWords(clicksCount); + + public boolean isMouseClickSelectionHonorsCamelWords() { + return myIsMouseClickSelectionHonorsCamelWords != null + ? myIsMouseClickSelectionHonorsCamelWords.booleanValue() + : EditorSettingsExternalizable.getInstance().isMouseClickSelectionHonorsCamelWords(); } - public void setMouseClickSelectionHonorsCamelWords(int clicksCount, boolean val) { - if (myHonorCamelHumpsOnClicks == null) { - myHonorCamelHumpsOnClicks = new TIntIntHashMap(); - } - myHonorCamelHumpsOnClicks.put(clicksCount, val ? 1 : 0); + public void setMouseClickSelectionHonorsCamelWords(boolean val) { + myIsMouseClickSelectionHonorsCamelWords = val ? Boolean.TRUE : Boolean.FALSE; } public boolean isVariableInplaceRenameEnabled() { diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties index 0e64315cb09d..508bc6436ef6 100644 --- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties +++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties @@ -387,7 +387,6 @@ checkbox.enable.ctrl.mousewheel.changes.font.size=Change font size (Zoom) with C checkbox.enable.ctrl.mousewheel.changes.font.size.macos=Enable Command+MouseWheel changes font size checkbox.enable.drag.n.drop.functionality.in.editor=Enable Drag'n'Drop functionality in editor checkbox.honor.camelhumps.words.settings.on.double.click=Honor "CamelHumps" words settings when selecting on
double click -checkbox.honor.camelhumps.words.settings.on.triple.click=Honor "CamelHumps" words settings when selecting on
triple click group.smart.keys=Smart Keys checkbox.use.camelhumps.words=Use "CamelHumps" words checkbox.insert.pair.quote=Insert pair quote @@ -546,4 +545,4 @@ desktop.entry.checking=Checking... desktop.entry.preparing=Preparing entry... desktop.entry.installing=Installing entry... desktop.entry.sudo.prompt=Please enter your password to create a desktop entry -title.tabs.and.indents=Tabs and Indents \ No newline at end of file +title.tabs.and.indents=Tabs and Indents From 408b3ead3e50a048034db09b56d0779e1bb60a3a Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 19 Oct 2011 18:32:57 +0400 Subject: [PATCH 069/128] isSuiteMethod simplified --- .../intellij/execution/junit/JUnitUtil.java | 29 +++++++------------ .../intellij/execution/ConfigurationUtil.java | 2 +- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java index f884997e3038..a285b5ba4fc4 100644 --- a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java +++ b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java @@ -24,12 +24,11 @@ import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.Key; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.ClassInheritorsSearch; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiClassUtil; -import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.Processor; import com.intellij.util.containers.Convertor; import junit.runner.BaseTestRunner; @@ -53,25 +52,16 @@ public class JUnitUtil { @NonNls public static final String RUN_WITH = "org.junit.runner.RunWith"; @NonNls public static final String SUITE_METHOD_NAME = "suite"; - private static final Key TEST_INTERFACE_KEY = Key.create(TEST_INTERFACE); - public static boolean isSuiteMethod(@NotNull PsiMethod psiMethod, @NotNull Project project) { + public static boolean isSuiteMethod(@NotNull PsiMethod psiMethod) { if (!psiMethod.hasModifierProperty(PsiModifier.PUBLIC)) return false; if (!psiMethod.hasModifierProperty(PsiModifier.STATIC)) return false; if (psiMethod.isConstructor()) return false; + if (psiMethod.getParameterList().getParametersCount() > 0) return false; final PsiType returnType = psiMethod.getReturnType(); if (returnType == null || returnType instanceof PsiPrimitiveType) return false; - if (!returnType.equalsToText(TEST_INTERFACE) && !returnType.equalsToText(TESTSUITE_CLASS)) { - PsiType cachedTestInterfaceType = project.getUserData(TEST_INTERFACE_KEY); - if (cachedTestInterfaceType == null) { - final PsiType testType = JavaPsiFacade.getInstance(project).getElementFactory().createTypeFromText(TEST_INTERFACE, null); - project.putUserData(TEST_INTERFACE_KEY,testType); - cachedTestInterfaceType = testType; - } - if (!TypeConversionUtil.isAssignable(cachedTestInterfaceType, returnType)) { - return false; - } - } - return psiMethod.getParameterList().getParametersCount() == 0; + return returnType.equalsToText(TEST_INTERFACE)|| + returnType.equalsToText(TESTSUITE_CLASS) || + InheritanceUtil.isInheritor(returnType, TEST_INTERFACE); } public static boolean isTestMethod(final Location location) { @@ -123,7 +113,7 @@ public class JUnitUtil { for (final PsiMethod method : psiClass.getAllMethods()) { ProgressManager.checkCanceled(); - if (isSuiteMethod(method, psiClass.getProject())) return true; + if (isSuiteMethod(method)) return true; if (isTestAnnotated(method)) return true; } @@ -172,6 +162,7 @@ public class JUnitUtil { return false; } + @Nullable private static PsiClass getTestCaseClassOrNull(final Location location) { final Location ancestorOrSelf = location.getAncestorOrSelf(PsiClass.class); final PsiClass aClass = ancestorOrSelf.getPsiElement(); @@ -197,6 +188,8 @@ public class JUnitUtil { if (testCaseClass == null) throw new NoJUnitException(scope.getDisplayName()); return testCaseClass; } + + @Nullable private static PsiClass getTestCaseClassOrNull(final GlobalSearchScope scope, final Project project) { return JavaPsiFacade.getInstance(project).findClass(TESTCASE_CLASS, scope); } @@ -246,7 +239,7 @@ public class JUnitUtil { public static PsiMethod findFirstTestMethod(PsiClass clazz) { PsiMethod testMethod = null; for (PsiMethod method : clazz.getMethods()) { - if (isTestMethod(MethodLocation.elementInClass(method, clazz)) || isSuiteMethod(method, clazz.getProject())) { + if (isTestMethod(MethodLocation.elementInClass(method, clazz)) || isSuiteMethod(method)) { testMethod = method; break; } diff --git a/plugins/junit/src/com/intellij/execution/ConfigurationUtil.java b/plugins/junit/src/com/intellij/execution/ConfigurationUtil.java index 32deff9afe42..4c56562ab873 100644 --- a/plugins/junit/src/com/intellij/execution/ConfigurationUtil.java +++ b/plugins/junit/src/com/intellij/execution/ConfigurationUtil.java @@ -67,7 +67,7 @@ public class ConfigurationUtil { if (containingClass instanceof PsiAnonymousClass) return; if (containingClass.hasModifierProperty(PsiModifier.ABSTRACT)) return; if (containingClass.getContainingClass() != null && !containingClass.hasModifierProperty(PsiModifier.STATIC)) return; - if (JUnitUtil.isSuiteMethod(method, project)) { + if (JUnitUtil.isSuiteMethod(method)) { found.add(containingClass); } } From 1b23e63013edc2476ef03609bc82316a6d269e36 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 19 Oct 2011 19:00:48 +0400 Subject: [PATCH 070/128] IDEA-75685 ui does not respond: do not process java classes from jsps --- .../com/intellij/psi/impl/file/JavaDirectoryServiceImpl.java | 3 +-- .../src/com/intellij/psi/impl/JavaPsiFacadeImpl.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/file/JavaDirectoryServiceImpl.java b/java/java-impl/src/com/intellij/psi/impl/file/JavaDirectoryServiceImpl.java index 532341469a04..227f2cd746bf 100644 --- a/java/java-impl/src/com/intellij/psi/impl/file/JavaDirectoryServiceImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/file/JavaDirectoryServiceImpl.java @@ -62,8 +62,7 @@ public class JavaDirectoryServiceImpl extends JavaDirectoryService { List classes = null; for (PsiFile file : dir.getFiles()) { - FileViewProvider viewProvider = file.getViewProvider(); - if (file instanceof PsiClassOwner && file == viewProvider.getPsi(viewProvider.getBaseLanguage())) { + if (file instanceof PsiClassOwner && file.getViewProvider().getLanguages().size() == 1) { PsiClass[] psiClasses = ((PsiClassOwner)file).getClasses(); if (psiClasses.length == 0) continue; if (classes == null) classes = new ArrayList(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java index b49ddae76aea..ddc74b7ee2da 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java @@ -306,8 +306,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx { Set names = null; for (PsiDirectory dir : psiPackage.getDirectories(scope)) { for (PsiFile file : dir.getFiles()) { - FileViewProvider viewProvider = file.getViewProvider(); - if (file instanceof PsiClassOwner && file == viewProvider.getPsi(viewProvider.getBaseLanguage())) { + if (file instanceof PsiClassOwner && file.getViewProvider().getLanguages().size() == 1) { Set inFile = file instanceof PsiClassOwnerEx ? ((PsiClassOwnerEx)file).getClassNames() : getClassNames(((PsiClassOwner)file).getClasses()); if (inFile.isEmpty()) continue; From cae0957f0a3368d732b5fc3290d1c93f52e4eb21 Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 19 Oct 2011 20:39:16 +0200 Subject: [PATCH 071/128] plugins: cosmetics --- .../intellij/ide/plugins/InstalledPluginsManagerMain.java | 4 ++-- .../src/com/intellij/ide/plugins/PluginManagerMain.java | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java index 539632e3c67a..3c534f329e3c 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java @@ -49,7 +49,7 @@ public class InstalledPluginsManagerMain extends PluginManagerMain { super(uiSettings); init(); myActionsPanel.setLayout(new BorderLayout(5, 0)); - final JButton button = new JButton("Browse repositories"); + final JButton button = new JButton("Browse repositories..."); button.setMnemonic('b'); button.addActionListener(new ActionListener() { @Override @@ -63,7 +63,7 @@ public class InstalledPluginsManagerMain extends PluginManagerMain { } }); myActionsPanel.add(button, BorderLayout.WEST); - final JButton manageRepositoriesBtn = new JButton("Manage repositories"); + final JButton manageRepositoriesBtn = new JButton("Manage repositories..."); manageRepositoriesBtn.setMnemonic('m'); manageRepositoriesBtn.addActionListener(new ActionListener() { @Override diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java index f4a1f2f8b09b..0e1aeb9d6d01 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java @@ -75,7 +75,13 @@ public abstract class PluginManagerMain implements Disposable { public static Logger LOG = Logger.getInstance("#com.intellij.ide.plugins.PluginManagerMain"); - @NonNls private static final String TEXT_PREFIX = ""; + @NonNls private static final String TEXT_PREFIX = "" + + " " + + ""; @NonNls private static final String TEXT_SUFIX = ""; @NonNls private static final String HTML_PREFIX = " Date: Wed, 19 Oct 2011 18:20:09 +0400 Subject: [PATCH 072/128] cleanup --- .../src/com/intellij/openapi/vfs/VirtualFile.java | 4 ++-- .../src/com/intellij/psi/SingleRootFileViewProvider.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java b/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java index 2a37e9f2e970..4928b32c504d 100644 --- a/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java +++ b/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java @@ -74,7 +74,7 @@ public abstract class VirtualFile extends UserDataHolderBase implements Modifica /** * Gets the path of this file. Path is a string which uniquely identifies file within given * {@link VirtualFileSystem}. Format of the path depends on the concrete file system. - * For {@link LocalFileSystem} it is an absolute file path with file separator characters + * For {@link com.intellij.openapi.vfs.LocalFileSystem} it is an absolute file path with file separator characters * (File.separatorChar) replaced to the forward slash ('/'). * * @return the path @@ -170,7 +170,7 @@ public abstract class VirtualFile extends UserDataHolderBase implements Modifica /** * Renames this file to the newName.

* This method should be only called within write-action. - * See {@link Application#runWriteAction}. + * See {@link com.intellij.openapi.application.Application#runWriteAction(Runnable)}. * * @param requestor any object to control who called this method. Note that * it is considered to be an external change if requestor is null. diff --git a/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java b/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java index d8c9e2d935cc..6ac5e7aa8282 100644 --- a/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java +++ b/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java @@ -267,15 +267,15 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi return contentSize > PersistentFSConstants.MAX_INTELLISENSE_FILESIZE; } - private static boolean fileSizeIsGreaterThan(@NotNull VirtualFile vFile, final long maxInBytes) { + private static boolean fileSizeIsGreaterThan(@NotNull VirtualFile vFile, final long maxBytes) { if (vFile instanceof LightVirtualFile) { // This is optimization in order to avoid conversion of [large] file contents to bytes final int lengthInChars = ((LightVirtualFile)vFile).getContent().length(); - if (lengthInChars < maxInBytes / 2) return false; - if (lengthInChars > maxInBytes ) return true; + if (lengthInChars < maxBytes / 2) return false; + if (lengthInChars > maxBytes ) return true; } - return vFile.getLength() > maxInBytes; + return vFile.getLength() > maxBytes; } @Nullable From b900f914b885720a04286629a40d7a72e6a5190f Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 20 Oct 2011 13:22:07 +0400 Subject: [PATCH 073/128] false positives in tests --- .../com/intellij/testFramework/LeakHunter.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/LeakHunter.java b/platform/testFramework/src/com/intellij/testFramework/LeakHunter.java index 6608994d0ae9..4c690938de03 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LeakHunter.java +++ b/platform/testFramework/src/com/intellij/testFramework/LeakHunter.java @@ -19,6 +19,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.impl.ProjectImpl; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.UserDataHolder; +import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.psi.PsiElement; import com.intellij.psi.impl.source.tree.TreeElement; import com.intellij.util.Processor; @@ -140,8 +141,7 @@ public class LeakHunter { object.putUserData(IS_NOT_A_LEAK, Boolean.TRUE); } private static boolean isReallyLeak(Field field, String fieldName, Object value, Class valueClass) { - if (value instanceof UserDataHolder && ((UserDataHolder)value).getUserData(IS_NOT_A_LEAK) != null) return false; - return true; + return !(value instanceof UserDataHolder) || ((UserDataHolder)value).getUserData(IS_NOT_A_LEAK) == null; } private static final Set noFollowClasses = new THashSet(); @@ -170,7 +170,11 @@ public class LeakHunter { checkLeak(root, ProjectImpl.class); } @TestOnly - public static void checkLeak(@NotNull Object root, @NotNull Class suspectClass) { + public static void checkLeak(@NotNull Object root, @NotNull Class suspectClass) throws AssertionError { + checkLeak(root, suspectClass, null); + } + @TestOnly + public static void checkLeak(@NotNull Object root, @NotNull Class suspectClass, final Processor isReallyLeak) throws AssertionError { if (SwingUtilities.isEventDispatchThread()) { UIUtil.dispatchAllInvocationEvents(); } @@ -186,9 +190,10 @@ public class LeakHunter { @Override public boolean process(BackLink backLink) { UserDataHolder leaked = (UserDataHolder)backLink.value; - if (leaked.getUserData(REPORTED_LEAKED) == null) { + if (((UserDataHolderBase)leaked).replace(REPORTED_LEAKED,null,Boolean.TRUE) && (isReallyLeak == null || isReallyLeak.process((T)leaked))) { String place = leaked instanceof Project ? PlatformTestCase.getCreationPlace((Project)leaked) : ""; - System.out.println("LEAK: hash: "+System.identityHashCode(leaked) + "; place: "+ place); + System.out.println("Leaked object found:" + leaked + + "; hash: "+System.identityHashCode(leaked) + "; place: "+ place); while (backLink != null) { String valueStr; try { @@ -202,8 +207,7 @@ public class LeakHunter { } System.out.println(";-----"); - leaked.putUserData(REPORTED_LEAKED, Boolean.TRUE); - throw new RuntimeException(); + throw new AssertionError(); } return true; } From 4b060c2591c87ad1616c0fee179bf3c1645f6e46 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 20 Oct 2011 12:22:54 +0200 Subject: [PATCH 074/128] no space after named argument label by default --- .../completion/handlers/NamedArgumentInsertHandler.java | 6 +++--- .../plugins/groovy/completion/GroovyCompletionTest.groovy | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/NamedArgumentInsertHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/NamedArgumentInsertHandler.java index d57992ee7a4d..a06fc1cdbff0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/NamedArgumentInsertHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/NamedArgumentInsertHandler.java @@ -51,7 +51,7 @@ public class NamedArgumentInsertHandler implements InsertHandler final Editor editor = context.getEditor(); if (argumentList != null) { - if (context.getCompletionChar() == ':' || context.getCompletionChar() == ' ') { + if (context.getCompletionChar() == ':') { context.setAddCompletionChar(false); } @@ -61,8 +61,8 @@ public class NamedArgumentInsertHandler implements InsertHandler s = StringUtil.trimEnd(s, ")"); if (s.trim().length() == 0) { - editor.getDocument().insertString(tailOffset, ": "); - editor.getCaretModel().moveToOffset(tailOffset + 2); + editor.getDocument().insertString(tailOffset, ":"); + editor.getCaretModel().moveToOffset(tailOffset + 1); } else { if (context.getCompletionChar() == Lookup.REPLACE_SELECT_CHAR) { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy index 3bbbd24099bc..68578b865319 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy @@ -325,7 +325,7 @@ class A { myFixture.checkResult """ class A { public int m(arg) { return arg.arg111 + arg.arg222 + arg.arg333; } - { m arg111: } + { m arg111: } } """ } @@ -397,7 +397,7 @@ class A { myFixture.checkResult """ class A { public int m(arg) { return arg.arg111 + arg.arg222 + arg.arg333; } - { m(arg111: )} + { m(arg111:)} } """ } @@ -432,7 +432,7 @@ class A { myFixture.checkResult """ class A { public int m(arg) { return arg.arg111 + arg.arg222 + arg.arg333; } - { m(arg111: )} + { m(arg111:)} } """ } From 9137b3b25b03690ad048923f756ec0df3462488c Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 20 Oct 2011 12:38:47 +0200 Subject: [PATCH 075/128] EA-30560 (NPE: ExtConnectionCvsSettings.processException) --- .../cvsSupport2/connections/ext/ExtConnectionCvsSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/connections/ext/ExtConnectionCvsSettings.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/connections/ext/ExtConnectionCvsSettings.java index d97893d1ca1f..c844efa05d2a 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/connections/ext/ExtConnectionCvsSettings.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/connections/ext/ExtConnectionCvsSettings.java @@ -117,7 +117,7 @@ public class ExtConnectionCvsSettings extends CvsConnectionSettings { Exception sourceException = t.getUnderlyingException(); if (!(sourceException instanceof IOException)) return t; String localizedMessage = t.getLocalizedMessage(); - if (!localizedMessage.startsWith(UNHANDLED_RESPONSE_PREFIX)) return t; + if (localizedMessage == null || !localizedMessage.startsWith(UNHANDLED_RESPONSE_PREFIX)) return t; String response = localizedMessage.substring(UNHANDLED_RESPONSE_PREFIX.length(), localizedMessage.length() - 1); if (StringUtil.startsWithConcatenationOf(response, USER + "@", HOST)) { From 2912045f0cc0cfb4ded57aa1b1c6f5f050970498 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Thu, 20 Oct 2011 14:58:46 +0400 Subject: [PATCH 076/128] old settings importer: 1. try to find path selector property if custom config path wasn't found 2. don't search anything in idea.properties comments --- .../application/ConfigImportHelper.java | 67 +++++++++++++------ .../application/ConfigImportSettings.java | 14 ---- .../openapi/application/PathManager.java | 22 +++--- 3 files changed, 59 insertions(+), 44 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java index d41dbdea1255..5529f305ba64 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java @@ -24,13 +24,13 @@ import com.intellij.util.SystemProperties; import com.intellij.util.ThreeState; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.util.MissingResourceException; import java.util.PropertyResourceBundle; /** @@ -203,19 +203,29 @@ public class ConfigImportHelper { return new File(oldInstallHome, "config"); } - File[] launchFileCandidates = getLaunchFilesCandidates(oldInstallHome); - for (File file : launchFileCandidates) { - if (file.exists()) { - String configDir = PathManager.substituteVars(getConfigFromLaxFile(file), oldInstallHome.getPath()); + final File[] launchFileCandidates = getLaunchFilesCandidates(oldInstallHome); + + // custom config folder + for (File candidate : launchFileCandidates) { + if (candidate.exists()) { + String configDir = PathManager.substituteVars(getPropertyFromLaxFile(candidate, PathManager.PROPERTY_CONFIG_PATH), + oldInstallHome.getPath()); if (configDir != null) { File probableConfig = new File(configDir); if (probableConfig.exists()) return probableConfig; + } + } + } - // in IDEA 11 idea.properties does not contain product version: "# idea.config.path=${user.home}/.IntelliJIdea/config" - String attempt2 = settings.fixConfigDir(configDir); - if (attempt2 != null && !configDir.equals(attempt2)) { - probableConfig = new File(attempt2); - if (probableConfig.exists()) return probableConfig; + // custom config folder not found - use paths selector + for (File candidate : launchFileCandidates) { + if (candidate.exists()) { + final String pathsSelector = getPropertyFromLaxFile(candidate, PathManager.PROPERTY_PATHS_SELECTOR); + if (pathsSelector != null) { + final String configDir = PathManager.getDefaultConfigPathFor(pathsSelector); + final File probableConfig = new File(configDir); + if (probableConfig.exists()) { + return probableConfig; } } } @@ -233,6 +243,7 @@ public class ConfigImportHelper { new File(new File(new File(bin, "idea.app"), "Contents"), "Info.plist"), new File(new File(new File(instHome, "idea.app"), "Contents"), "Info.plist"), new File(bin, "idea.properties"), + //TODO? other minor IDEs? new File(bin, "idea.lax"), new File(bin, "idea.bat"), new File(bin, "idea.sh") @@ -250,7 +261,8 @@ public class ConfigImportHelper { @SuppressWarnings({"HardCodedStringLiteral"}) @Nullable - public static String getConfigFromLaxFile(File file) { + public static String getPropertyFromLaxFile(@NotNull final File file, + @NotNull final String propertyName) { if (file.getName().endsWith(".properties")) { try { InputStream fis = new BufferedInputStream(new FileInputStream(file)); @@ -261,22 +273,35 @@ public class ConfigImportHelper { finally { fis.close(); } - return bundle.getString("idea.config.path"); + if (bundle.containsKey(propertyName)) { + return bundle.getString(propertyName); + } + return null; } catch (IOException e) { return null; } - catch (MissingResourceException e) { - // property is missing or commented out, go on with this file - } + } + + final String fileContent = getContent(file); + + // try to find custom config path + final String propertyValue = findProperty(propertyName, fileContent); + if (!StringUtil.isEmpty(propertyValue)) { + return propertyValue; } - String fileContent = getContent(file); - String configParam = "idea.config.path="; - int idx = fileContent.indexOf(configParam); + return null; + } + + @Nullable + private static String findProperty(final String propertyName, + final String fileContent) { + String param = propertyName + "="; + int idx = fileContent.indexOf(param); if (idx == -1) { - configParam = "idea.config.path"; - idx = fileContent.indexOf(configParam); + param = "" + propertyName + ""; + idx = fileContent.indexOf(param); if (idx == -1) return null; idx = fileContent.indexOf("", idx); if (idx == -1) return null; @@ -285,7 +310,7 @@ public class ConfigImportHelper { } else { String configDir = ""; - idx += configParam.length(); + idx += param.length(); if (fileContent.length() > idx) { if (fileContent.charAt(idx) == '"') { idx++; diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportSettings.java b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportSettings.java index d98832540649..d1c15def3eba 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportSettings.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportSettings.java @@ -1,7 +1,5 @@ package com.intellij.openapi.application; -import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.SystemProperties; import com.intellij.util.ThreeState; import org.jetbrains.annotations.Nullable; @@ -71,16 +69,4 @@ public class ConfigImportSettings { public void importFinished(String newConfigPath) { } - - @Nullable - public String fixConfigDir(String configDir) { - String s = FileUtil.toSystemIndependentName(configDir); - final String selector = PathManager.getPathsSelector(); - if (selector == null) return null; - - final String dot = SystemInfo.isMac ? "" : "."; - final String prefix = dot + selector.replaceAll("\\d", ""); - if (s.contains("/" + prefix + "/")) return configDir.replace(prefix, dot + selector); - return null; - } } diff --git a/platform/util/src/com/intellij/openapi/application/PathManager.java b/platform/util/src/com/intellij/openapi/application/PathManager.java index ed561cce67ae..7f4f4f5ee580 100644 --- a/platform/util/src/com/intellij/openapi/application/PathManager.java +++ b/platform/util/src/com/intellij/openapi/application/PathManager.java @@ -34,13 +34,13 @@ import java.util.PropertyResourceBundle; import java.util.Set; public class PathManager { - @NonNls private static final String PROPERTIES_FILE = "idea.properties.file"; - @NonNls private static final String PROPERTY_SYSTEM_PATH = "idea.system.path"; - @NonNls private static final String PROPERTY_CONFIG_PATH = "idea.config.path"; - @NonNls private static final String PROPERTY_PLUGINS_PATH = "idea.plugins.path"; - @NonNls private static final String PROPERTY_HOME_PATH = "idea.home.path"; - @NonNls private static final String PROPERTY_LOG_PATH = "idea.log.path"; - @NonNls private static final String PROPERTY_PATHS_SELECTOR = "idea.paths.selector"; + @NonNls public static final String PROPERTIES_FILE = "idea.properties.file"; + @NonNls public static final String PROPERTY_SYSTEM_PATH = "idea.system.path"; + @NonNls public static final String PROPERTY_CONFIG_PATH = "idea.config.path"; + @NonNls public static final String PROPERTY_PLUGINS_PATH = "idea.plugins.path"; + @NonNls public static final String PROPERTY_HOME_PATH = "idea.home.path"; + @NonNls public static final String PROPERTY_LOG_PATH = "idea.log.path"; + @NonNls public static final String PROPERTY_PATHS_SELECTOR = "idea.paths.selector"; @NonNls private static String ourHomePath; @NonNls private static String ourSystemPath; @@ -176,8 +176,7 @@ public class PathManager { final String selector = getPathsSelector(); // Mac: ~/Library/Preferences/@@selector@@ // Others: ~/.@@selector@@/config - ourConfigPath = SystemProperties.getUserHome() + (SystemInfo.isMac ? "/Library/Preferences/" + selector - : File.separator + "." + selector + File.separator + "config"); + ourConfigPath = getDefaultConfigPathFor(selector); } else { ourConfigPath = getHomePath() + File.separator + "config"; @@ -185,6 +184,11 @@ public class PathManager { return ourConfigPath; } + public static String getDefaultConfigPathFor(String selector) { + return SystemProperties.getUserHome() + (SystemInfo.isMac ? "/Library/Preferences/" + selector + : File.separator + "." + selector + File.separator + "config"); + } + public static String getPathsSelector() { return System.getProperty(PROPERTY_PATHS_SELECTOR); } From 20e8603438ea29d71c2a51c24a2d820071fd4129 Mon Sep 17 00:00:00 2001 From: "Rustam.Vishnyakov" Date: Thu, 20 Oct 2011 15:06:52 +0400 Subject: [PATCH 077/128] Fix for EA-30598, EA-29115 --- ...emplateLanguageFormattingModelBuilder.java | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/formatting/templateLanguages/TemplateLanguageFormattingModelBuilder.java b/platform/lang-impl/src/com/intellij/formatting/templateLanguages/TemplateLanguageFormattingModelBuilder.java index a6027b2104a1..ea260305e183 100644 --- a/platform/lang-impl/src/com/intellij/formatting/templateLanguages/TemplateLanguageFormattingModelBuilder.java +++ b/platform/lang-impl/src/com/intellij/formatting/templateLanguages/TemplateLanguageFormattingModelBuilder.java @@ -53,20 +53,23 @@ public abstract class TemplateLanguageFormattingModelBuilder implements Delegati if (node == null) { return createDummyBlock(node); } - final Language dataLanguage = ((TemplateLanguageFileViewProvider)viewProvider).getTemplateDataLanguage(); - final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forLanguage(dataLanguage); - if (builder instanceof DelegatingFormattingModelBuilder && ((DelegatingFormattingModelBuilder)builder).dontFormatMyModel()) { - return createDummyBlock(node); + if (viewProvider instanceof TemplateLanguageFileViewProvider) { + final Language dataLanguage = ((TemplateLanguageFileViewProvider)viewProvider).getTemplateDataLanguage(); + final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forLanguage(dataLanguage); + if (builder instanceof DelegatingFormattingModelBuilder && ((DelegatingFormattingModelBuilder)builder).dontFormatMyModel()) { + return createDummyBlock(node); + } + if (builder != null) { + final FormattingModel model = builder.createModel(viewProvider.getPsi(dataLanguage), settings); + List childWrappers = buildChildWrappers(model.getRootBlock()); + if (childWrappers.size() == 1) { + childWrappers = buildChildWrappers(childWrappers.get(0).getOriginal()); + } + return createTemplateLanguageBlock(node, Wrap.createWrap(WrapType.NONE, false), null, + filterBlocksByRange(childWrappers, node.getTextRange()), settings); + } } - if (builder == null) { - return createTemplateLanguageBlock(node, Wrap.createWrap(WrapType.NONE, false), null, Collections.emptyList(), settings); - } - final FormattingModel model = builder.createModel(viewProvider.getPsi(dataLanguage), settings); - List childWrappers = buildChildWrappers(model.getRootBlock()); - if (childWrappers.size() == 1) { - childWrappers = buildChildWrappers(childWrappers.get(0).getOriginal()); - } - return createTemplateLanguageBlock(node, Wrap.createWrap(WrapType.NONE, false), null, filterBlocksByRange(childWrappers, node.getTextRange()), settings); + return createTemplateLanguageBlock(node, Wrap.createWrap(WrapType.NONE, false), null, Collections.emptyList(), settings); } protected AbstractBlock createDummyBlock(final ASTNode node) { From a01130f200531efeb67740eb929170ab847d54f6 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 20 Oct 2011 13:43:42 +0200 Subject: [PATCH 078/128] EA-30380 (CCE: EmptyDirectoryInspection.runInspection) --- .../packaging/EmptyDirectoryInspection.java | 60 +++++++------------ 1 file changed, 23 insertions(+), 37 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/packaging/EmptyDirectoryInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/packaging/EmptyDirectoryInspection.java index 4bb4521e6520..68fd50f9cc94 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/packaging/EmptyDirectoryInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/packaging/EmptyDirectoryInspection.java @@ -26,20 +26,20 @@ import com.intellij.openapi.roots.ContentIterator; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Computable; -import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiManager; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.SearchScope; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseGlobalInspection; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.JComponent; +import javax.swing.*; public class EmptyDirectoryInspection extends BaseGlobalInspection { @@ -61,15 +61,16 @@ public class EmptyDirectoryInspection extends BaseGlobalInspection { } @Override - public void runInspection( - final AnalysisScope scope, final InspectionManager manager, + public void runInspection(final AnalysisScope scope, final InspectionManager manager, final GlobalInspectionContext context, final ProblemDescriptionsProcessor processor) { final Project project = context.getProject(); - final ProjectFileIndex index = - ProjectRootManager.getInstance(project).getFileIndex(); - final GlobalSearchScope searchScope = - (GlobalSearchScope)scope.toSearchScope(); + final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex(); + final SearchScope searchScope = scope.toSearchScope(); + if (!(searchScope instanceof GlobalSearchScope)) { + return; + } + final GlobalSearchScope globalSearchScope = (GlobalSearchScope)searchScope; final PsiManager psiManager = PsiManager.getInstance(project); index.iterateContent(new ContentIterator() { @Override @@ -77,19 +78,17 @@ public class EmptyDirectoryInspection extends BaseGlobalInspection { if (!fileOrDir.isDirectory()) { return true; } - if (!searchScope.contains(fileOrDir)) { + if (!globalSearchScope.contains(fileOrDir)) { return true; } - if (onlyReportDirectoriesUnderSourceRoots && - !index.isInSourceContent(fileOrDir)) { + if (onlyReportDirectoriesUnderSourceRoots && !index.isInSourceContent(fileOrDir)) { return true; } final VirtualFile[] children = fileOrDir.getChildren(); if (children.length != 0) { return true; } - final Application application = - ApplicationManager.getApplication(); + final Application application = ApplicationManager.getApplication(); final PsiDirectory directory = application.runReadAction( new Computable() { @Override @@ -97,36 +96,25 @@ public class EmptyDirectoryInspection extends BaseGlobalInspection { return psiManager.findDirectory(fileOrDir); } }); - final RefElement refDirectory = - context.getRefManager().getReference(directory); - if (context.shouldCheck(refDirectory, - EmptyDirectoryInspection.this)) { + final RefElement refDirectory = context.getRefManager().getReference(directory); + if (context.shouldCheck(refDirectory, EmptyDirectoryInspection.this)) { return true; } - final String relativePath = - getPathRelativeToModule(fileOrDir, project); + final String relativePath = getPathRelativeToModule(fileOrDir, project); if (relativePath == null) { return true; } - processor.addProblemElement(refDirectory, - manager.createProblemDescriptor( - InspectionGadgetsBundle.message( - "empty.directories.problem.descriptor", - relativePath), - new EmptyPackageFix(fileOrDir.getUrl(), - fileOrDir.getName()))); + processor.addProblemElement(refDirectory, manager.createProblemDescriptor(InspectionGadgetsBundle.message( + "empty.directories.problem.descriptor", relativePath), new EmptyPackageFix(fileOrDir.getUrl(), fileOrDir.getName()))); return true; } }); } @Nullable - private static String getPathRelativeToModule(VirtualFile file, - Project project) { - final ProjectRootManager rootManager = - ProjectRootManager.getInstance(project); - final Application application = - ApplicationManager.getApplication(); + private static String getPathRelativeToModule(VirtualFile file, Project project) { + final ProjectRootManager rootManager = ProjectRootManager.getInstance(project); + final Application application = ApplicationManager.getApplication(); final VirtualFile[] contentRoots = application.runReadAction( new Computable() { @Override @@ -135,7 +123,7 @@ public class EmptyDirectoryInspection extends BaseGlobalInspection { } }); for (VirtualFile otherRoot : contentRoots) { - if (VfsUtil.isAncestor(otherRoot, file, false)) { + if (VfsUtilCore.isAncestor(otherRoot, file, false)) { return VfsUtilCore.getRelativePath(file, otherRoot, '/'); } } @@ -166,10 +154,8 @@ public class EmptyDirectoryInspection extends BaseGlobalInspection { } @Override - public void applyFix(@NotNull Project project, - @NotNull CommonProblemDescriptor descriptor) { - final VirtualFile file = - VirtualFileManager.getInstance().findFileByUrl(url); + public void applyFix(@NotNull Project project, @NotNull CommonProblemDescriptor descriptor) { + final VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url); if (file == null) { return; } From 59fa7d3aa565b01ecf0fb067a4336af2c174bf5b Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 20 Oct 2011 15:55:45 +0400 Subject: [PATCH 079/128] xdebugger: avoid firing 'breakpointChanged' events for temporary default breakpoints created during save --- .../impl/breakpoints/XBreakpointManagerImpl.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java index 52412df69364..df17bb4a726a 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java @@ -50,6 +50,7 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta public static final SkipDefaultValuesSerializationFilters SERIALIZATION_FILTER = new SkipDefaultValuesSerializationFilters(); private final MultiValuesMap> myBreakpoints = new MultiValuesMap>(true); private final Map> myDefaultBreakpoints = new LinkedHashMap>(); + private final Set> myAllBreakpoints = new HashSet>(); private final Map> myDispatchers = new HashMap>(); private final Map, XBreakpointTypeDialogState> myBreakpointsDialogSettings = new HashMap, XBreakpointTypeDialogState>(); private final EventDispatcher myAllBreakpointsDispatcher; @@ -128,6 +129,7 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta else { myBreakpoints.put(type, breakpoint); } + myAllBreakpoints.add(breakpoint); if (breakpoint instanceof XLineBreakpointImpl) { myLineBreakpointManager.registerBreakpoint((XLineBreakpointImpl)breakpoint, initUI); } @@ -145,6 +147,10 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta } public void fireBreakpointChanged(XBreakpointBase breakpoint) { + if (!myAllBreakpoints.contains(breakpoint)) { + return; + } + if (breakpoint instanceof XLineBreakpointImpl) { myLineBreakpointManager.breakpointChanged((XLineBreakpointImpl)breakpoint); } @@ -165,6 +171,7 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta XBreakpointType type = breakpoint.getType(); XBreakpointBase breakpointBase = (XBreakpointBase)breakpoint; myBreakpoints.remove(type, breakpointBase); + myAllBreakpoints.remove(breakpointBase); if (breakpointBase instanceof XLineBreakpointImpl) { myLineBreakpointManager.unregisterBreakpoint((XLineBreakpointImpl)breakpointBase); } @@ -189,10 +196,7 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta @NotNull public XBreakpointBase[] getAllBreakpoints() { ApplicationManager.getApplication().assertReadAccessAllowed(); - List> breakpoints = new ArrayList>(); - breakpoints.addAll(myDefaultBreakpoints.values()); - breakpoints.addAll(myBreakpoints.values()); - return breakpoints.toArray(new XBreakpointBase[breakpoints.size()]); + return myAllBreakpoints.toArray(new XBreakpointBase[myAllBreakpoints.size()]); } @SuppressWarnings({"unchecked"}) @@ -322,6 +326,7 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta } } + myAllBreakpoints.clear(); myDefaultBreakpoints.clear(); for (BreakpointState breakpointState : state.getDefaultBreakpoints()) { loadBreakpoint(breakpointState, true); From 8088b75bda8eefc0471ed428fe4b75c639bdc445 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 20 Oct 2011 14:07:58 +0200 Subject: [PATCH 080/128] propagate "dirty" state for all modules that depend on dirty modules cleanup output directories for dirty modules and for modules being rebuilt --- .../jps/incremental/CompileContext.java | 79 +++++++++--------- .../jps/incremental/IncProjectBuilder.java | 81 ++++++++++++++++--- .../src/org/jetbrains/jps/PathUtil.java | 0 3 files changed, 107 insertions(+), 53 deletions(-) rename jps/{ => model}/src/org/jetbrains/jps/PathUtil.java (100%) diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java index f4ccdd1fbc3b..60cb028c7bb5 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java @@ -4,9 +4,7 @@ import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.util.containers.SLRUCache; import org.jetbrains.annotations.NotNull; import org.jetbrains.ether.dependencyView.Mappings; -import org.jetbrains.jps.Module; -import org.jetbrains.jps.ModuleChunk; -import org.jetbrains.jps.Project; +import org.jetbrains.jps.*; import org.jetbrains.jps.incremental.messages.BuildMessage; import org.jetbrains.jps.incremental.storage.BuildDataManager; @@ -23,6 +21,8 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler private final CompileScope myScope; private final boolean myIsMake; + private final ProjectChunks myProductionChunks; + private final ProjectChunks myTestChunks; private final MessageHandler myDelegateMessageHandler; private volatile boolean myCompilingTests = false; private final BuildDataManager myDataManager; @@ -36,9 +36,17 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler } }; - public CompileContext(CompileScope scope, String projectName, boolean isMake, final Mappings mappings, MessageHandler delegateMessageHandler) { + public CompileContext(CompileScope scope, + String projectName, + boolean isMake, + final Mappings mappings, + ProjectChunks productionChunks, + ProjectChunks testChunks, + MessageHandler delegateMessageHandler) { myScope = scope; myIsMake = isMake; + myProductionChunks = productionChunks; + myTestChunks = testChunks; myDelegateMessageHandler = delegateMessageHandler; final File buildDataRoot = new File(System.getProperty("user.home"), ".jps" + File.separator + projectName + File.separator + "build_data"); myDataManager = new BuildDataManager(buildDataRoot); @@ -55,13 +63,17 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler public boolean isDirty(ModuleChunk chunk) { for (Module module : chunk.getModules()) { - if (myDirtyModules.contains(module)) { + if (isDirty(module)) { return true; } } return false; } + public boolean isDirty(Module module) { + return myDirtyModules.contains(module); + } + public void setDirty(ModuleChunk chunk, boolean isDirty) { final Set modules = chunk.getModules(); if (isDirty) { @@ -70,6 +82,28 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler else { myDirtyModules.removeAll(modules); } + + // now mark all modules that depend on dirty modules + final ClasspathKind classpathKind = ClasspathKind.compile(isCompilingTests()); + final ProjectChunks chunks = isCompilingTests()? myTestChunks : myProductionChunks; + boolean found = false; + for (ModuleChunk moduleChunk : chunks.getChunkList()) { + if (!found) { + if (moduleChunk.equals(chunk)) { + found = true; + } + } + else { + MODULES_LOOP: for (final Module module : moduleChunk.getModules()) { + for (ClasspathItem dependency : module.getClasspath(classpathKind)) { + if (dependency instanceof Module && isDirty((Module)dependency)) { + myDirtyModules.addAll(moduleChunk.getModules()); + break MODULES_LOOP; + } + } + } + } + } } public Mappings getMappings() { @@ -111,22 +145,6 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler } /** @noinspection unchecked*/ - //private boolean processModule(Module module, FileProcessor processor) throws Exception { - // final Set excludes = new HashSet(); - // for (String excludePath : (Collection)module.getExcludes()) { - // excludes.add(new File(excludePath)); - // } - // - // final Collection roots = myCompilingTests? (Collection)module.getTestRoots() : (Collection)module.getSourceRoots(); - // for (String root : roots) { - // final File rootFile = new File(root); - // if (!processRootRecursively(module, rootFile, root, processor, excludes)) { - // return false; - // } - // } - // return true; - //} - private FSSnapshot buildSnapshot(Module module) { final Set excludes = new HashSet(); for (String excludePath : (Collection)module.getExcludes()) { @@ -141,25 +159,6 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler return snapshot; } - //private static boolean processRootRecursively(final Module module, final File fromFile, final String sourceRoot, FileProcessor processor, final Set excluded) throws Exception { - // if (fromFile.isDirectory()) { - // if (isExcluded(excluded, fromFile)) { - // return true; - // } - // final File[] children = fromFile.listFiles(); - // if (children != null) { - // for (File child : children) { - // final boolean shouldContinue = processRootRecursively(module, child, sourceRoot, processor, excluded); - // if (!shouldContinue) { - // return false; - // } - // } - // } - // return true; - // } - // return processor.apply(module, fromFile, sourceRoot); - //} - private static void buildStructure(final FSSnapshot.Node from, final Set excluded) { final File nodeFile = from.getFile(); if (nodeFile.isDirectory()) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index 80052589dc3d..9e3f5d78bb20 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -1,12 +1,14 @@ package org.jetbrains.jps.incremental; +import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.ether.dependencyView.Mappings; import org.jetbrains.jps.*; import org.jetbrains.jps.incremental.messages.BuildMessage; +import org.jetbrains.jps.incremental.messages.CompilerMessage; import org.jetbrains.jps.incremental.messages.ProgressMessage; -import java.util.ArrayList; -import java.util.List; +import java.io.File; +import java.util.*; /** * @author Eugene Zhuravlev @@ -14,7 +16,6 @@ import java.util.List; */ public class IncProjectBuilder { - private final Project myProject; private final String myProjectName; private final BuilderRegistry myBuilderRegistry; private ProjectChunks myProductionChunks; @@ -23,7 +24,6 @@ public class IncProjectBuilder { private final Mappings myMappings; public IncProjectBuilder(Project project, String projectName, final Mappings mappings, BuilderRegistry builderRegistry) { - myProject = project; myProjectName = projectName; myBuilderRegistry = builderRegistry; myProductionChunks = new ProjectChunks(project, ClasspathKind.PRODUCTION_COMPILE); @@ -36,7 +36,7 @@ public class IncProjectBuilder { } public void build(CompileScope scope, final boolean isMake) { - final CompileContext context = new CompileContext(scope, myProjectName, isMake, myMappings, new MessageHandler() { + final CompileContext context = new CompileContext(scope, myProjectName, isMake, myMappings, myProductionChunks, myTestChunks, new MessageHandler() { public void processMessage(BuildMessage msg) { for (MessageHandler h : myMessageHandlers) { h.processMessage(msg); @@ -44,14 +44,7 @@ public class IncProjectBuilder { } }); try { - if (!isMake) { - context.getBuildDataManager().clean(); - } - - for (Module module : scope.getAffectedModules()) { - //context.processMessage(new ProgressMessage("Cleaning module " + module.getName())); - //myProject.cleanModule(module); - } + cleanOutputRoots(scope, context); runTasks(context, myBuilderRegistry.getBeforeTasks()); @@ -71,6 +64,68 @@ public class IncProjectBuilder { } } + private void cleanOutputRoots(CompileScope scope, CompileContext context) { + final Collection allProjectModules = scope.getProject().getModules().values(); + final Collection modulesToClean = new HashSet(); + + if (context.isMake()) { + for (Module module : scope.getAffectedModules()) { + if (context.isDirty(module)) { + modulesToClean.add(module); + } + } + } + else { + modulesToClean.addAll(scope.getAffectedModules()); + + final Set allModules = new HashSet(allProjectModules); + allModules.removeAll(scope.getAffectedModules()); + if (allModules.isEmpty()) { + // whole project is affected + context.getBuildDataManager().clean(); + } + } + + if (!modulesToClean.isEmpty()) { + final Set toDelete = new HashSet(); + final Set allSourceRoots = new HashSet(); + for (Module module : modulesToClean) { + toDelete.add(new File(module.getOutputPath())); + toDelete.add(new File(module.getTestOutputPath())); + } + for (Module module : allProjectModules) { + for (Object root : module.getSourceRoots()) { + allSourceRoots.add(new File((String)root)); + } + for (Object root : module.getTestRoots()) { + allSourceRoots.add(new File((String)root)); + } + } + // check that output and source roots are not overlapping + for (File outputRoot : toDelete) { + boolean okToDelete = true; + if (PathUtil.isUnder(allSourceRoots, outputRoot)) { + okToDelete = false; + } + else { + final Set _outRoot = Collections.singleton(outputRoot); + for (File srcRoot : allSourceRoots) { + if (PathUtil.isUnder(_outRoot, srcRoot)) { + okToDelete = false; + break; + } + } + } + if (okToDelete) { + FileUtil.delete(outputRoot); + } + else { + context.processMessage(new CompilerMessage("JPS BUILD", BuildMessage.Kind.WARNING, "Output path " + outputRoot.getPath() + " intersects with a source root. The output cannot be cleaned.")); + } + } + } + } + private static void runTasks(CompileContext context, final List tasks) throws ProjectBuildException { for (BuildTask task : tasks) { task.build(context); diff --git a/jps/src/org/jetbrains/jps/PathUtil.java b/jps/model/src/org/jetbrains/jps/PathUtil.java similarity index 100% rename from jps/src/org/jetbrains/jps/PathUtil.java rename to jps/model/src/org/jetbrains/jps/PathUtil.java From d2ca52024740cd7e48a356f059404defa612983f Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 20 Oct 2011 14:26:19 +0200 Subject: [PATCH 081/128] NPE fixes --- .../jetbrains/jps/incremental/CompileContext.java | 6 ++++++ .../jps/incremental/IncProjectBuilder.java | 10 ++++++++-- .../jps/incremental/java/JavaBuilder.java | 5 +---- jps/model/src/org/jetbrains/jps/ProjectPaths.java | 14 +++++++++----- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java index 60cb028c7bb5..9aac9714ea7b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java @@ -35,6 +35,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler return buildSnapshot(key); } }; + private final ProjectPaths myProjectPaths; public CompileContext(CompileScope scope, String projectName, @@ -51,12 +52,17 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler final File buildDataRoot = new File(System.getProperty("user.home"), ".jps" + File.separator + projectName + File.separator + "build_data"); myDataManager = new BuildDataManager(buildDataRoot); myMappings = mappings; + myProjectPaths = new ProjectPaths(scope.getProject()); } public Project getProject() { return myScope.getProject(); } + public ProjectPaths getProjectPaths() { + return myProjectPaths; + } + public boolean isMake() { return myIsMake; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index 9e3f5d78bb20..816d640d132f 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -90,8 +90,14 @@ public class IncProjectBuilder { final Set toDelete = new HashSet(); final Set allSourceRoots = new HashSet(); for (Module module : modulesToClean) { - toDelete.add(new File(module.getOutputPath())); - toDelete.add(new File(module.getTestOutputPath())); + final File out = context.getProjectPaths().getModuleOutputDir(module, false); + if (out != null) { + toDelete.add(out); + } + final File testOut = context.getProjectPaths().getModuleOutputDir(module, true); + if (testOut != null) { + toDelete.add(testOut); + } } for (Module module : allProjectModules) { for (Object root : module.getSourceRoots()) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index 5494e3150053..1c46093f3890 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -189,10 +189,7 @@ public class JavaBuilder extends Builder{ return exitCode; } - ProjectPaths paths = ProjectPaths.KEY.get(context); - if (paths == null) { - ProjectPaths.KEY.set(context, paths = new ProjectPaths(context.getProject())); - } + final ProjectPaths paths = context.getProjectPaths(); final Mappings delta = new Mappings(); DELTA_MAPPINGS_CALLBACK_KEY.set(context, delta.getCallback()); diff --git a/jps/model/src/org/jetbrains/jps/ProjectPaths.java b/jps/model/src/org/jetbrains/jps/ProjectPaths.java index c2bcc3aef590..156833963f59 100644 --- a/jps/model/src/org/jetbrains/jps/ProjectPaths.java +++ b/jps/model/src/org/jetbrains/jps/ProjectPaths.java @@ -1,6 +1,5 @@ package org.jetbrains.jps; -import com.intellij.openapi.util.Key; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -12,8 +11,6 @@ import java.util.*; * Date: 9/30/11 */ public class ProjectPaths { - public static final Key KEY = Key.create("_project_paths_"); - @NotNull private final Project myProject; @Nullable @@ -81,10 +78,16 @@ public class ProjectPaths { if (it instanceof ModuleSourceEntry) { final Module dep = ((ModuleSourceEntry) it).getModule(); if (!excludeMainModuleOutput && kind.isTestsIncluded()) { - classpath.add(getModuleOutputDir(dep, true)); + final File out = getModuleOutputDir(dep, true); + if (out != null) { + classpath.add(out); + } } if (!excludeMainModuleOutput || kind.isTestsIncluded()) { - classpath.add(getModuleOutputDir(dep, false)); + final File out = getModuleOutputDir(dep, false); + if (out != null) { + classpath.add(out); + } } } else if (it instanceof Module) { @@ -169,6 +172,7 @@ public class ProjectPaths { (forTests ? myCustomModuleTestOutputDir : myCustomModuleOutputDir).put(module, outputDir); } + @Nullable public File getModuleOutputDir(Module module, boolean forTests) { File customOutput = (forTests ? myCustomModuleTestOutputDir : myCustomModuleOutputDir).get(module); if (customOutput != null) { From 3d7aec2e808a70bfa625e00cf2e1ca04298d787a Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 20 Oct 2011 14:29:24 +0200 Subject: [PATCH 082/128] independent paths --- .../src/org/jetbrains/jps/incremental/java/JavaBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index 1c46093f3890..7f095b567fe6 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -79,7 +79,7 @@ public class JavaBuilder extends Builder{ //noinspection SynchronizationOnLocalVariableOrMethodParameter synchronized (callback) { // todo: parse class data out of synchronized block (move it from the 'associate' implementation) - callback.associate(className, Callbacks.getDefaultLookup(srcFile.getPath()), reader); + callback.associate(className, Callbacks.getDefaultLookup(FileUtil.toSystemIndependentName(srcFile.getPath())), reader); } } } From 1f9308d6a7a22feb5f6d85efbbdeedccd8af244c Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Thu, 20 Oct 2011 15:44:11 +0400 Subject: [PATCH 083/128] old settings importer: launch candidates should include launch files for platform based IDEs, not only for IDEA. --- .../application/ConfigImportHelper.java | 61 ++++++++++++------- .../application/ConfigImportSettings.java | 12 ++++ .../application/ImportOldConfigsPanel.java | 3 +- 3 files changed, 52 insertions(+), 24 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java index 5529f305ba64..44095805148d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java @@ -31,6 +31,8 @@ import javax.swing.*; import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; import java.util.PropertyResourceBundle; /** @@ -203,7 +205,7 @@ public class ConfigImportHelper { return new File(oldInstallHome, "config"); } - final File[] launchFileCandidates = getLaunchFilesCandidates(oldInstallHome); + final File[] launchFileCandidates = getLaunchFilesCandidates(oldInstallHome, settings); // custom config folder for (File candidate : launchFileCandidates) { @@ -235,28 +237,40 @@ public class ConfigImportHelper { } @SuppressWarnings({"HardCodedStringLiteral"}) - private static File[] getLaunchFilesCandidates(File instHome) { - File bin = new File(instHome, BIN_FOLDER); + private static File[] getLaunchFilesCandidates(@NotNull final File instHome, @NotNull final ConfigImportSettings settings) { + final File bin = new File(instHome, BIN_FOLDER); + final List files = new ArrayList(); if (SystemInfo.isMac) { - return new File[]{ - new File(new File(instHome, "Contents"), "Info.plist"), - new File(new File(new File(bin, "idea.app"), "Contents"), "Info.plist"), - new File(new File(new File(instHome, "idea.app"), "Contents"), "Info.plist"), - new File(bin, "idea.properties"), - //TODO? other minor IDEs? - new File(bin, "idea.lax"), - new File(bin, "idea.bat"), - new File(bin, "idea.sh") - }; + // Info.plist + files.add(new File(new File(instHome, "Contents"), "Info.plist")); + + files.add(new File(new File(new File(bin, "idea.app"), "Contents"), "Info.plist")); + files.add(new File(new File(new File(instHome, "idea.app"), "Contents"), "Info.plist")); } - else { - return new File[]{ - new File(bin, "idea.properties"), - new File(bin, "idea.lax"), - new File(bin, "idea.bat"), - new File(bin, "idea.sh") - }; + // idea.properties + files.add(new File(bin, "idea.properties")); + + + // other binary scripts + final String executableName = StringUtil.toLowerCase(settings.getProductName(ThreeState.NO)); + // * defaults: + addLaunchExecutableScriptsCandidates(files, executableName, bin); + // * customized files: + files.addAll(settings.getCustomLaunchFilesCandidates(instHome, bin)); + // * legacy support: + if (!"idea".equals(executableName)) { + // for compatibility with some platform-base IDEs with wrong executable names + addLaunchExecutableScriptsCandidates(files, "idea", bin); } + return files.toArray(new File[files.size()]); + } + + private static void addLaunchExecutableScriptsCandidates(final List files, + final String executableName, + final File binFolder) { + files.add(new File(binFolder, executableName + ".lax")); + files.add(new File(binFolder, executableName + ".bat")); + files.add(new File(binFolder, executableName + ".sh")); } @SuppressWarnings({"HardCodedStringLiteral"}) @@ -374,17 +388,18 @@ public class ConfigImportHelper { return dir; } - public static boolean isInstallationHomeOrConfig(String installationHome, String productName) { + public static boolean isInstallationHomeOrConfig(@NotNull final String installationHome, + @NotNull final ConfigImportSettings settings) { if (new File(installationHome, OPTIONS_XML).exists()) return true; if (new File(installationHome, CONFIG_RELATED_PATH + OPTIONS_XML).exists()) return true; - String mainJarName = StringUtil.toLowerCase(productName) + ".jar"; + String mainJarName = StringUtil.toLowerCase(settings.getProductName(ThreeState.NO)) + ".jar"; //noinspection HardCodedStringLiteral boolean quickTest = new File(new File(installationHome, "lib"), mainJarName).exists() && new File(installationHome, BIN_FOLDER).exists(); if (!quickTest) return false; - File[] files = getLaunchFilesCandidates(new File(installationHome)); + File[] files = getLaunchFilesCandidates(new File(installationHome), settings); for (File file : files) { if (file.exists()) return true; } diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportSettings.java b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportSettings.java index d1c15def3eba..010d459efa0f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportSettings.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportSettings.java @@ -2,9 +2,12 @@ package com.intellij.openapi.application; import com.intellij.util.SystemProperties; import com.intellij.util.ThreeState; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; +import java.util.Collections; +import java.util.List; /** * User: ksafonov @@ -69,4 +72,13 @@ public class ConfigImportSettings { public void importFinished(String newConfigPath) { } + + @NotNull + public List getCustomLaunchFilesCandidates(final File ideInstallationHome, + final File ideBinFolder) { + // custom files where to find config folder or path selector properties. + // by default "Info.plist", "idea.properties"; "idea.sh,idea.bat,..." and + // "product_lower_name.sh, product_lower_name.bat,..." are used + return Collections.emptyList(); + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ImportOldConfigsPanel.java b/platform/platform-impl/src/com/intellij/openapi/application/ImportOldConfigsPanel.java index b61058070aab..3e125e0cfbe3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/ImportOldConfigsPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/ImportOldConfigsPanel.java @@ -207,7 +207,8 @@ public class ImportOldConfigsPanel extends JDialog { return; } - if (myRbImport.isSelected() && !ConfigImportHelper.isInstallationHomeOrConfig(instHome, mySettings.getProductName(ThreeState.NO))) { + assert instHome != null; + if (myRbImport.isSelected() && !ConfigImportHelper.isInstallationHomeOrConfig(instHome, mySettings)) { JOptionPane.showMessageDialog(this, mySettings.getInvalidHomeErrorText(productWithVendor, instHome), mySettings.getInstallationHomeRequiredTitle(), JOptionPane.ERROR_MESSAGE); From 68e216f1eca9f478526f055a9c6f37701a0a5fb2 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 20 Oct 2011 14:47:47 +0200 Subject: [PATCH 084/128] IDEA-75615 ("Quality with outer class" inspection problem) --- ...UnqualifiedInnerClassAccessInspection.java | 93 ++++++------------- .../unqualified_inner_class_access/Test.java | 6 ++ .../expected.xml | 19 ++-- ...alifiedInnerClassAccessInspectionTest.java | 5 +- 4 files changed, 45 insertions(+), 78 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedInnerClassAccessInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedInnerClassAccessInspection.java index 581117cc45dc..608de25da3ed 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedInnerClassAccessInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedInnerClassAccessInspection.java @@ -43,23 +43,19 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection { @NotNull @Override public String getDisplayName() { - return InspectionGadgetsBundle.message( - "unqualified.inner.class.access.display.name"); + return InspectionGadgetsBundle.message("unqualified.inner.class.access.display.name"); } @NotNull @Override protected String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "unqualified.inner.class.access.problem.descriptor"); + return InspectionGadgetsBundle.message("unqualified.inner.class.access.problem.descriptor"); } @Override public JComponent createOptionsPanel() { - return new SingleCheckboxOptionsPanel( - InspectionGadgetsBundle.message( - "unqualified.inner.class.access.option"), - this, "ignoreReferencesToLocalInnerClasses"); + return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("unqualified.inner.class.access.option"), + this, "ignoreReferencesToLocalInnerClasses"); } @Override @@ -67,8 +63,7 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection { return new UnqualifiedInnerClassAccessFix(); } - private static class UnqualifiedInnerClassAccessFix - extends InspectionGadgetsFix { + private static class UnqualifiedInnerClassAccessFix extends InspectionGadgetsFix { @NotNull public String getName() { @@ -77,14 +72,12 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection { } @Override - protected void doFix(Project project, ProblemDescriptor descriptor) - throws IncorrectOperationException { + protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement element = descriptor.getPsiElement(); if (!(element instanceof PsiJavaCodeReferenceElement)) { return; } - final PsiJavaCodeReferenceElement referenceElement = - (PsiJavaCodeReferenceElement)element; + final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)element; final PsiElement target = referenceElement.resolve(); if (!(target instanceof PsiClass)) { return; @@ -111,8 +104,7 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection { if (importList == null) { return; } - final PsiImportStatement[] importStatements = - importList.getImportStatements(); + final PsiImportStatement[] importStatements = importList.getImportStatements(); final int importStatementsLength = importStatements.length; boolean onDemand = false; PsiImportStatement referenceImportStatement = null; @@ -135,41 +127,33 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection { } final ReferenceCollector referenceCollector; if (onDemand) { - referenceCollector = - new ReferenceCollector(qualifiedName, onDemand); + referenceCollector = new ReferenceCollector(qualifiedName, onDemand); } else { - referenceCollector = - new ReferenceCollector(innerClassName, onDemand); + referenceCollector = new ReferenceCollector(innerClassName, onDemand); } final PsiClass[] classes = javaFile.getClasses(); for (PsiClass psiClass : classes) { psiClass.accept(referenceCollector); } - final Collection references = - referenceCollector.getReferences(); - final SmartPointerManager pointerManager = - SmartPointerManager.getInstance(project); + final Collection references = referenceCollector.getReferences(); + final SmartPointerManager pointerManager = SmartPointerManager.getInstance(project); final List pointers = new ArrayList(); for (PsiJavaCodeReferenceElement reference : references) { - final SmartPsiElementPointer pointer = - pointerManager.createSmartPsiElementPointer(reference); + final SmartPsiElementPointer pointer = pointerManager.createSmartPsiElementPointer(reference); pointers.add(pointer); } if (referenceImportStatement != null) { referenceImportStatement.delete(); } ImportUtils.addImportIfNeeded(containingClass, referenceElement); - final PsiDocumentManager documentManager = - PsiDocumentManager.getInstance(project); - final Document document = - documentManager.getDocument(containingFile); + final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); + final Document document = documentManager.getDocument(containingFile); if (document == null) { return; } documentManager.doPostponedOperationsAndUnblockDocument(document); - final String text = buildNewText(javaFile, references, - containingClass, new StringBuilder()).toString(); + final String text = buildNewText(javaFile, references, containingClass, new StringBuilder()).toString(); document.replaceString(0, document.getTextLength(), text); documentManager.commitDocument(document); if (pointers.size() > 1) { @@ -181,11 +165,8 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection { } } - - private static StringBuilder buildNewText( - PsiElement element, - Collection references, - PsiClass aClass, StringBuilder out) { + private static StringBuilder buildNewText(PsiElement element, Collection references, + PsiClass aClass, StringBuilder out) { if (element == null) { return out; } @@ -211,16 +192,11 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection { return out; } - private static boolean isReferenceToTargetClass( - String referenceText, PsiClass targetClass, - PsiElement context) { + private static boolean isReferenceToTargetClass(String referenceText, PsiClass targetClass, PsiElement context) { final PsiManager manager = targetClass.getManager(); - final JavaPsiFacade facade = - JavaPsiFacade.getInstance(manager.getProject()); + final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject()); final PsiResolveHelper resolveHelper = facade.getResolveHelper(); - final PsiClass referencedClass = - resolveHelper.resolveReferencedClass(referenceText, - context); + final PsiClass referencedClass = resolveHelper.resolveReferencedClass(referenceText, context); if (referencedClass == null) { return true; } @@ -228,13 +204,11 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection { } } - private static class ReferenceCollector - extends JavaRecursiveElementVisitor { + private static class ReferenceCollector extends JavaRecursiveElementVisitor { private final String name; private final boolean onDemand; - private final Set references = - new HashSet(); + private final Set references = new HashSet(); ReferenceCollector(String name, boolean onDemand) { this.name = name; @@ -242,8 +216,7 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection { } @Override - public void visitReferenceElement( - PsiJavaCodeReferenceElement reference) { + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { super.visitReferenceElement(reference); if (reference.isQualified()) { return; @@ -271,8 +244,7 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection { } @Override - public void visitReferenceExpression( - PsiReferenceExpression expression) { + public void visitReferenceExpression(PsiReferenceExpression expression) { visitReferenceElement(expression); } @@ -286,12 +258,10 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection { return new UnqualifiedInnerClassAccessVisitor(); } - private class UnqualifiedInnerClassAccessVisitor - extends BaseInspectionVisitor { + private class UnqualifiedInnerClassAccessVisitor extends BaseInspectionVisitor { @Override - public void visitReferenceElement( - PsiJavaCodeReferenceElement reference) { + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { super.visitReferenceElement(reference); if (reference.isQualified()) { return; @@ -309,10 +279,8 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection { if (PsiTreeUtil.isAncestor(containingClass, reference, true)) { return; } - final PsiClass referenceClass = - PsiTreeUtil.getParentOfType(reference, PsiClass.class); - if (PsiTreeUtil.isAncestor(referenceClass, containingClass, - true)) { + final PsiClass referenceClass = PsiTreeUtil.getParentOfType(reference, PsiClass.class); + if (referenceClass != null && referenceClass.isInheritor(containingClass, true)) { return; } } @@ -320,8 +288,7 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection { } @Override - public void visitReferenceExpression( - PsiReferenceExpression expression) { + public void visitReferenceExpression(PsiReferenceExpression expression) { visitReferenceElement(expression); } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_inner_class_access/Test.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_inner_class_access/Test.java index 09ccee47ee2c..c32ed5249be8 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_inner_class_access/Test.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_inner_class_access/Test.java @@ -16,4 +16,10 @@ public class Test { static class Inner { public static final String TEST = "test"; } +} +class A { + class X {} +} +class B extends A { + void foo(X x) {} } \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_inner_class_access/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_inner_class_access/expected.xml index 40f055f0781a..2bc83c222f5c 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_inner_class_access/expected.xml +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_inner_class_access/expected.xml @@ -1,11 +1,11 @@ - - Test.java - 9 - Unqualified inner class access - <code>Entry</code> is not qualified with outer class #loc - + + Test.java + 9 + Unqualified inner class access + <code>Entry</code> is not qualified with outer class #loc + Test.java @@ -21,11 +21,4 @@ <code>Entry</code> is not qualified with outer class #loc - - Test.java - 14 - Unqualified inner class access - <code>Inner</code> is not qualified with outer class #loc - - \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnqualifiedInnerClassAccessInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnqualifiedInnerClassAccessInspectionTest.java index 2b4e0b39b136..e92c6afd8d34 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnqualifiedInnerClassAccessInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnqualifiedInnerClassAccessInspectionTest.java @@ -6,7 +6,8 @@ public class UnqualifiedInnerClassAccessInspectionTest extends IGInspectionTestCase { public void test() throws Exception { - doTest("com/siyeh/igtest/style/unqualified_inner_class_access", - new UnqualifiedInnerClassAccessInspection()); + final UnqualifiedInnerClassAccessInspection tool = new UnqualifiedInnerClassAccessInspection(); + tool.ignoreReferencesToLocalInnerClasses = true; + doTest("com/siyeh/igtest/style/unqualified_inner_class_access", tool); } } \ No newline at end of file From ec16394f5ed02221e7df679b0b44711846ed535d Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Thu, 20 Oct 2011 16:54:12 +0400 Subject: [PATCH 085/128] RunnerMediator: send ctrl-break before closing stream (last change was incorrect and should be reverted) --- .../src/com/intellij/execution/process/RunnerMediator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/execution/process/RunnerMediator.java b/platform/platform-impl/src/com/intellij/execution/process/RunnerMediator.java index de56defeb3a6..87f8af1ca40f 100644 --- a/platform/platform-impl/src/com/intellij/execution/process/RunnerMediator.java +++ b/platform/platform-impl/src/com/intellij/execution/process/RunnerMediator.java @@ -157,9 +157,9 @@ public class RunnerMediator { } @Override - protected void doDestroyProcess() { + protected void destroyProcessImpl() { if (!RunnerMediator.destroyProcess(getProcess())) { - super.doDestroyProcess(); + super.destroyProcessImpl(); } } } From 0f0b0f359943c3b6a8a00605587ceaf351445bcc Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 20 Oct 2011 13:37:03 +0200 Subject: [PATCH 086/128] read access (EA-30527) --- .../groovy/findUsages/AnnotatedMembersSearcher.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/AnnotatedMembersSearcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/AnnotatedMembersSearcher.java index 89a15e699fa3..86aec323217e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/AnnotatedMembersSearcher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/AnnotatedMembersSearcher.java @@ -76,7 +76,14 @@ public class AnnotatedMembersSearcher implements QueryExecutor Date: Thu, 20 Oct 2011 13:39:58 +0200 Subject: [PATCH 087/128] tolerate incomplete new expression PSI (EA-30509) --- .../codeInsight/completion/JavaSmartCompletionContributor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java index 6dea9b5e0136..b7c3faaccd52 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java @@ -389,7 +389,8 @@ public class JavaSmartCompletionContributor extends CompletionContributor { if (parameterList == null) return null; PsiElement parent = parameterList.getParent(); - assert parent instanceof PsiJavaCodeReferenceElement : parent + "; text=" + parent.getText(); + if (!(parent instanceof PsiJavaCodeReferenceElement)) return null; + final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)parent; final int parameterIndex; From 9cf9342225fdffd2c92fce5313b071da40655d98 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 20 Oct 2011 16:32:18 +0200 Subject: [PATCH 088/128] fix named argument completion tests --- .../handlers/NamedArgumentInsertHandler.java | 9 +++++---- .../groovy/completion/GroovyCompletionTest.groovy | 12 ++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/NamedArgumentInsertHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/NamedArgumentInsertHandler.java index a06fc1cdbff0..f5664379cd05 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/NamedArgumentInsertHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/NamedArgumentInsertHandler.java @@ -86,16 +86,17 @@ public class NamedArgumentInsertHandler implements InsertHandler else { m = Pattern.compile("([ \\t]*)([\\n \\t]*)[\\],](.*)", Pattern.DOTALL).matcher(s); if (m.matches()) { - editor.getDocument().replaceString(tailOffset, tailOffset + m.start(2), ": "); - editor.getCaretModel().moveToOffset(tailOffset + 2); + editor.getDocument().replaceString(tailOffset, tailOffset + m.start(2), ":"); + editor.getCaretModel().moveToOffset(tailOffset + 1); } else { m = Pattern.compile("([ \\t]*)(.*)", Pattern.DOTALL).matcher(s); if (!m.matches()) throw new RuntimeException("This pattern must match any non-empty string! (" + s + ")"); - String toInsert = m.group(2).startsWith("\n") ? ": ," : ": , "; + String toInsert = m.group(2).startsWith("\n") ? ":," : ":, "; editor.getDocument().replaceString(tailOffset, tailOffset + m.start(2), toInsert); - editor.getCaretModel().moveToOffset(tailOffset + 2); + editor.getCaretModel().moveToOffset(tailOffset + 1); + context.setTailOffset(tailOffset + 1); } } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy index 68578b865319..c0f6aafffcb7 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy @@ -342,7 +342,7 @@ class A { myFixture.checkResult """ class A { public int m(arg) { return arg.arg111 + arg.arg222 + arg.arg333; } - { m (arg111: , zzz) } + { m (arg111:, zzz) } } """ } @@ -361,7 +361,7 @@ class A { myFixture.checkResult(""" class A { public int m(arg) { return arg.arg111 + arg.arg222 + arg.arg333; } - { m (arg111: , { + { m (arg111:, { out << "asdasdas" } ) } } @@ -380,7 +380,7 @@ class A { myFixture.checkResult """ class A { public int m(arg) { return arg.arg111 + arg.arg222 + arg.arg333; } - { m([arg111: ])} + { m([arg111:])} } """ } @@ -414,7 +414,7 @@ class A { myFixture.checkResult """ class A { public int m(arg) { return arg.arg111 + arg.arg222 + arg.arg333; } - { m(arg111: ,)} + { m(arg111:,)} } """ } @@ -517,7 +517,7 @@ class A { class A { public int m(arg) { return arg.arg111 + arg.arg222 + arg.arg333; } { - m(arg111: , + m(arg111:, arg222: 222, ) } @@ -543,7 +543,7 @@ class A { class A { public int m(arg) { return arg.arg111 + arg.arg222 + arg.arg333; } { - m(arg111: + m(arg111: , arg222: 222, arg333: 333, ) From f3f39913bcc336c7cbeb9d6ab64b2b42ebacfa7e Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 20 Oct 2011 17:05:45 +0200 Subject: [PATCH 089/128] IDEA-75758 Tab focus change doesn't work on Mac Snow Leopard --- platform/platform-resources-en/src/misc/registry.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 95941a6aa42c..fa8af6c7e041 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -6,7 +6,7 @@ actionSystem.fixLostTyping=true actionSystem.fixLostTyping.description=Redispatch events, lost between actions and dialog show/close actionSystem.fixStickyFocusedWindows=true actionSystem.fixNullFocusedComponent=true -actionSystem.noDefaultComponent=true +actionSystem.noDefaultComponent=false actionSystem.commandProcessingTimeout=30000 actionSystem.commandProcessingTimeout.description=Timeout after which currently proccessed command is forcibly cancelled actionSystem.typeAheadTimeBeforeDialog=2000 From 557eacf096c2cd362648a522fa4d4eff533bdcab Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Thu, 20 Oct 2011 19:19:12 +0400 Subject: [PATCH 090/128] IDEA-75758 Tab focus change doesnt work on Mac Snow Leopard --- .../openapi/wm/ex/LayoutFocusTraversalPolicyExt.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/ex/LayoutFocusTraversalPolicyExt.java b/platform/platform-impl/src/com/intellij/openapi/wm/ex/LayoutFocusTraversalPolicyExt.java index 6ac6109f7914..50d1d028af8e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/ex/LayoutFocusTraversalPolicyExt.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/ex/LayoutFocusTraversalPolicyExt.java @@ -102,8 +102,6 @@ public class LayoutFocusTraversalPolicyExt extends LayoutFocusTraversalPolicy{ } public Component getFirstComponent(final Container focusCycleRoot) { - if (isNoDefaultComponent()) return null; - if (myOverridenDefaultComponent != null) { return myOverridenDefaultComponent; } @@ -115,8 +113,6 @@ public class LayoutFocusTraversalPolicyExt extends LayoutFocusTraversalPolicy{ } public Component getLastComponent(final Container focusCycleRoot) { - if (isNoDefaultComponent()) return null; - if (myOverridenDefaultComponent != null) { return myOverridenDefaultComponent; } @@ -128,8 +124,6 @@ public class LayoutFocusTraversalPolicyExt extends LayoutFocusTraversalPolicy{ } public Component getComponentAfter(final Container focusCycleRoot, final Component aComponent) { - if (isNoDefaultComponent()) return null; - if (myOverridenDefaultComponent != null) { return myOverridenDefaultComponent; } @@ -141,8 +135,6 @@ public class LayoutFocusTraversalPolicyExt extends LayoutFocusTraversalPolicy{ } public Component getComponentBefore(final Container focusCycleRoot, final Component aComponent) { - if (isNoDefaultComponent()) return null; - if (myOverridenDefaultComponent != null) { return myOverridenDefaultComponent; } From eb722d2df53451833515788d602b5b06b18bec58 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Thu, 20 Oct 2011 19:22:56 +0400 Subject: [PATCH 091/128] Revert "IDEA-75758 Tab focus change doesn't work on Mac Snow Leopard" This reverts commit f3f39913bcc336c7cbeb9d6ab64b2b42ebacfa7e. --- platform/platform-resources-en/src/misc/registry.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index fa8af6c7e041..95941a6aa42c 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -6,7 +6,7 @@ actionSystem.fixLostTyping=true actionSystem.fixLostTyping.description=Redispatch events, lost between actions and dialog show/close actionSystem.fixStickyFocusedWindows=true actionSystem.fixNullFocusedComponent=true -actionSystem.noDefaultComponent=false +actionSystem.noDefaultComponent=true actionSystem.commandProcessingTimeout=30000 actionSystem.commandProcessingTimeout.description=Timeout after which currently proccessed command is forcibly cancelled actionSystem.typeAheadTimeBeforeDialog=2000 From c08c00a43d2b41266008ba650dcfe0f8c0d09d97 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 20 Oct 2011 13:20:03 +0200 Subject: [PATCH 092/128] inplace introduce: reinit default type before show dialog on the second key stroke; correct undo chain --- .../IntroduceConstantHandler.java | 11 ++++++----- .../introduceField/IntroduceFieldHandler.java | 15 ++++++++------- .../AbstractJavaInplaceIntroducer.java | 2 +- .../IntroduceParameterHandler.java | 18 ++++++++++-------- .../inplace/AbstractInplaceIntroducer.java | 9 +++++++-- 5 files changed, 32 insertions(+), 23 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java index 242cf0c19f4e..78c73c0b537a 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java @@ -93,7 +93,7 @@ public class IntroduceConstantHandler extends BaseExpressionToFieldHandler { protected Settings showRefactoringDialog(Project project, - Editor editor, + final Editor editor, PsiClass parentClass, PsiExpression expr, PsiType type, @@ -150,31 +150,32 @@ public class IntroduceConstantHandler extends BaseExpressionToFieldHandler { String enteredName = null; boolean replaceAllOccurrences = true; - final TypeSelectorManagerImpl typeSelectorManager = new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurrences); if (editor != null && editor.getSettings().isVariableInplaceRenameEnabled() && (expr == null || expr.isPhysical())) { final AbstractInplaceIntroducer activeIntroducer = AbstractInplaceIntroducer.getActiveIntroducer(editor); if (activeIntroducer == null) { myInplaceIntroduceConstantPopup = - new InplaceIntroduceConstantPopup(project, editor, parentClass, expr, localVariable, occurrences, typeSelectorManager, + new InplaceIntroduceConstantPopup(project, editor, parentClass, expr, localVariable, occurrences, + new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurrences), anchorElement, anchorElementIfAll, expr != null ? createOccurrenceManager(expr, parentClass) : null); if (myInplaceIntroduceConstantPopup.startInplaceIntroduceTemplate() ){ return null; } } else { - AbstractInplaceIntroducer.stopIntroduce(editor); + activeIntroducer.stopIntroduce(editor); expr = (PsiExpression)activeIntroducer.getExpr(); localVariable = (PsiLocalVariable)activeIntroducer.getLocalVariable(); occurrences = (PsiExpression[])activeIntroducer.getOccurrences(); enteredName = activeIntroducer.getInputName(); replaceAllOccurrences = activeIntroducer.isReplaceAllOccurrences(); + type = ((InplaceIntroduceConstantPopup)activeIntroducer).getType(); } } final IntroduceConstantDialog dialog = new IntroduceConstantDialog(project, parentClass, expr, localVariable, localVariable != null, occurrences, getParentClass(), - typeSelectorManager, enteredName); + new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurrences), enteredName); dialog.setReplaceAllOccurrences(replaceAllOccurrences); dialog.show(); if (!dialog.isOK()) { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java index fa7fb3b81aa2..77284b936479 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java @@ -25,6 +25,7 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer; +import com.intellij.refactoring.introduceParameter.AbstractJavaInplaceIntroducer; import com.intellij.refactoring.ui.TypeSelectorManagerImpl; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.occurrences.*; @@ -102,7 +103,6 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler { final boolean currentMethodConstructor = containingMethod != null && containingMethod.isConstructor(); final boolean allowInitInMethod = (!currentMethodConstructor || !isInSuperOrThis) && (anchorElement instanceof PsiLocalVariable || anchorElement instanceof PsiStatement); final boolean allowInitInMethodIfAll = (!currentMethodConstructor || !isInSuperOrThis) && anchorElementIfAll instanceof PsiStatement; - final TypeSelectorManagerImpl typeSelectorManager = new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurrences); String enteredName = null; boolean replaceAll = false; @@ -110,20 +110,21 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler { final AbstractInplaceIntroducer activeIntroducer = AbstractInplaceIntroducer.getActiveIntroducer(editor); if (activeIntroducer == null) { myInplaceIntroduceFieldPopup = - new InplaceIntroduceFieldPopup(localVariable, parentClass, declareStatic, currentMethodConstructor, occurrences, expr, typeSelectorManager, editor, - allowInitInMethod, allowInitInMethodIfAll, anchorElement, anchorElementIfAll, expr != null ? createOccurrenceManager( - expr, parentClass) : null, - project); + new InplaceIntroduceFieldPopup(localVariable, parentClass, declareStatic, currentMethodConstructor, occurrences, expr, + new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurrences), editor, + allowInitInMethod, allowInitInMethodIfAll, anchorElement, anchorElementIfAll, + expr != null ? createOccurrenceManager(expr, parentClass) : null,project); if (myInplaceIntroduceFieldPopup.startInplaceIntroduceTemplate()) { return null; } } else { - AbstractInplaceIntroducer.stopIntroduce(editor); + activeIntroducer.stopIntroduce(editor); expr = (PsiExpression)activeIntroducer.getExpr(); localVariable = (PsiLocalVariable)activeIntroducer.getLocalVariable(); occurrences = (PsiExpression[])activeIntroducer.getOccurrences(); enteredName = activeIntroducer.getInputName(); replaceAll = activeIntroducer.isReplaceAllOccurrences(); + type = ((AbstractJavaInplaceIntroducer)activeIntroducer).getType(); IntroduceFieldDialog.ourLastInitializerPlace = ((InplaceIntroduceFieldPopup)activeIntroducer).getInitializerPlace(); } } @@ -133,7 +134,7 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler { currentMethodConstructor, localVariable != null, declareStatic, occurrences, allowInitInMethod, allowInitInMethodIfAll, - typeSelectorManager, + new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurrences), enteredName ); dialog.setReplaceAllOccurrences(replaceAll); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java index ec59f37cf5b4..6265d9309062 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java @@ -96,7 +96,7 @@ public abstract class AbstractJavaInplaceIntroducer extends AbstractInplaceIntro TypeSelectorManagerImpl.typeSelected(psiVariable.getType(), getType());//myDefaultType.getType()); } - protected PsiType getType() { + public PsiType getType() { return myTypeSelectorManager.getDefaultType(); } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java index 53d170a73c6f..a29f7d3eba25 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java @@ -400,11 +400,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R final String propName = myLocalVar != null ? JavaCodeStyleManager .getInstance(myProject).variableNameToPropertyName(myLocalVar.getName(), VariableKind.LOCAL_VARIABLE) : null; - final PsiType initializerType = IntroduceParameterProcessor.getInitializerType(null, myExpr, myLocalVar); - - TypeSelectorManagerImpl typeSelectorManager = myExpr != null - ? new TypeSelectorManagerImpl(myProject, initializerType, myExpr, occurences) - : new TypeSelectorManagerImpl(myProject, initializerType, occurences); + PsiType initializerType = IntroduceParameterProcessor.getInitializerType(null, myExpr, myLocalVar); boolean isInplaceAvailableOnDataContext = myEditor != null && myEditor.getSettings().isVariableInplaceRenameEnabled(); @@ -421,7 +417,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R myInplaceIntroduceParameterPopup = new InplaceIntroduceParameterPopup(myProject, myEditor, classMemberRefs, - typeSelectorManager, + createTypeSelectorManager(occurences, initializerType), myExpr, myLocalVar, method, methodToSearchFor, occurences, getParamsToRemove(method, occurences), mustBeFinal); @@ -430,13 +426,14 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R } } else { - AbstractInplaceIntroducer.stopIntroduce(myEditor); + activeIntroducer.stopIntroduce(myEditor); myExpr = (PsiExpression)activeIntroducer.getExpr(); myLocalVar = (PsiLocalVariable)activeIntroducer.getLocalVariable(); occurences = (PsiExpression[])activeIntroducer.getOccurrences(); enteredName = activeIntroducer.getInputName(); replaceAllOccurrences = activeIntroducer.isReplaceAllOccurrences(); delegate = ((InplaceIntroduceParameterPopup)activeIntroducer).isGenerateDelegate(); + initializerType = ((AbstractJavaInplaceIntroducer)activeIntroducer).getType(); } } if (ApplicationManager.getApplication().isUnitTestMode()) { @@ -455,7 +452,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R final IntroduceParameterDialog dialog = new IntroduceParameterDialog(myProject, classMemberRefs, occurences, myLocalVar, myExpr, createNameSuggestionGenerator(myExpr, propName, myProject, enteredName), - typeSelectorManager, methodToSearchFor, method, getParamsToRemove(method, occurences), mustBeFinal); + createTypeSelectorManager(occurences, initializerType), methodToSearchFor, method, getParamsToRemove(method, occurences), mustBeFinal); dialog.setReplaceAllOccurrences(replaceAllOccurrences); dialog.setGenerateDelegate(delegate); dialog.show(); @@ -465,6 +462,11 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R } } + private TypeSelectorManagerImpl createTypeSelectorManager(PsiExpression[] occurences, PsiType initializerType) { + return myExpr != null ? new TypeSelectorManagerImpl(myProject, initializerType, myExpr, occurences) + : new TypeSelectorManagerImpl(myProject, initializerType, occurences); + } + private TIntArrayList getParamsToRemove(PsiMethod method, PsiExpression[] occurences) { PsiExpression expressionToRemoveParamFrom = myExpr; if (myExpr == null) { diff --git a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java index 57b95e7cc434..b4dbff208521 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java @@ -531,10 +531,15 @@ public abstract class AbstractInplaceIntroducer Date: Thu, 20 Oct 2011 14:04:22 +0200 Subject: [PATCH 093/128] skip check for unused parameters for methods annotated with ... (IDEA-75640) --- .../deadCode/UnusedDeclarationInspection.java | 16 ++---------- .../ex/EntryPointsManagerImpl.java | 25 ++++++++++++++++++ .../UnusedParametersInspection.java | 16 ++++++++++++ .../unusedSymbol/OptionsPanel.form | 2 +- .../UnusedSymbolLocalInspection.java | 26 ++++++------------- 5 files changed, 52 insertions(+), 33 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java index e6f03d4b0136..5ff1af1018b8 100644 --- a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java @@ -38,9 +38,7 @@ import com.intellij.codeInspection.ui.EntryPointsNode; import com.intellij.codeInspection.ui.InspectionNode; import com.intellij.codeInspection.ui.InspectionTreeNode; import com.intellij.codeInspection.util.RefFilter; -import com.intellij.ide.DataManager; import com.intellij.lang.annotation.HighlightSeverity; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; @@ -49,7 +47,6 @@ import com.intellij.openapi.extensions.ExtensionPoint; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.util.*; import com.intellij.psi.*; import com.intellij.psi.impl.PsiClassImplUtil; @@ -203,15 +200,7 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool { gc.gridy++; add(myNonJavaCheckbox, gc); - final JButton configureAnnotations = new JButton("Configure annotations"); - configureAnnotations.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(OptionsPanel.this)); - if (project == null) project = ProjectManager.getInstance().getDefaultProject(); - EntryPointsManagerImpl.getInstance(project).configureAnnotations(); - } - }); + final JButton configureAnnotations = EntryPointsManagerImpl.createConfigureAnnotationsBtn(this); gc.fill = GridBagConstraints.NONE; gc.gridy++; @@ -446,8 +435,7 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool { if (RefUtil.isImplicitUsage(element)) return true; if (element instanceof PsiModifierListOwner) { final EntryPointsManagerImpl entryPointsManager = EntryPointsManagerImpl.getInstance(element.getProject()); - if (AnnotationUtil.isAnnotated((PsiModifierListOwner)element, entryPointsManager.ADDITIONAL_ANNOTATIONS) || - AnnotationUtil.isAnnotated((PsiModifierListOwner)element, entryPointsManager.getAdditionalAnnotations())) { + if (entryPointsManager.isEntryPoint((PsiModifierListOwner)element)) { return true; } } diff --git a/java/java-impl/src/com/intellij/codeInspection/ex/EntryPointsManagerImpl.java b/java/java-impl/src/com/intellij/codeInspection/ex/EntryPointsManagerImpl.java index d9ae487120db..c1d316ff0914 100644 --- a/java/java-impl/src/com/intellij/codeInspection/ex/EntryPointsManagerImpl.java +++ b/java/java-impl/src/com/intellij/codeInspection/ex/EntryPointsManagerImpl.java @@ -25,8 +25,11 @@ package com.intellij.codeInspection.ex; import com.intellij.ExtensionPoints; +import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInspection.reference.*; import com.intellij.codeInspection.util.SpecialAnnotationsUtil; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.ServiceManager; @@ -37,10 +40,12 @@ import com.intellij.openapi.extensions.ExtensionPointListener; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.extensions.PluginDescriptor; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.*; import com.intellij.profile.codeInspection.InspectionProfileManager; import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiModifierListOwner; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; import org.jdom.Element; @@ -49,6 +54,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.util.*; @State( @@ -360,6 +367,19 @@ public class EntryPointsManagerImpl implements PersistentStateComponent }.show(); } + public static JButton createConfigureAnnotationsBtn(final JComponent parent) { + final JButton configureAnnotations = new JButton("Configure annotations..."); + configureAnnotations.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(parent)); + if (project == null) project = ProjectManager.getInstance().getDefaultProject(); + EntryPointsManagerImpl.getInstance(project).configureAnnotations(); + } + }); + return configureAnnotations; + } + public void addAllPersistentEntries(EntryPointsManagerImpl manager) { myPersistentEntryPoints.putAll(manager.myPersistentEntryPoints); } @@ -411,4 +431,9 @@ public class EntryPointsManagerImpl implements PersistentStateComponent public void setAddNonJavaEntries(final boolean addNonJavaEntries) { myAddNonJavaEntries = addNonJavaEntries; } + + public boolean isEntryPoint(PsiModifierListOwner element) { + return AnnotationUtil.isAnnotated(element, ADDITIONAL_ANNOTATIONS) || + AnnotationUtil.isAnnotated(element, getAdditionalAnnotations()); + } } diff --git a/java/java-impl/src/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java b/java/java-impl/src/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java index ed608257a9fc..d61aa226a3f5 100644 --- a/java/java-impl/src/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java @@ -28,6 +28,7 @@ import com.intellij.analysis.AnalysisScope; import com.intellij.codeInsight.CodeInsightUtilBase; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.codeInspection.*; +import com.intellij.codeInspection.ex.EntryPointsManagerImpl; import com.intellij.codeInspection.reference.*; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; @@ -45,6 +46,8 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; +import java.awt.*; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -71,6 +74,7 @@ public class UnusedParametersInspection extends GlobalJavaInspectionTool { if ((refMethod.isAbstract() || refMethod.getOwnerClass().isInterface()) && refMethod.getDerivedMethods().isEmpty()) return null; if (RefUtil.isEntryPoint(refMethod)) return null; + if (EntryPointsManagerImpl.getInstance(manager.getProject()).isEntryPoint(refMethod.getElement())) return null; if (refMethod.isAppMain()) return null; @@ -215,6 +219,18 @@ public class UnusedParametersInspection extends GlobalJavaInspectionTool { return SHORT_NAME; } + @Override + public JComponent createOptionsPanel() { + final JPanel panel = new JPanel(new GridBagLayout()); + final GridBagConstraints gc = + new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, + new Insets(5, 0, 0, 0), 0, 0); + panel.add(EntryPointsManagerImpl.createConfigureAnnotationsBtn(panel), gc); + gc.weightx = 1; + gc.fill = GridBagConstraints.HORIZONTAL; + panel.add(Box.createHorizontalBox(), gc); + return panel; + } private static class AcceptSuggested implements LocalQuickFix { private final RefManager myManager; diff --git a/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/OptionsPanel.form b/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/OptionsPanel.form index 85ad51f4ba1c..5800c27a6bd2 100644 --- a/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/OptionsPanel.form +++ b/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/OptionsPanel.form @@ -46,7 +46,7 @@ - + diff --git a/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspection.java index 4ede61a08dbc..4db4e778770b 100644 --- a/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspection.java @@ -16,7 +16,6 @@ package com.intellij.codeInspection.unusedSymbol; -import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.codeInsight.daemon.QuickFixBundle; import com.intellij.codeInsight.daemon.impl.HighlightInfoType; @@ -25,10 +24,7 @@ import com.intellij.codeInspection.BaseJavaLocalInspectionTool; import com.intellij.codeInspection.ex.EntryPointsManagerImpl; import com.intellij.codeInspection.ex.UnfairLocalInspectionTool; import com.intellij.codeInspection.util.SpecialAnnotationsUtil; -import com.intellij.ide.DataManager; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; import com.intellij.psi.PsiModifierListOwner; import org.intellij.lang.annotations.Pattern; import org.jetbrains.annotations.NonNls; @@ -128,17 +124,13 @@ public class UnusedSymbolLocalInspection extends BaseJavaLocalInspectionTool imp myCheckClassesCheckBox.addActionListener(listener); myCheckParametersCheckBox.addActionListener(listener); myReportUnusedParametersInPublics.addActionListener(listener); - - final JButton configureAnnotations = new JButton("Configure annotations"); - configureAnnotations.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(myPanel)); - if (project == null) project = ProjectManager.getInstance().getDefaultProject(); - EntryPointsManagerImpl.getInstance(project).configureAnnotations(); - } - }); - myAnnos.add(configureAnnotations, BorderLayout.NORTH); + final GridBagConstraints gc = + new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, + new Insets(0, 0, 0, 0), 0, 0); + myAnnos.add(EntryPointsManagerImpl.createConfigureAnnotationsBtn(myPanel), gc); + gc.weightx = 1; + gc.fill = GridBagConstraints.HORIZONTAL; + myAnnos.add(Box.createHorizontalBox(), gc); } public JComponent getPanel() { @@ -160,8 +152,6 @@ public class UnusedSymbolLocalInspection extends BaseJavaLocalInspectionTool imp } public static boolean isInjected(final PsiModifierListOwner modifierListOwner) { - final EntryPointsManagerImpl entryPointsManager = EntryPointsManagerImpl.getInstance(modifierListOwner.getProject()); - return AnnotationUtil.isAnnotated(modifierListOwner, entryPointsManager.ADDITIONAL_ANNOTATIONS) || - AnnotationUtil.isAnnotated(modifierListOwner, entryPointsManager.getAdditionalAnnotations()); + return EntryPointsManagerImpl.getInstance(modifierListOwner.getProject()).isEntryPoint(modifierListOwner); } } From 4fbc686cb54b281b957fa47879364a47d572ed24 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 20 Oct 2011 16:04:40 +0200 Subject: [PATCH 094/128] do not change package when chooser was canceled --- .../ui/PackageNameReferenceEditorCombo.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/ui/PackageNameReferenceEditorCombo.java b/java/java-impl/src/com/intellij/refactoring/ui/PackageNameReferenceEditorCombo.java index 86864bf2dc47..a5e0591adb81 100644 --- a/java/java-impl/src/com/intellij/refactoring/ui/PackageNameReferenceEditorCombo.java +++ b/java/java-impl/src/com/intellij/refactoring/ui/PackageNameReferenceEditorCombo.java @@ -33,12 +33,14 @@ public class PackageNameReferenceEditorCombo extends ReferenceEditorComboWithBro super(null, text, project, false, recentsKey); addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - PackageChooserDialog chooser = new PackageChooserDialog(chooserTitle, project); + final PackageChooserDialog chooser = new PackageChooserDialog(chooserTitle, project); chooser.selectPackage(getText()); chooser.show(); - PsiPackage aPackage = chooser.getSelectedPackage(); - if (aPackage != null) { - setText(aPackage.getQualifiedName()); + if (chooser.isOK()) { + final PsiPackage aPackage = chooser.getSelectedPackage(); + if (aPackage != null) { + setText(aPackage.getQualifiedName()); + } } } }); From 49c599c36af1959e91c72abbcf69b939d32de51a Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 20 Oct 2011 16:24:34 +0200 Subject: [PATCH 095/128] test console: follow running tests, scroll to the beginning for the completed tests only (IDEA-75565) --- .../ui/TestsOutputConsolePrinter.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java index 78d9c99c84d0..0a105eb26f83 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java @@ -106,15 +106,14 @@ public class TestsOutputConsolePrinter implements Printer, Disposable { scrollToBeginning(); } }; - if (isRoot() && myUnboundOutputRoot != null) { - myUnboundOutputRoot.invokeInAlarm(clearRunnable); - myUnboundOutputRoot.printOn(this); - myUnboundOutputRoot.invokeInAlarm(scrollRunnable); - } else { - myCurrentTest.invokeInAlarm(clearRunnable); - myCurrentTest.printOn(this); - myCurrentTest.invokeInAlarm(scrollRunnable); - } + final AbstractTestProxy currentProxyOrRoot = getCurrentProxyOrRoot(); + currentProxyOrRoot.invokeInAlarm(clearRunnable); + currentProxyOrRoot.printOn(this); + currentProxyOrRoot.invokeInAlarm(scrollRunnable); + } + + private AbstractTestProxy getCurrentProxyOrRoot() { + return isRoot() && myUnboundOutputRoot != null ? myUnboundOutputRoot : myCurrentTest; } public boolean isCurrent(CompositePrintable printable) { @@ -145,7 +144,11 @@ public class TestsOutputConsolePrinter implements Printer, Disposable { protected void scrollToBeginning() { myConsole.performWhenNoDeferredOutput(new Runnable() { public void run() { - myConsole.scrollTo(myMarkOffset); + final AbstractTestProxy currentProxyOrRoot = getCurrentProxyOrRoot(); + if (!currentProxyOrRoot.isInProgress()) { + //do not scroll to any mark during run + myConsole.scrollTo(myMarkOffset); + } } }); } From 888ba9b3305a242db3ccc68b52b5cc532fcfa0d7 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 20 Oct 2011 19:26:38 +0400 Subject: [PATCH 096/128] IDEA-75441 Fix prompthooks.py to pass 3 args to readauthforuri if needed. --- plugins/hg4idea/resources/python/prompthooks.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/hg4idea/resources/python/prompthooks.py b/plugins/hg4idea/resources/python/prompthooks.py index 9bcaf0e84384..a8ac9d47bca5 100644 --- a/plugins/hg4idea/resources/python/prompthooks.py +++ b/plugins/hg4idea/resources/python/prompthooks.py @@ -177,12 +177,18 @@ def find_user_password(self, realm, authuri): else: def read_hgrc_authtoken(ui, authuri): try: - # hg 1.8 + # since hg 1.8 from mercurial.url import readauthforuri except ImportError: # hg 1.9: readauthforuri moved to httpconnection from mercurial.httpconnection import readauthforuri - res = readauthforuri(self.ui, authuri) + from inspect import getargspec + args, _, _, _ = getargspec(readauthforuri) + if len(args) == 2: + res = readauthforuri(self.ui, authuri) + else: + # since hg 1.9.2 readauthforuri accepts 3 required arguments instead of 2 + res = readauthforuri(self.ui, authuri, "") if res: group, auth = res return auth @@ -201,4 +207,4 @@ def find_user_password(self, realm, authuri): raise util.Abort(_('http authorization required')) user, passwd = retrievedPass self.add_password(realm, authuri, user, passwd) - return retrievedPass \ No newline at end of file + return retrievedPass \ No newline at end of file From c2b1b12520b60c9bb22e4b2c8cac84a86a0621f0 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 20 Oct 2011 16:50:29 +0200 Subject: [PATCH 097/128] IDEA-75632 Console folding: additional patterns --- resources/src/META-INF/IdeaPlugin.xml | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 75bf9fd2d388..6caec3b45cae 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -747,6 +747,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 94475556f16739a421e1b30f4a8d9db0a9946594 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 20 Oct 2011 16:58:22 +0200 Subject: [PATCH 098/128] plugin.xml: extension point usages should be searched in the whole project, not just dependencies --- plugins/devkit/resources/META-INF/plugin.xml | 1 + .../devkit/src/DevKitUseScopeEnlarger.java | 46 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 plugins/devkit/src/DevKitUseScopeEnlarger.java diff --git a/plugins/devkit/resources/META-INF/plugin.xml b/plugins/devkit/resources/META-INF/plugin.xml index 66cc3fa281b5..469d3ba08353 100644 --- a/plugins/devkit/resources/META-INF/plugin.xml +++ b/plugins/devkit/resources/META-INF/plugin.xml @@ -18,6 +18,7 @@ + diff --git a/plugins/devkit/src/DevKitUseScopeEnlarger.java b/plugins/devkit/src/DevKitUseScopeEnlarger.java new file mode 100644 index 000000000000..f34c40e57e89 --- /dev/null +++ b/plugins/devkit/src/DevKitUseScopeEnlarger.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2011 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.idea.devkit; + +import com.intellij.pom.PomTarget; +import com.intellij.pom.PomTargetPsiElement; +import com.intellij.psi.PsiElement; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.SearchScope; +import com.intellij.psi.search.UseScopeEnlarger; +import com.intellij.util.xml.DomElement; +import com.intellij.util.xml.DomTarget; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.devkit.dom.ExtensionPoint; + +/** + * @author peter + */ +public class DevKitUseScopeEnlarger extends UseScopeEnlarger { + @Override + public SearchScope getAdditionalUseScope(@NotNull PsiElement element) { + if (element instanceof PomTargetPsiElement) { + PomTarget target = ((PomTargetPsiElement)element).getTarget(); + if (target instanceof DomTarget) { + DomElement domElement = ((DomTarget)target).getDomElement(); + if (domElement instanceof ExtensionPoint) { + return GlobalSearchScope.allScope(element.getProject()); + } + } + } + return null; + } +} From 4e629e5b219eeab7d86aa5810be4d71ce2d7365b Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 20 Oct 2011 17:17:28 +0200 Subject: [PATCH 099/128] render method lookup elements with substituted types in groovy --- .../expressions/CompleteReferenceExpression.java | 6 +++--- .../groovy/completion/GroovyCompletionTest.groovy | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java index 2c5473fd4eb1..eaa4a9f17daa 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java @@ -32,7 +32,6 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyIcons; import org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionUtil; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; -import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; @@ -299,9 +298,10 @@ public class CompleteReferenceExpression { Project project) { final ResolveState state = ResolveState.initial(); if (qualifierType instanceof PsiClassType) { - PsiClass qualifierClass = ((PsiClassType)qualifierType).resolve(); + PsiClassType.ClassResolveResult result = ((PsiClassType)qualifierType).resolveGenerics(); + PsiClass qualifierClass = result.getElement(); if (qualifierClass != null) { - qualifierClass.processDeclarations(processor, state, null, refExpr); + qualifierClass.processDeclarations(processor, state.put(PsiSubstitutor.KEY, result.getSubstitutor()), null, refExpr); } } else if (qualifierType instanceof PsiArrayType) { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy index c0f6aafffcb7..e1fc1ad4fece 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy @@ -228,6 +228,15 @@ public class GroovyCompletionTest extends GroovyCompletionTestBase { assert presentation.typeText == 'String' } + public void testSubstitutedMethodType() throws Exception { + myFixture.configureByText "a.groovy", "new HashMap().putx" + def presentation = new LookupElementPresentation() + myFixture.completeBasic()[0].renderElement(presentation) + assert presentation.itemText == 'put' + assert presentation.tailText == '(String key, Integer value)' + assert presentation.typeText == 'Integer' + } + public void testIntCompletionInPlusMethod() {doBasicTest();} public void testIntCompletionInGenericParameter() {doBasicTest();} From 9443a55e67b464ae46924a7799364e44c033882e Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 20 Oct 2011 18:27:17 +0200 Subject: [PATCH 100/128] storage paths reworked --- .../intellij/compiler/JpsServerManager.java | 21 +++++++++-- .../jetbrains/jps/incremental/Builder.java | 2 + .../jps/incremental/CompileContext.java | 3 +- .../jps/incremental/IncProjectBuilder.java | 8 ++-- .../org/jetbrains/jps/incremental/Paths.java | 37 +++++++++++++++++++ .../jps/incremental/forms/FormsBuilder.java | 23 ------------ .../jps/incremental/java/JavaBuilder.java | 5 +++ .../resourses/ResourcesBuilder.java | 5 +++ .../incremental/storage/BuildDataManager.java | 31 ++++++---------- .../src/org/jetbrains/jps/server/Server.java | 11 ++++-- .../org/jetbrains/jps/server/ServerState.java | 1 - 11 files changed, 90 insertions(+), 57 deletions(-) create mode 100644 jps/jps-builders/src/org/jetbrains/jps/incremental/Paths.java delete mode 100644 jps/jps-builders/src/org/jetbrains/jps/incremental/forms/FormsBuilder.java diff --git a/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java b/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java index 030467761b44..98fcdb46b58a 100644 --- a/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java @@ -58,6 +58,7 @@ import org.jetbrains.jps.server.Server; import javax.tools.*; import java.io.File; +import java.io.IOException; import java.util.*; import java.util.concurrent.Future; import java.util.concurrent.RunnableFuture; @@ -71,7 +72,7 @@ public class JpsServerManager implements ApplicationComponent{ private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.JpsServerManager"); private static final String COMPILE_SERVER_SYSTEM_ROOT = "compile-server"; private volatile OSProcessHandler myProcessHandler; - + private final File mySystemDirectory; private volatile Client myClient = new Client(); private final SequentialTaskExecutor myTaskExecutor = new SequentialTaskExecutor(new SequentialTaskExecutor.AsyncTaskExecutor() { public void submit(Runnable runnable) { @@ -80,7 +81,18 @@ public class JpsServerManager implements ApplicationComponent{ }); public JpsServerManager(ProjectManager projectManager) { + final String systemPath = PathManager.getSystemPath(); + File system = new File(systemPath); + try { + system = system.getCanonicalFile(); + } + catch (IOException e) { + LOG.info(e); + } + mySystemDirectory = system; + projectManager.addProjectManagerListener(new ProjectWatcher()); + ShutDownTracker.getInstance().registerShutdownTask(new Runnable() { @Override public void run() { @@ -275,7 +287,7 @@ public class JpsServerManager implements ApplicationComponent{ return paths; } - private static Process launchServer(int port) throws ExecutionException { + private Process launchServer(int port) throws ExecutionException { final Sdk projectJdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk(); final GeneralCommandLine cmdLine = new GeneralCommandLine(); cmdLine.setExePath(((JavaSdkType)projectJdk.getSdkType()).getVMExecutablePath(projectJdk)); @@ -302,8 +314,11 @@ public class JpsServerManager implements ApplicationComponent{ cmdLine.addParameter(org.jetbrains.jps.server.Server.class.getName()); cmdLine.addParameter(Integer.toString(port)); - final File workDirectory = new File(PathManager.getSystemPath(), COMPILE_SERVER_SYSTEM_ROOT); + final File workDirectory = new File(mySystemDirectory, COMPILE_SERVER_SYSTEM_ROOT); workDirectory.mkdirs(); + + cmdLine.addParameter(FileUtil.toSystemIndependentName(workDirectory.getPath())); + cmdLine.setWorkDirectory(workDirectory); return cmdLine.createProcess(); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/Builder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/Builder.java index 60621f3b5b71..6a2682991730 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/Builder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/Builder.java @@ -20,6 +20,8 @@ public abstract class Builder { OK, ABORT, ADDITIONAL_PASS_REQUIRED } + public abstract String getName(); + public abstract ExitCode build(CompileContext context, ModuleChunk chunk) throws ProjectBuildException; public abstract String getDescription(); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java index 9aac9714ea7b..69cd7b0c905c 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java @@ -49,8 +49,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler myProductionChunks = productionChunks; myTestChunks = testChunks; myDelegateMessageHandler = delegateMessageHandler; - final File buildDataRoot = new File(System.getProperty("user.home"), ".jps" + File.separator + projectName + File.separator + "build_data"); - myDataManager = new BuildDataManager(buildDataRoot); + myDataManager = new BuildDataManager(projectName); myMappings = mappings; myProjectPaths = new ProjectPaths(scope.getProject()); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index 816d640d132f..3a0b9155a270 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -36,7 +36,9 @@ public class IncProjectBuilder { } public void build(CompileScope scope, final boolean isMake) { - final CompileContext context = new CompileContext(scope, myProjectName, isMake, myMappings, myProductionChunks, myTestChunks, new MessageHandler() { + final CompileContext context = new CompileContext( + scope, myProjectName, isMake, myMappings, myProductionChunks, myTestChunks, new MessageHandler() { + public void processMessage(BuildMessage msg) { for (MessageHandler h : myMessageHandlers) { h.processMessage(msg); @@ -163,10 +165,6 @@ public class IncProjectBuilder { do { nextPassRequired = false; for (Builder builder : builders) { - - //final String sourcesKind = context.isCompilingTests() ? "test" : "production"; - //context.processMessage(new ProgressMessage("Compiling " + chunk.getName() + "[" + sourcesKind+"]; Compiler: " + builder.getDescription())); - final Builder.ExitCode buildResult = builder.build(context, chunk); if (buildResult == Builder.ExitCode.ABORT) { throw new ProjectBuildException("Builder " + builder.getDescription() + " requested build stop"); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/Paths.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/Paths.java new file mode 100644 index 000000000000..46821654b38f --- /dev/null +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/Paths.java @@ -0,0 +1,37 @@ +package org.jetbrains.jps.incremental; + +import java.io.File; +import java.util.Locale; + +/** + * @author Eugene Zhuravlev + * Date: 10/20/11 + */ +public class Paths { + private static final Paths ourInstance = new Paths(); + private volatile File mySystemRoot = new File(System.getProperty("user.home", ".jps-server")); + + private Paths() { + } + + public static Paths getInstance() { + return ourInstance; + } + + public File getSystemRoot() { + return mySystemRoot; + } + + public void setSystemRoot(File systemRoot) { + mySystemRoot = systemRoot; + } + + public File getDataStorageRoot(String projectName) { + return new File(mySystemRoot, projectName.toLowerCase(Locale.US)); + } + + public File getBuilderDataRoot(final String projectName, String builderName) { + return new File(getDataStorageRoot(projectName), builderName.toLowerCase(Locale.US)); + } + +} diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/forms/FormsBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/forms/FormsBuilder.java deleted file mode 100644 index 96d05f05bdb7..000000000000 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/forms/FormsBuilder.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.jetbrains.jps.incremental.forms; - -import org.jetbrains.jps.ModuleChunk; -import org.jetbrains.jps.incremental.Builder; -import org.jetbrains.jps.incremental.CompileContext; -import org.jetbrains.jps.incremental.ProjectBuildException; - -/** - * @author Eugene Zhuravlev - * Date: 10/10/11 - */ -public class FormsBuilder extends Builder { - public static final String BUILDER_NAME = "forms"; - - public ExitCode build(CompileContext context, ModuleChunk chunk) throws ProjectBuildException { - - return null; - } - - public String getDescription() { - return "UI Designer Forms Builder"; - } -} diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index 7f095b567fe6..ca9283b2bf42 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -87,6 +87,11 @@ public class JavaBuilder extends Builder{ }); } + @Override + public String getName() { + return BUILDER_NAME; + } + public String getDescription() { return "Java Builder"; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/resourses/ResourcesBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/resourses/ResourcesBuilder.java index 947357b9f77b..028e6618f6c9 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/resourses/ResourcesBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/resourses/ResourcesBuilder.java @@ -23,6 +23,11 @@ public class ResourcesBuilder extends Builder{ public ResourcesBuilder() { } + @Override + public String getName() { + return BUILDER_NAME; + } + public ExitCode build(final CompileContext context, ModuleChunk chunk) throws ProjectBuildException { CompilerConfiguration config = null; for (Module module : chunk.getModules()) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java index cb4e5647a771..b36c3ce11024 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java @@ -2,6 +2,7 @@ package org.jetbrains.jps.incremental.storage; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.io.FileUtil; +import org.jetbrains.jps.incremental.Paths; import java.io.File; import java.io.IOException; @@ -14,22 +15,20 @@ import java.util.Map; */ public class BuildDataManager { private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.storage.BuildDataManager"); + private static final String TIMESTAMP_STORAGE = "stamps"; + private final String myProjectName; - public static final String TIMESTAMP_STORAGE = "timestamps"; - - private final File myDataRoot; private final Map myBuilderToStampStorageMap = new HashMap(); - //private final Map myBuilderToStorageMap = new HashMap(); - public BuildDataManager(File dataRoot) { - myDataRoot = dataRoot; + public BuildDataManager(String projectName) { + myProjectName = projectName; } public TimestampStorage getTimestampStorage(String builderName) throws IOException { synchronized (myBuilderToStampStorageMap) { TimestampStorage storage = myBuilderToStampStorageMap.get(builderName); if (storage == null) { - storage = new TimestampStorage(getStoreFile(builderName, TIMESTAMP_STORAGE)); + storage = new TimestampStorage(new File(getTimestampsStorageRoot(builderName), "data")); myBuilderToStampStorageMap.put(builderName, storage); } return storage; @@ -39,7 +38,7 @@ public class BuildDataManager { public void clean() { synchronized (myBuilderToStampStorageMap) { close(); - FileUtil.delete(myDataRoot); + FileUtil.delete(Paths.getInstance().getDataStorageRoot(myProjectName)); } } @@ -54,7 +53,7 @@ public class BuildDataManager { LOG.info(e); } } - FileUtil.delete(getDataRoot(builderName, TIMESTAMP_STORAGE)); + FileUtil.delete(Paths.getInstance().getBuilderDataRoot(myProjectName, builderName)); } } @@ -69,7 +68,7 @@ public class BuildDataManager { catch (IOException e) { LOG.error(e); final String builderName = entry.getKey(); - FileUtil.delete(getDataRoot(builderName, TIMESTAMP_STORAGE)); + FileUtil.delete(getTimestampsStorageRoot(builderName)); } } } @@ -79,15 +78,7 @@ public class BuildDataManager { } } - private File getStoreFile(String builderName, String storageName) { - return new File(getDataRoot(builderName, storageName), "data"); + public File getTimestampsStorageRoot(String builderName) { + return new File(Paths.getInstance().getBuilderDataRoot(myProjectName, builderName), TIMESTAMP_STORAGE); } - - private File getDataRoot(String builderName, String storageName) { - return new File(myDataRoot, builderName + File.separator + storageName); - } - - //public AbstractStateStorage getStorage(String builderName) { - // - //} } diff --git a/jps/jps-builders/src/org/jetbrains/jps/server/Server.java b/jps/jps-builders/src/org/jetbrains/jps/server/Server.java index 4ca62f502c53..5bc798764f8e 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/server/Server.java +++ b/jps/jps-builders/src/org/jetbrains/jps/server/Server.java @@ -11,7 +11,9 @@ import org.jboss.netty.handler.codec.protobuf.ProtobufEncoder; import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender; import org.jetbrains.jps.api.JpsRemoteProto; +import org.jetbrains.jps.incremental.Paths; +import java.io.File; import java.net.InetSocketAddress; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -31,7 +33,8 @@ public class Server { private final ChannelPipelineFactory myPipelineFactory; private final ExecutorService myBuildsExecutor; - public Server() { + public Server(File systemDir) { + Paths.getInstance().setSystemRoot(systemDir); final ExecutorService threadPool = Executors.newCachedThreadPool(); myBuildsExecutor = Executors.newFixedThreadPool(MAX_SIMULTANEOUS_BUILD_SESSIONS); myChannelFactory = new NioServerSocketChannelFactory(threadPool, threadPool, 1); @@ -74,7 +77,7 @@ public class Server { public static void main(String[] args) { try { int port = DEFAULT_SERVER_PORT; - + File systemDir = null; if (args.length > 0) { try { port = Integer.parseInt(args[0]); @@ -83,9 +86,11 @@ public class Server { System.err.println("Error parsing port: " + e.getMessage()); System.exit(-1); } + + systemDir = new File(args[1]); } - final Server server = new Server(); + final Server server = new Server(systemDir); server.start(port); Runtime.getRuntime().addShutdownHook(new Thread("Shutdown hook thread") { public void run() { diff --git a/jps/jps-builders/src/org/jetbrains/jps/server/ServerState.java b/jps/jps-builders/src/org/jetbrains/jps/server/ServerState.java index 4283ce0f65b4..02d35ed7403d 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/server/ServerState.java +++ b/jps/jps-builders/src/org/jetbrains/jps/server/ServerState.java @@ -53,7 +53,6 @@ class ServerState { public void startBuild(String projectPath, Set modules, final BuildParameters params, final MessageHandler msgHandler) throws Throwable{ Project project; Mappings mappings; - synchronized (myConfigurationLock) { project = myProjects.get(projectPath); if (project == null) { From 70ce15ac30c68d220f888e82b5e5a0cf7e8b7ec1 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 20 Oct 2011 20:27:50 +0200 Subject: [PATCH 101/128] optimizedFileManager.jar license fix --- build/scripts/libLicenses.gant | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant index 28f31f83e692..3000d7188d95 100644 --- a/build/scripts/libLicenses.gant +++ b/build/scripts/libLicenses.gant @@ -222,6 +222,6 @@ libraryLicense(name: "YourKit Java Profiler", libraryName: "yjp-controller-api-r libraryLicense(name: "protobuf", version: "2.3.0", license: "New BSD", url: "http://code.google.com/p/protobuf/", licenseUrl: "http://code.google.com/p/protobuf/source/browse/trunk/COPYING.txt?r=367") libraryLicense(name: "Netty", libraryName: "Netty", version: "3.2.5", license: "Apache 2.0", url: "http://www.jboss.org/netty", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0") jetbrainsLibrary("JPS") -jetbrainsLibrary("JPS-facade") jetbrainsLibrary("Maven Embedder") -jetbrainsLibrary("tcServiceMessages") \ No newline at end of file +jetbrainsLibrary("tcServiceMessages") +jetbrainsLibrary("optimizedFileManager.jar") \ No newline at end of file From c154559332e70d7d018e1ce0109b85a403dcacb5 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 20 Oct 2011 20:28:08 +0200 Subject: [PATCH 102/128] cosmetics --- .../jps/incremental/IncProjectBuilder.java | 21 +++++++++++++++++-- .../org/jetbrains/jps/incremental/Paths.java | 9 +++++--- .../incremental/storage/BuildDataManager.java | 6 +++--- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index 3a0b9155a270..95bff084b6ce 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -7,7 +7,10 @@ import org.jetbrains.jps.incremental.messages.BuildMessage; import org.jetbrains.jps.incremental.messages.CompilerMessage; import org.jetbrains.jps.incremental.messages.ProgressMessage; +import java.io.BufferedWriter; import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import java.util.*; /** @@ -16,6 +19,7 @@ import java.util.*; */ public class IncProjectBuilder { + public static final String JPS_SERVER_NAME = "JPS BUILD"; private final String myProjectName; private final BuilderRegistry myBuilderRegistry; private ProjectChunks myProductionChunks; @@ -63,10 +67,23 @@ public class IncProjectBuilder { } finally { context.getBuildDataManager().close(); + final File mappingsDataFile = Paths.getMappingsStorageFile(myProjectName); + try { + final BufferedWriter writer = new BufferedWriter(new FileWriter(mappingsDataFile)); + try { + context.getMappings().write(writer); + } + finally { + writer.close(); + } + } + catch (IOException e) { + context.processMessage(new CompilerMessage(JPS_SERVER_NAME, BuildMessage.Kind.WARNING, e.getMessage())); + } } } - private void cleanOutputRoots(CompileScope scope, CompileContext context) { + private static void cleanOutputRoots(CompileScope scope, CompileContext context) { final Collection allProjectModules = scope.getProject().getModules().values(); final Collection modulesToClean = new HashSet(); @@ -128,7 +145,7 @@ public class IncProjectBuilder { FileUtil.delete(outputRoot); } else { - context.processMessage(new CompilerMessage("JPS BUILD", BuildMessage.Kind.WARNING, "Output path " + outputRoot.getPath() + " intersects with a source root. The output cannot be cleaned.")); + context.processMessage(new CompilerMessage(JPS_SERVER_NAME, BuildMessage.Kind.WARNING, "Output path " + outputRoot.getPath() + " intersects with a source root. The output cannot be cleaned.")); } } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/Paths.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/Paths.java index 46821654b38f..441cd8610385 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/Paths.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/Paths.java @@ -26,12 +26,15 @@ public class Paths { mySystemRoot = systemRoot; } - public File getDataStorageRoot(String projectName) { - return new File(mySystemRoot, projectName.toLowerCase(Locale.US)); + public static File getDataStorageRoot(String projectName) { + return new File(getInstance().mySystemRoot, projectName.toLowerCase(Locale.US)); } - public File getBuilderDataRoot(final String projectName, String builderName) { + public static File getBuilderDataRoot(final String projectName, String builderName) { return new File(getDataStorageRoot(projectName), builderName.toLowerCase(Locale.US)); } + public static File getMappingsStorageFile(final String projectName) { + return new File(getDataStorageRoot(projectName), "mappings/data"); + } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java index b36c3ce11024..71340e08516f 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java @@ -38,7 +38,7 @@ public class BuildDataManager { public void clean() { synchronized (myBuilderToStampStorageMap) { close(); - FileUtil.delete(Paths.getInstance().getDataStorageRoot(myProjectName)); + FileUtil.delete(Paths.getDataStorageRoot(myProjectName)); } } @@ -53,7 +53,7 @@ public class BuildDataManager { LOG.info(e); } } - FileUtil.delete(Paths.getInstance().getBuilderDataRoot(myProjectName, builderName)); + FileUtil.delete(Paths.getBuilderDataRoot(myProjectName, builderName)); } } @@ -79,6 +79,6 @@ public class BuildDataManager { } public File getTimestampsStorageRoot(String builderName) { - return new File(Paths.getInstance().getBuilderDataRoot(myProjectName, builderName), TIMESTAMP_STORAGE); + return new File(Paths.getBuilderDataRoot(myProjectName, builderName), TIMESTAMP_STORAGE); } } From 6234180c76580eec57ce934fb317736274e4e4f6 Mon Sep 17 00:00:00 2001 From: Evgeny Zakrevsky Date: Thu, 20 Oct 2011 22:31:46 +0400 Subject: [PATCH 103/128] SOE during spotlighting --- .../com/intellij/openapi/options/newEditor/OptionsEditor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java index 7d8d2a6d7c54..af7ee5564440 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java @@ -1107,7 +1107,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat public boolean updateForCurrentConfigurable() { final Configurable current = getContext().getCurrentConfigurable(); - if (!isShowing(current)) return false; + if (current != null && !myConfigurable2Content.containsKey(current)) return false; String text = getFilterText(); From 29db6bb2bd29aa8b9d31a895e81ef7df0af4cdad Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 19 Oct 2011 16:39:56 +0200 Subject: [PATCH 104/128] @Nullable --- .../com/intellij/refactoring/BaseRefactoringProcessor.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java index b9dc74f9a0fa..9d46930643df 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java +++ b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2011 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. @@ -549,7 +549,7 @@ public abstract class BaseRefactoringProcessor { return showConflicts(conflicts, null); } - protected boolean showConflicts(final MultiMap conflicts, final UsageInfo[] usages) { + protected boolean showConflicts(final MultiMap conflicts, @Nullable final UsageInfo[] usages) { if (!conflicts.isEmpty() && ApplicationManager.getApplication().isUnitTestMode()) { throw new ConflictsInTestsException(conflicts.values()); } @@ -567,7 +567,7 @@ public abstract class BaseRefactoringProcessor { return true; } - protected ConflictsDialog prepareConflictsDialog(MultiMap conflicts, final UsageInfo[] usages) { + protected ConflictsDialog prepareConflictsDialog(MultiMap conflicts, @Nullable final UsageInfo[] usages) { final ConflictsDialog conflictsDialog = new ConflictsDialog(myProject, conflicts, usages == null ? null : new Runnable() { public void run() { execute(usages); From 43d1cdad50bfeaacdee8ddc986d2e9c15c90e6ac Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 19 Oct 2011 16:51:29 +0200 Subject: [PATCH 105/128] Accept UsageInfo subclasses for a conversion to an array --- .../src/com/intellij/usageView/UsageViewUtil.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/usageView/UsageViewUtil.java b/platform/lang-impl/src/com/intellij/usageView/UsageViewUtil.java index d1956b928f34..23cdb902ef73 100644 --- a/platform/lang-impl/src/com/intellij/usageView/UsageViewUtil.java +++ b/platform/lang-impl/src/com/intellij/usageView/UsageViewUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 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. @@ -76,7 +76,8 @@ public class UsageViewUtil { } final Language lang = psiElement.getLanguage(); - FindUsagesProvider provider = LanguageFindUsages.INSTANCE.forLanguage(lang); + final FindUsagesProvider provider = LanguageFindUsages.INSTANCE.forLanguage(lang); + assert provider != null : lang; return provider.getDescriptiveName(psiElement); } @@ -144,7 +145,7 @@ public class UsageViewUtil { } @NotNull - public static UsageInfo[] toUsageInfoArray(@NotNull final Collection collection) { + public static UsageInfo[] toUsageInfoArray(@NotNull final Collection collection) { final int size = collection.size(); return size == 0 ? UsageInfo.EMPTY_ARRAY : collection.toArray(new UsageInfo[size]); } From 707705121afa28edd1e7abe93841da62c2a5b871 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 19 Oct 2011 17:59:11 +0200 Subject: [PATCH 106/128] Cleanup --- .../refactoring/BaseRefactoringProcessor.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java index 9d46930643df..23119e6956be 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java +++ b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java @@ -40,11 +40,12 @@ import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.util.Factory; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.WindowManager; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.util.PsiUtilBase; +import com.intellij.psi.util.PsiUtilCore; import com.intellij.refactoring.listeners.RefactoringListenerManager; import com.intellij.refactoring.listeners.impl.RefactoringListenerManagerImpl; import com.intellij.refactoring.listeners.impl.RefactoringTransaction; @@ -76,7 +77,6 @@ public abstract class BaseRefactoringProcessor { private boolean myIsPreviewUsages; protected Runnable myPrepareSuccessfulSwingThreadCallback = EmptyRunnable.INSTANCE; - protected BaseRefactoringProcessor(Project project) { this(project, null); } @@ -168,7 +168,8 @@ public abstract class BaseRefactoringProcessor { } }; - if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(findUsagesRunnable, RefactoringBundle.message("progress.text"), true, myProject)) { + if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(findUsagesRunnable, RefactoringBundle.message("progress.text"), + true, myProject)) { return; } @@ -195,7 +196,7 @@ public abstract class BaseRefactoringProcessor { if (!isPreview) { isPreview = !ensureElementsWritable(usages, descriptor) || UsageViewUtil.hasReadOnlyUsages(usages); if (isPreview) { - WindowManager.getInstance().getStatusBar(myProject).setInfo(RefactoringBundle.message("readonly.occurences.found")); + setStatusBarInfo(RefactoringBundle.message("readonly.occurences.found")); } } if (isPreview) { @@ -206,6 +207,13 @@ public abstract class BaseRefactoringProcessor { } } + private void setStatusBarInfo(final String message) { + final StatusBar statusBar = WindowManager.getInstance().getStatusBar(myProject); + if (statusBar != null) { + statusBar.setInfo(message); + } + } + protected void previewRefactoring(final UsageInfo[] usages) { final UsageViewDescriptor viewDescriptor = createUsageViewDescriptor(usages); final PsiElement[] elements = viewDescriptor.getElements(); @@ -258,7 +266,7 @@ public abstract class BaseRefactoringProcessor { } private static boolean ensureFilesWritable(final Project project, Collection elements) { - PsiElement[] psiElements = PsiUtilBase.toPsiElementArray(elements); + PsiElement[] psiElements = PsiUtilCore.toPsiElementArray(elements); return CommonRefactoringUtil.checkReadOnlyStatus(project, psiElements); } @@ -276,6 +284,7 @@ public abstract class BaseRefactoringProcessor { return PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext()) == null; } + @SuppressWarnings("MethodMayBeStatic") protected UndoConfirmationPolicy getUndoConfirmationPolicy() { return UndoConfirmationPolicy.DEFAULT; } @@ -357,7 +366,8 @@ public abstract class BaseRefactoringProcessor { String canNotMakeString = RefactoringBundle.message("usageView.need.reRun"); - usageView.addPerformOperationAction(refactoringRunnable, getCommandName(), canNotMakeString, RefactoringBundle.message("usageView.doAction")); + usageView.addPerformOperationAction(refactoringRunnable, getCommandName(), canNotMakeString, + RefactoringBundle.message("usageView.doAction")); } private static Set getUsageInfosToRefactor(final UsageView usageView) { @@ -424,11 +434,11 @@ public abstract class BaseRefactoringProcessor { int count = writableUsageInfos.length; if (count > 0) { - WindowManager.getInstance().getStatusBar(myProject).setInfo(RefactoringBundle.message("statusBar.refactoring.result", count)); + setStatusBarInfo(RefactoringBundle.message("statusBar.refactoring.result", count)); } else { if (!isPreviewUsages(writableUsageInfos)) { - WindowManager.getInstance().getStatusBar(myProject).setInfo(RefactoringBundle.message("statusBar.noUsages")); + setStatusBarInfo(RefactoringBundle.message("statusBar.noUsages")); } } } @@ -440,7 +450,6 @@ public abstract class BaseRefactoringProcessor { * {@link #performRefactoring(UsageInfo[])}. */ protected void performPsiSpoilingRefactoring() { - } protected void prepareSuccessful() { @@ -462,7 +471,6 @@ public abstract class BaseRefactoringProcessor { * Override in subclasses */ protected void prepareTestRun() { - } public final void run() { From c5ba09329714541011c23aca01f206291abf4f4a Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 20 Oct 2011 14:18:57 +0200 Subject: [PATCH 107/128] MultiMap: factory methods, cleanup --- .../com/intellij/util/containers/HashMap.java | 9 +++-- .../intellij/util/containers/MultiMap.java | 33 ++++++++++++++----- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/platform/util/src/com/intellij/util/containers/HashMap.java b/platform/util/src/com/intellij/util/containers/HashMap.java index a1610befa42d..b5ef3b8beb62 100644 --- a/platform/util/src/com/intellij/util/containers/HashMap.java +++ b/platform/util/src/com/intellij/util/containers/HashMap.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 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. @@ -15,7 +15,10 @@ */ package com.intellij.util.containers; -public class HashMap extends java.util.HashMap { +import java.util.Map; + +@SuppressWarnings("ClassNameSameAsAncestorName") +public class HashMap extends java.util.HashMap { public HashMap(int i, float v) { super(i, v); } @@ -26,7 +29,7 @@ public class HashMap extends java.util.HashMap { public HashMap() { } - public HashMap(java.util.Map map) { + public HashMap(Map map) { super(map); } diff --git a/platform/util/src/com/intellij/util/containers/MultiMap.java b/platform/util/src/com/intellij/util/containers/MultiMap.java index bb11f8a5e840..3b8da1cae0b5 100644 --- a/platform/util/src/com/intellij/util/containers/MultiMap.java +++ b/platform/util/src/com/intellij/util/containers/MultiMap.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 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. @@ -24,7 +24,6 @@ import java.util.*; * @author Dmitry Avdeev */ public class MultiMap { - public static final MultiMap EMPTY = new MultiMap() { @Override protected Map createMap() { @@ -33,17 +32,24 @@ public class MultiMap { }; private final Map> myMap; - private Collection values; public MultiMap() { myMap = createMap(); } + public MultiMap(int i, float v) { + myMap = createMap(i, v); + } + protected Map> createMap() { return new HashMap>(); } + protected Map> createMap(int i, float v) { + return new HashMap>(i, v); + } + protected Collection createCollection() { return new ArrayList(); } @@ -52,10 +58,9 @@ public class MultiMap { return Collections.emptyList(); } - public void putAllValues(MultiMap from) { - for (K k : from.keySet()) { - //noinspection unchecked - putValues(k, ((MultiMap)from).get(k)); + public void putAllValues(MultiMap from) { + for (Map.Entry> entry : from.entrySet()) { + putValues(entry.getKey(), entry.getValue()); } } @@ -211,8 +216,20 @@ public class MultiMap { return myMap.remove(key); } + @NotNull public static MultiMap emptyInstance() { - return EMPTY; + @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) final MultiMap empty = EMPTY; + return empty; + } + + @NotNull + public static MultiMap create() { + return new MultiMap(); + } + + @NotNull + public static MultiMap create(int i, float v) { + return new MultiMap(i, v); } @Override From c99b6c11231958a4ce4549aa6da085588ec5b02a Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 20 Oct 2011 21:57:13 +0200 Subject: [PATCH 108/128] persistence for mappings --- .../jps/incremental/IncProjectBuilder.java | 16 +++++---- .../org/jetbrains/jps/server/ServerState.java | 34 +++++++++++++++---- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index 95bff084b6ce..bf39ecd3c60e 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -7,19 +7,17 @@ import org.jetbrains.jps.incremental.messages.BuildMessage; import org.jetbrains.jps.incremental.messages.CompilerMessage; import org.jetbrains.jps.incremental.messages.ProgressMessage; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; import java.util.*; +import java.util.zip.DeflaterOutputStream; /** * @author Eugene Zhuravlev * Date: 9/17/11 */ public class IncProjectBuilder { - public static final String JPS_SERVER_NAME = "JPS BUILD"; + private final String myProjectName; private final BuilderRegistry myBuilderRegistry; private ProjectChunks myProductionChunks; @@ -27,7 +25,10 @@ public class IncProjectBuilder { private final List myMessageHandlers = new ArrayList(); private final Mappings myMappings; - public IncProjectBuilder(Project project, String projectName, final Mappings mappings, BuilderRegistry builderRegistry) { + public IncProjectBuilder(String projectName, + Project project, + final Mappings mappings, + BuilderRegistry builderRegistry) { myProjectName = projectName; myBuilderRegistry = builderRegistry; myProductionChunks = new ProjectChunks(project, ClasspathKind.PRODUCTION_COMPILE); @@ -69,7 +70,8 @@ public class IncProjectBuilder { context.getBuildDataManager().close(); final File mappingsDataFile = Paths.getMappingsStorageFile(myProjectName); try { - final BufferedWriter writer = new BufferedWriter(new FileWriter(mappingsDataFile)); + FileUtil.createIfDoesntExist(mappingsDataFile); + final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new DeflaterOutputStream(new FileOutputStream(mappingsDataFile)))); try { context.getMappings().write(writer); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/server/ServerState.java b/jps/jps-builders/src/org/jetbrains/jps/server/ServerState.java index 02d35ed7403d..44fd6a07be0b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/server/ServerState.java +++ b/jps/jps-builders/src/org/jetbrains/jps/server/ServerState.java @@ -10,13 +10,13 @@ import org.jetbrains.jps.api.BuildParameters; import org.jetbrains.jps.api.GlobalLibrary; import org.jetbrains.jps.api.SdkLibrary; import org.jetbrains.jps.idea.IdeaProjectLoader; -import org.jetbrains.jps.incremental.BuilderRegistry; -import org.jetbrains.jps.incremental.CompileScope; -import org.jetbrains.jps.incremental.IncProjectBuilder; -import org.jetbrains.jps.incremental.MessageHandler; +import org.jetbrains.jps.incremental.*; +import org.jetbrains.jps.incremental.messages.BuildMessage; +import org.jetbrains.jps.incremental.messages.CompilerMessage; -import java.io.File; +import java.io.*; import java.util.*; +import java.util.zip.DeflaterInputStream; /** * @author Eugene Zhuravlev @@ -51,6 +51,8 @@ class ServerState { } public void startBuild(String projectPath, Set modules, final BuildParameters params, final MessageHandler msgHandler) throws Throwable{ + final String projectName = getProjectName(projectPath); + Project project; Mappings mappings; synchronized (myConfigurationLock) { @@ -59,9 +61,27 @@ class ServerState { project = loadProject(projectPath, params); myProjects.put(projectPath, project); } + mappings = myProjectMappings.get(projectPath); if (mappings == null) { - mappings = new Mappings(); + final File mappingsStorageFile = Paths.getMappingsStorageFile(projectName); + try { + final BufferedReader reader = new BufferedReader(new InputStreamReader(new DeflaterInputStream(new FileInputStream(mappingsStorageFile)))); + try { + mappings = new Mappings(reader); + } + finally { + reader.close(); + } + } + catch (FileNotFoundException e) { + mappings = new Mappings(); + } + catch (IOException e) { + msgHandler.processMessage(new CompilerMessage(IncProjectBuilder.JPS_SERVER_NAME, BuildMessage.Kind.WARNING, e.getMessage())); + mappings = new Mappings(); + } + myProjectMappings.put(projectPath, mappings); } } @@ -84,7 +104,7 @@ class ServerState { } }; - final IncProjectBuilder builder = new IncProjectBuilder(project, getProjectName(projectPath), mappings, BuilderRegistry.getInstance()); + final IncProjectBuilder builder = new IncProjectBuilder(projectName, project, mappings, BuilderRegistry.getInstance()); if (msgHandler != null) { builder.addMessageHandler(msgHandler); } From e9896186abe4934b57596823644be7f6ae0fefa4 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 20 Oct 2011 23:05:05 +0200 Subject: [PATCH 109/128] assertions and progress --- .../intellij/compiler/JpsServerManager.java | 3 ++- .../jps/incremental/IncProjectBuilder.java | 6 +++++ .../ether/dependencyView/Mappings.java | 26 ++++++++++++++++--- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java b/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java index 98fcdb46b58a..9aedd7d49230 100644 --- a/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java @@ -292,8 +292,9 @@ public class JpsServerManager implements ApplicationComponent{ final GeneralCommandLine cmdLine = new GeneralCommandLine(); cmdLine.setExePath(((JavaSdkType)projectJdk.getSdkType()).getVMExecutablePath(projectJdk)); cmdLine.addParameter("-ea"); + cmdLine.addParameter("-XX:+HeapDumpOnOutOfMemoryError"); cmdLine.addParameter("-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5008"); - cmdLine.addParameter("-Xmx256m"); // todo: get this value from settings + cmdLine.addParameter("-Xmx512m"); // todo: get this value from settings cmdLine.addParameter("-classpath"); final List cp = ClasspathBootstrap.getApplicationClasspath(); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index bf39ecd3c60e..6602e3455c45 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -53,20 +53,25 @@ public class IncProjectBuilder { try { cleanOutputRoots(scope, context); + context.processMessage(new ProgressMessage("Running 'before' tasks")); runTasks(context, myBuilderRegistry.getBeforeTasks()); context.setCompilingTests(false); + context.processMessage(new ProgressMessage("Building production sources")); buildChunks(context, myProductionChunks); context.setCompilingTests(true); + context.processMessage(new ProgressMessage("Building test sources")); buildChunks(context, myTestChunks); + context.processMessage(new ProgressMessage("Running 'after' tasks")); runTasks(context, myBuilderRegistry.getAfterTasks()); } catch (ProjectBuildException e) { context.processMessage(new ProgressMessage(e.getMessage())); } finally { + context.processMessage(new ProgressMessage("Build complete")); context.getBuildDataManager().close(); final File mappingsDataFile = Paths.getMappingsStorageFile(myProjectName); try { @@ -144,6 +149,7 @@ public class IncProjectBuilder { } } if (okToDelete) { + context.processMessage(new ProgressMessage("Cleaning " + outputRoot.getPath())); FileUtil.delete(outputRoot); } else { diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java index a5e43b9099e3..5bcd6133e9b6 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -3,6 +3,7 @@ package org.jetbrains.ether.dependencyView; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.ether.RW; import org.objectweb.asm.ClassReader; import org.objectweb.asm.Opcodes; @@ -93,8 +94,13 @@ public class Mappings implements RW.Writable { } } + @Nullable private ClassRepr getReprByName(final StringCache.S name) { - final Collection reprs = sourceFileToClasses.foxyGet(classToSourceFile.get(name)); + final StringCache.S source = classToSourceFile.get(name); + + assert source != null; + + final Collection reprs = sourceFileToClasses.foxyGet(source); if (reprs != null) { for (ClassRepr repr : reprs) { @@ -318,7 +324,11 @@ public class Mappings implements RW.Writable { affectedUsages.add(rootUsage); for (StringCache.S p : subclasses) { - final Collection deps = fileToFileDependency.foxyGet(classToSourceFile.get(p)); + final StringCache.S source = classToSourceFile.get(p); + + assert source != null; + + final Collection deps = fileToFileDependency.foxyGet(source); if (deps != null) { dependents.addAll(deps); @@ -336,7 +346,11 @@ public class Mappings implements RW.Writable { affectedUsages.add(rootUsage); for (StringCache.S p : subclasses) { - final Collection deps = fileToFileDependency.foxyGet(classToSourceFile.get(p)); + final StringCache.S source = classToSourceFile.get(p); + + assert source != null; + + final Collection deps = fileToFileDependency.foxyGet(source); if (deps != null) { dependents.addAll(deps); @@ -601,7 +615,11 @@ public class Mappings implements RW.Writable { } if (allAbstract && visited) { - affectedFiles.add(classToSourceFile.get(p)); + final StringCache.S source = classToSourceFile.get(p); + + assert source != null; + + affectedFiles.add(source); } } } From 36aa1526ad66164d075635153c5e1583d7f2d83b Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 21 Oct 2011 01:02:05 +0200 Subject: [PATCH 110/128] transparent bg --- .../com/intellij/ide/navigationToolbar/NavBarItem.java | 4 ++-- .../com/intellij/ide/navigationToolbar/NavBarPanel.java | 3 ++- .../ide/navigationToolbar/NavBarRootPaneExtension.java | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarItem.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarItem.java index 609672d557af..beafda7c50b6 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarItem.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarItem.java @@ -153,7 +153,7 @@ class NavBarItem extends SimpleColoredComponent implements Disposable { final Color selBg = new Color(c.getRed(), c.getGreen(), c.getBlue(), getAlpha()); int w = getWidth(); int h = getHeight(); - if (!UIUtil.isUnderAquaLookAndFeel() || myPanel.isInFloatingMode() || (isSelected() && myPanel.hasFocus())) { + if (/*!UIUtil.isUnderAquaLookAndFeel() ||*/ myPanel.isInFloatingMode() || (isSelected() && myPanel.hasFocus())) { g.setPaint(isSelected() && isFocused() ? selBg : bg); g.fillRect(0, 0, w - (isLastElement() /*|| !UIUtil.isUnderAquaLookAndFeel()*/ ? 0 : getDecorationOffset()), h); } @@ -180,7 +180,7 @@ class NavBarItem extends SimpleColoredComponent implements Disposable { g.translate(-2, 0); } - if (!UIUtil.isUnderAquaLookAndFeel() || myPanel.isInFloatingMode() || isNextSelected()) { + if (/*!UIUtil.isUnderAquaLookAndFeel() || */myPanel.isInFloatingMode() || isNextSelected()) { if (! isLastElement()) { path = new Path2D.Double(); path.moveTo(0, 0); diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java index 38d6ec12cf89..249a3b198a74 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java @@ -65,6 +65,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.border.EmptyBorder; import javax.swing.tree.TreeNode; import java.awt.*; import java.awt.event.MouseAdapter; @@ -111,7 +112,7 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis PopupHandler.installPopupHandler(this, IdeActions.GROUP_NAVBAR_POPUP, ActionPlaces.NAVIGATION_BAR); if (!isDecorated()) { - setBorder(new NavBarBorder(false, -1)); + setBorder(/*new NavBarBorder(false, -1)*/ new EmptyBorder(1,0,1,4)); } setOpaque(false); diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java index 7783f58edbe0..7240c7efc39c 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java @@ -242,7 +242,7 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension { @Override protected void paintComponent(Graphics g) { - if (UIUtil.isUnderAquaLookAndFeel()) { + //if (UIUtil.isUnderAquaLookAndFeel()) { final Rectangle r = getBounds(); final Graphics2D g2d = (Graphics2D)g; if (!isMainToolbarVisible()) { @@ -275,9 +275,9 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension { if (!undocked) g.drawLine(0, 0, r.width, 0); g.drawLine(0, r.height - 1, r.width - 1, r.height - 1); } - } else { - super.paintComponent(g); - } + //} else { + // super.paintComponent(g); + //} } @Override From f184dc8c69a2a1d664013c139071802ef4fc0196 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 21 Oct 2011 09:39:35 +0400 Subject: [PATCH 111/128] tests fixed by sorting breakpoints --- .../com/intellij/xdebugger/XBreakpointManagerTest.java | 8 ++++---- .../com/intellij/xdebugger/XBreakpointsTestCase.java | 10 ++++++++++ .../intellij/xdebugger/XDependentBreakpointsTest.java | 5 +++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointManagerTest.java b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointManagerTest.java index eb08e6782e5c..38e9154d936e 100644 --- a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointManagerTest.java +++ b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointManagerTest.java @@ -53,12 +53,12 @@ public class XBreakpointManagerTest extends XBreakpointsTestCase { public void testSerialize() { XLineBreakpoint breakpoint = - myBreakpointManager.addLineBreakpoint(MY_LINE_BREAKPOINT_TYPE, "myurl", 239, new MyBreakpointProperties("abc")); + myBreakpointManager.addLineBreakpoint(MY_LINE_BREAKPOINT_TYPE, "myurl", 239, new MyBreakpointProperties("z1")); breakpoint.setCondition("cond"); breakpoint.setLogExpression("log"); breakpoint.setSuspendPolicy(SuspendPolicy.NONE); breakpoint.setLogMessage(true); - myBreakpointManager.addBreakpoint(MY_SIMPLE_BREAKPOINT_TYPE, new MyBreakpointProperties("123")); + myBreakpointManager.addBreakpoint(MY_SIMPLE_BREAKPOINT_TYPE, new MyBreakpointProperties("z2")); reload(); List> breakpoints = getAllBreakpoints(); @@ -71,13 +71,13 @@ public class XBreakpointManagerTest extends XBreakpointsTestCase { XLineBreakpoint lineBreakpoint = assertInstanceOf(breakpoints.get(1), XLineBreakpoint.class); assertEquals(239, lineBreakpoint.getLine()); assertEquals("myurl", lineBreakpoint.getFileUrl()); - assertEquals("abc", assertInstanceOf(lineBreakpoint.getProperties(), MyBreakpointProperties.class).myOption); + assertEquals("z1", assertInstanceOf(lineBreakpoint.getProperties(), MyBreakpointProperties.class).myOption); assertEquals("cond", lineBreakpoint.getCondition()); assertEquals("log", lineBreakpoint.getLogExpression()); assertTrue(lineBreakpoint.isLogMessage()); assertEquals(SuspendPolicy.NONE, lineBreakpoint.getSuspendPolicy()); - assertEquals("123", assertInstanceOf(breakpoints.get(2).getProperties(), MyBreakpointProperties.class).myOption); + assertEquals("z2", assertInstanceOf(breakpoints.get(2).getProperties(), MyBreakpointProperties.class).myOption); assertEquals(SuspendPolicy.ALL, breakpoints.get(2).getSuspendPolicy()); assertFalse(breakpoints.get(2).isLogMessage()); } diff --git a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointsTestCase.java b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointsTestCase.java index d1cef1f5f6c7..7220922e7f75 100644 --- a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointsTestCase.java +++ b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointsTestCase.java @@ -15,6 +15,7 @@ */ package com.intellij.xdebugger; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.testFramework.TempFiles; import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; import com.intellij.util.xmlb.XmlSerializer; @@ -25,6 +26,8 @@ import com.intellij.xdebugger.impl.breakpoints.XBreakpointManagerImpl; import org.jdom.Element; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; /** @@ -59,6 +62,13 @@ public abstract class XBreakpointsTestCase extends XDebuggerTestCase { result.add(breakpoint); } } + Collections.sort(result, new Comparator>() { + @Override + public int compare(XBreakpoint o1, XBreakpoint o2) { + return StringUtil.compare(((MyBreakpointProperties)o1.getProperties()).myOption, + ((MyBreakpointProperties)o2.getProperties()).myOption, true); + } + }); return result; } } diff --git a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDependentBreakpointsTest.java b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDependentBreakpointsTest.java index b05fc2457cc4..b24cbca61c97 100644 --- a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDependentBreakpointsTest.java +++ b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDependentBreakpointsTest.java @@ -61,6 +61,7 @@ public class XDependentBreakpointsTest extends XBreakpointsTestCase { List> breakpoints = getAllBreakpoints(); assertEquals(3, breakpoints.size()); + assertEquals("default", ((MyBreakpointProperties)breakpoints.get(0).getProperties()).myOption); XLineBreakpoint newMaster = (XLineBreakpoint)breakpoints.get(1); XLineBreakpoint newSlave = (XLineBreakpoint)breakpoints.get(2); assertEquals("file://master", newMaster.getFileUrl()); @@ -70,10 +71,10 @@ public class XDependentBreakpointsTest extends XBreakpointsTestCase { } private XLineBreakpoint createSlave() { - return myBreakpointManager.addLineBreakpoint(MY_LINE_BREAKPOINT_TYPE, "file://slave", 2, new MyBreakpointProperties()); + return myBreakpointManager.addLineBreakpoint(MY_LINE_BREAKPOINT_TYPE, "file://slave", 2, new MyBreakpointProperties("z-slave")); } private XLineBreakpoint createMaster() { - return myBreakpointManager.addLineBreakpoint(MY_LINE_BREAKPOINT_TYPE, "file://master", 1, new MyBreakpointProperties()); + return myBreakpointManager.addLineBreakpoint(MY_LINE_BREAKPOINT_TYPE, "file://master", 1, new MyBreakpointProperties("z-master")); } } From 14af547a83c310843d4031fc3cc03ce429304bb0 Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Wed, 19 Oct 2011 13:37:50 +0400 Subject: [PATCH 112/128] IDEA-75549 An inspection to detect incompatible types using 'in' --- .../GroovyInArgumentCheck.html | 7 ++ plugins/groovy/src/META-INF/plugin.xml | 3 + .../GroovyInspectionBundle.properties | 3 +- .../bugs/GroovyInArgumentCheckInspection.java | 117 ++++++++++++++++++ .../groovy/lang/GroovyHighlightingTest.groovy | 4 + .../MemberShipOperatorCheck.groovy | 29 +++++ 6 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 plugins/groovy/resources/inspectionDescriptions/GroovyInArgumentCheck.html create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyInArgumentCheckInspection.java create mode 100644 plugins/groovy/testdata/highlighting/MemberShipOperatorCheck.groovy diff --git a/plugins/groovy/resources/inspectionDescriptions/GroovyInArgumentCheck.html b/plugins/groovy/resources/inspectionDescriptions/GroovyInArgumentCheck.html new file mode 100644 index 000000000000..5073b5f83d84 --- /dev/null +++ b/plugins/groovy/resources/inspectionDescriptions/GroovyInArgumentCheck.html @@ -0,0 +1,7 @@ + + + + This inspection reports usages of membership operator which check items and containers of incompatible types. + + + diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 77dfb76758a9..3020361877f5 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -566,6 +566,9 @@ + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionBundle.properties index 457002f13b2e..cc1890234c9f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionBundle.properties @@ -71,4 +71,5 @@ add.method=Add method ''{0}()'' to class ''{1}'' implement.class=Implement {0} fix.class=Fix class {0} check.labeled.statement=Labeled statement inspection -unnecessary.qualified.reference=Unnecessary qualified reference \ No newline at end of file +unnecessary.qualified.reference=Unnecessary qualified reference +rtype.cannot.contain.ltype=''{1}'' cannot contain ''{0}'' \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyInArgumentCheckInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyInArgumentCheckInspection.java new file mode 100644 index 000000000000..3b5e58883af0 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyInArgumentCheckInspection.java @@ -0,0 +1,117 @@ +/* + * Copyright 2000-2011 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.codeInspection.bugs; + +import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiUtil; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.codeInspection.BaseInspection; +import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor; +import org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; + +/** + * @author Max Medvedev + */ +public class GroovyInArgumentCheckInspection extends BaseInspection { + private MyVisitor MY_VISITOR = new MyVisitor(); + + @Override + protected BaseInspectionVisitor buildVisitor() { + return MY_VISITOR; + } + + @Override + protected String buildErrorString(Object... args) { + PsiType ltype = (PsiType)args[0]; + PsiType rtype = (PsiType)args[1]; + return GroovyInspectionBundle.message("rtype.cannot.contain.ltype", ltype.getPresentableText(), rtype.getPresentableText()); + + } + + @Nls + @NotNull + @Override + public String getGroupDisplayName() { + return BaseInspection.PROBABLE_BUGS; + } + + @Nls + @NotNull + @Override + public String getDisplayName() { + return "Incompatible 'in' argument types"; + } + + private static class MyVisitor extends BaseInspectionVisitor { + @Override + public void visitBinaryExpression(GrBinaryExpression expression) { + super.visitBinaryExpression(expression); + + if (expression.getOperationTokenType() != GroovyTokenTypes.kIN) return; + + GrExpression leftOperand = expression.getLeftOperand(); + GrExpression rightOperand = expression.getRightOperand(); + if (leftOperand == null || rightOperand == null) return; + + PsiType ltype = leftOperand.getType(); + PsiType rtype = rightOperand.getType(); + if (ltype == null || rtype == null) return; + + PsiType component; + + if (rtype instanceof PsiArrayType) { + component = ((PsiArrayType)rtype).getComponentType(); + } + else if (InheritanceUtil.isInheritor(rtype, CommonClassNames.JAVA_UTIL_COLLECTION)) { + component = PsiUtil.substituteTypeParameter(rtype, CommonClassNames.JAVA_UTIL_COLLECTION, 0, false); + } + else { + checkSimpleClasses(ltype, rtype, expression); + return; + } + + if (component == null) return; + + if (TypesUtil.isAssignable(ltype, component, PsiManager.getInstance(expression.getProject()), expression.getResolveScope(), false)) return; + + registerError(expression, ltype, rtype); + } + + private void checkSimpleClasses(PsiType ltype, PsiType rtype, GrBinaryExpression expression) { + if (!(rtype instanceof PsiClassType)) return; + if (!(ltype instanceof PsiClassType)) return; + + PsiClass lclass = ((PsiClassType)ltype).resolve(); + PsiClass rclass = ((PsiClassType)rtype).resolve(); + + if (lclass == null || rclass == null) return; + + if (PsiManager.getInstance(expression.getProject()).areElementsEquivalent(lclass, rclass)) return; + + if (lclass.isInterface() || rclass.isInterface()) return; + + if (lclass.isInheritor(rclass, true) || rclass.isInheritor(lclass, true)) return; + + registerError(expression, ltype, rtype); + } + } +} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy index 9c039b635085..80c3e04e1b17 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy @@ -512,4 +512,8 @@ class Bar {{ }}''' myFixture.checkHighlighting(false, false, false) } + + public void testMemberShipOperatorCheck() { + doTest(new GroovyInArgumentCheckInspection()); + } } \ No newline at end of file diff --git a/plugins/groovy/testdata/highlighting/MemberShipOperatorCheck.groovy b/plugins/groovy/testdata/highlighting/MemberShipOperatorCheck.groovy new file mode 100644 index 000000000000..fe3a9fc7607f --- /dev/null +++ b/plugins/groovy/testdata/highlighting/MemberShipOperatorCheck.groovy @@ -0,0 +1,29 @@ +/* + * Copyright 2000-2011 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. + */ +interface I1 {} +interface I2 {} + +def foo(I1 a, I2 b) { + print (a in b) +} + +print (1 in [1]) +print (1 in ['a']) +print (1 in 1) +print ([2] in [2]) + +print (1 in new ArrayList()) +print (new Date() in 2) \ No newline at end of file From 8bea31ec3c4d85ed033bc89cb637ba73c6ca85b9 Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Thu, 20 Oct 2011 11:22:57 +0400 Subject: [PATCH 113/128] geese braces initial --- .../plugins/groovy/formatter/GeeseUtil.java | 115 ++++++++++++++++ .../plugins/groovy/formatter/GroovyBlock.java | 39 +++++- .../formatter/GroovyBlockGenerator.java | 124 +++++++++++------- .../MethodCallWithoutQualifierBlock.java | 35 ++--- .../processors/GroovySpacingProcessor.java | 13 +- .../editor/actions/GroovyEnterHandler.java | 68 ++++++++-- 6 files changed, 312 insertions(+), 82 deletions(-) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java new file mode 100644 index 000000000000..2845668483ff --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java @@ -0,0 +1,115 @@ +/* + * Copyright 2000-2011 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.formatter; + +import com.intellij.formatting.Alignment; +import com.intellij.lang.ASTNode; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.TokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; + +import java.util.Map; + +import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mRCURLY; +import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.WHITE_SPACES_SET; +import static org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes.CLOSABLE_BLOCK; + +/** + * @author Max Medvedev + */ +public class GeeseUtil { + private static final Logger LOG = Logger.getInstance(GeeseUtil.class); + + private GeeseUtil() { + } + + @Nullable + public static ASTNode getClosureRBraceAtTheEnd(ASTNode node) { + IElementType elementType = node.getElementType(); + if (elementType == CLOSABLE_BLOCK) { + PsiElement rBrace = ((GrClosableBlock)node.getPsi()).getRBrace(); + return rBrace != null ? rBrace.getNode() : null; + } + + ASTNode lastChild = node.getLastChildNode(); + while (lastChild != null && WHITE_SPACES_SET.contains(lastChild.getElementType())) { + lastChild = lastChild.getTreePrev(); + } + if (lastChild == null) return null; + + return getClosureRBraceAtTheEnd(lastChild); + } + + public static boolean isClosureRBrace(PsiElement e) { + return e != null && e.getNode().getElementType() == mRCURLY && + e.getParent() instanceof GrClosableBlock && + ((GrClosableBlock)e.getParent()).getRBrace() == e; + } + + @Nullable + public static PsiElement getNextNonWhitespaceToken(PsiElement e) { + PsiElement next = PsiTreeUtil.nextLeaf(e); + while (next != null && next.getNode().getElementType() == TokenType.WHITE_SPACE) next = PsiTreeUtil.nextLeaf(next); + return next; + } + + @Nullable + public static PsiElement getPreviousNonWhitespaceToken(PsiElement e) { + PsiElement next = PsiTreeUtil.prevLeaf(e); + while (next != null && next.getNode().getElementType() == TokenType.WHITE_SPACE) next = PsiTreeUtil.prevLeaf(next); + return next; + } + + static Alignment calculateRBraceAlignment(PsiElement psi, Map alignments) { + int leadingBraceCount = 0; + PsiElement next = psi; + while (isClosureRBrace(next = getPreviousNonWhitespaceToken(next))) { + leadingBraceCount++; + } + + PsiElement cur = psi; + while (isClosureRBrace(next = getNextNonWhitespaceToken(cur))) { + cur = next; + } + + for (; leadingBraceCount > 0; leadingBraceCount--) { + cur = getPreviousNonWhitespaceToken(cur); + } + + PsiElement parent = cur.getParent(); + LOG.assertTrue(parent instanceof GrClosableBlock); + + //search for start of the line + cur = parent; + while (!PsiUtil.isNewLine(next = PsiTreeUtil.prevLeaf(cur, true))) { + if (next == null) break; + cur = next; + } + + //PsiElement statement = PsiUtil.findEnclosingStatement(parent); + Alignment alignment = alignments.get(cur); + if (alignment == null) { + alignment = Alignment.createAlignment(true); + alignments.put(cur, alignment); + } + return alignment; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java index 529a3ca2864d..d8be6c51db63 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 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. @@ -25,6 +25,7 @@ import com.intellij.psi.PsiErrorElement; import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.psi.tree.ILazyParseableElementType; +import com.intellij.util.containers.CollectionFactory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.formatter.processors.GroovyIndentProcessor; @@ -47,7 +48,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinary import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCommandArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList; -import java.util.Collections; import java.util.List; import java.util.Map; @@ -65,21 +65,41 @@ public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { final protected CommonCodeStyleSettings mySettings; final protected Map myInnerAlignments; - protected List mySubBlocks = null; - public GroovyBlock(@NotNull final ASTNode node, @Nullable final Alignment alignment, @NotNull final Indent indent, @Nullable final Wrap wrap, final CommonCodeStyleSettings settings) { - this(node, alignment, indent, wrap, settings, Collections.emptyMap()); + public GroovyBlock(@NotNull final ASTNode node, + @Nullable final Alignment alignment, + @NotNull final Indent indent, + @Nullable final Wrap wrap, + final CommonCodeStyleSettings settings) { + this(node, alignment, indent, wrap, settings, CollectionFactory.hashMap()); } - public GroovyBlock(@NotNull final ASTNode node, @Nullable final Alignment alignment, @NotNull final Indent indent, @Nullable final Wrap wrap, final CommonCodeStyleSettings settings, + public GroovyBlock(@NotNull final ASTNode node, + @Nullable Alignment alignment, + @NotNull final Indent indent, + @Nullable final Wrap wrap, + final CommonCodeStyleSettings settings, @NotNull Map innerAlignments) { myNode = node; - myAlignment = alignment; + if (settings.USE_FLYING_GEESE_BRACES && isLeaf()) { + PsiElement psi = myNode.getPsi(); + if (alignment == null) alignment = innerAlignments.get(psi); + if (alignment == null) alignment = Alignment.createAlignment(true); + + myAlignment = alignment; + innerAlignments.put(psi, myAlignment); + } + else { + myAlignment = alignment; + } + + myIndent = indent; myWrap = wrap; mySettings = settings; myInnerAlignments = innerAlignments; + } @NotNull @@ -172,6 +192,11 @@ public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { if (BLOCK_SET.contains(astNode.getElementType()) || SWITCH_STATEMENT.equals(astNode.getElementType())) { +// PsiElement psi = ((GroovyBlock)getSubBlocks().get(newChildIndex)).getNode().getPsi(); + // if (GeeseUtil.isClosureRBrace(psi)) { + // return new ChildAttributes(Indent.getNoneIndent(), GeeseUtil.calculateRBraceAlignment(psi, myInnerAlignments)); + // } + return new ChildAttributes(Indent.getNormalIndent(), null); } if (CASE_SECTION.equals(astNode.getElementType())) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java index b5a961de0ed7..982a0c54a081 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 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. @@ -21,6 +21,7 @@ import com.intellij.formatting.Block; import com.intellij.formatting.Indent; import com.intellij.formatting.Wrap; import com.intellij.lang.ASTNode; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.patterns.PlatformPatterns; @@ -32,7 +33,6 @@ import com.intellij.psi.impl.source.tree.LeafPsiElement; import com.intellij.psi.templateLanguages.OuterLanguageElement; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; -import com.intellij.util.containers.CollectionFactory; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -74,6 +74,8 @@ public class GroovyBlockGenerator implements GroovyElementTypes { PATH_METHOD_CALL, PATH_PROPERTY_REFERENCE); + private static final Logger LOG = Logger.getInstance(GroovyBlockGenerator.class); + public static List generateSubBlocks(ASTNode node, Alignment myAlignment, @@ -82,9 +84,11 @@ public class GroovyBlockGenerator implements GroovyElementTypes { GroovyBlock block) { //For binary expressions PsiElement blockPsi = block.getNode().getPsi(); + Map alignments = block.myInnerAlignments; + if (blockPsi instanceof GrBinaryExpression && !(blockPsi.getParent() instanceof GrBinaryExpression)) { - return generateForBinaryExpr(node, myWrap, mySettings, block.myInnerAlignments); + return generateForBinaryExpr(node, myWrap, mySettings, alignments); } //For multiline strings @@ -95,7 +99,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { if (text.length() > 6) { if (text.substring(0, 3).equals("'''") && text.substring(text.length() - 3).equals("'''") || text.substring(0, 3).equals("\"\"\"") & text.substring(text.length() - 3).equals("\"\"\"")) { - return generateForMultiLineString(block.getNode(), myAlignment, myWrap, mySettings); + return generateForMultiLineString(block.getNode(), myAlignment, myWrap, mySettings, alignments); } } } @@ -105,7 +109,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { String text = block.getNode().getText(); if (text.length() > 3) { if (text.substring(0, 3).equals("\"\"\"")) { - return generateForMultiLineGStringBegin(block.getNode(), myAlignment, myWrap, mySettings); + return generateForMultiLineGStringBegin(block.getNode(), myAlignment, myWrap, mySettings, alignments); } } @@ -118,7 +122,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { for (ASTNode childNode : children) { if (childNode.getTextRange().getLength() > 0) { final Indent indent = GroovyIndentProcessor.getChildIndent(block, childNode); - subBlocks.add(new GroovyBlock(childNode, myAlignment, indent, myWrap, mySettings)); + subBlocks.add(new GroovyBlock(childNode, myAlignment, indent, myWrap, mySettings, alignments)); } } return subBlocks; @@ -128,7 +132,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { if (NESTED.contains(block.getNode().getElementType()) && blockPsi.getParent() != null && !NESTED.contains(blockPsi.getParent().getNode().getElementType())) { final List subBlocks = new ArrayList(); Alignment dotsAlignment = mySettings.ALIGN_MULTILINE_CHAINED_METHODS ? Alignment.createAlignment() : null; - addNestedChildren(node.getPsi(), subBlocks, dotsAlignment, myWrap, mySettings, true); + addNestedChildren(node.getPsi(), subBlocks, dotsAlignment, myWrap, mySettings, true, alignments); return subBlocks; } @@ -139,7 +143,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final Alignment alignment = mustAlign(blockPsi, mySettings, astNodes) ? Alignment.createAlignment() : null; for (ASTNode childNode : astNodes) { final Indent indent = GroovyIndentProcessor.getChildIndent(block, childNode); - subBlocks.add(new GroovyBlock(childNode, isKeyword(childNode) ? null : alignment, indent, myWrap, mySettings)); + subBlocks.add(new GroovyBlock(childNode, isKeyword(childNode) ? null : alignment, indent, myWrap, mySettings, alignments)); } return subBlocks; } @@ -147,11 +151,11 @@ public class GroovyBlockGenerator implements GroovyElementTypes { boolean classLevel = blockPsi instanceof GrTypeDefinitionBody; if (blockPsi instanceof GrCodeBlock || blockPsi instanceof GroovyFile || classLevel) { List children = visibleChildren(node); - Map innerAlignments = calculateInnerAlignments(children, classLevel, mySettings); + calculateAlignments(children, classLevel, mySettings, alignments); final ArrayList subBlocks = new ArrayList(); for (ASTNode childNode : children) { final Indent indent = GroovyIndentProcessor.getChildIndent(block, childNode); - subBlocks.add(new GroovyBlock(childNode, classLevel ? myAlignment : null, indent, myWrap, mySettings, innerAlignments)); + subBlocks.add(new GroovyBlock(childNode, classLevel ? myAlignment : alignments.get(childNode.getPsi()), indent, myWrap, mySettings, alignments)); } return subBlocks; } @@ -160,13 +164,15 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final ArrayList subBlocks = new ArrayList(); for (ASTNode childNode : visibleChildren(node)) { final Indent indent = GroovyIndentProcessor.getChildIndent(block, childNode); - subBlocks.add(new GroovyBlock(childNode, block.myInnerAlignments.get(childNode.getPsi()), indent, myWrap, mySettings, block.myInnerAlignments)); + subBlocks.add(new GroovyBlock(childNode, alignments.get(childNode.getPsi()), indent, myWrap, mySettings, alignments)); } return subBlocks; } - private static Map calculateInnerAlignments(List children, boolean classLevel, CommonCodeStyleSettings settings) { - Map innerAlignments = CollectionFactory.hashMap(); + private static void calculateAlignments(List children, + boolean classLevel, + CommonCodeStyleSettings settings, + Map alignments) { List currentGroup = null; for (ASTNode child : children) { PsiElement psi = child.getPsi(); @@ -180,13 +186,13 @@ public class GroovyBlockGenerator implements GroovyElementTypes { for (LeafPsiElement expression : table) { Alignment alignment = Alignment.createAlignment(true); currentGroup.add(alignment); - ContainerUtil.putIfNotNull(expression, alignment, innerAlignments); + ContainerUtil.putIfNotNull(expression, alignment, alignments); } } } else if (currentGroup != null && isTablePart(psi)) { List table = getSpockTable((GrStatement)psi); for (int i = 0; i < Math.min(table.size(), currentGroup.size()); i++) { - innerAlignments.put(table.get(i), currentGroup.get(i)); + alignments.put(table.get(i), currentGroup.get(i)); } } else if (psi instanceof GrVariableDeclaration) { if (!classLevel || currentGroup == null || fieldGroupEnded(settings, psi)) { @@ -197,19 +203,22 @@ public class GroovyBlockGenerator implements GroovyElementTypes { if (variables.length > 0) { Alignment varName = currentGroup.get(1); for (GrVariable variable : variables) { - innerAlignments.put(variable.getNameIdentifierGroovy(), varName); + alignments.put(variable.getNameIdentifierGroovy(), varName); } if (classLevel && settings.ALIGN_GROUP_FIELD_DECLARATIONS) { - ContainerUtil.putIfNotNull(((GrVariableDeclaration)psi).getTypeElementGroovy(), currentGroup.get(0), innerAlignments); + ContainerUtil.putIfNotNull(((GrVariableDeclaration)psi).getTypeElementGroovy(), currentGroup.get(0), alignments); ASTNode eq = variables[variables.length - 1].getNode().findChildByType(GroovyTokenTypes.mASSIGN); if (eq != null) { - innerAlignments.put(eq.getPsi(), currentGroup.get(2)); + alignments.put(eq.getPsi(), currentGroup.get(2)); } } } } + else if (GeeseUtil.isClosureRBrace(psi)) { + alignments.put(psi, GeeseUtil.calculateRBraceAlignment(psi, alignments)); + } else { if (psi instanceof PsiComment) { PsiElement prev = psi.getPrevSibling(); @@ -220,7 +229,6 @@ public class GroovyBlockGenerator implements GroovyElementTypes { currentGroup = null; } } - return innerAlignments; } private static boolean fieldGroupEnded(CommonCodeStyleSettings settings, PsiElement psi) { @@ -296,24 +304,28 @@ public class GroovyBlockGenerator implements GroovyElementTypes { } - private static List generateForMultiLineString(ASTNode node, Alignment myAlignment, Wrap myWrap, CommonCodeStyleSettings mySettings) { + private static List generateForMultiLineString(ASTNode node, + Alignment myAlignment, + Wrap myWrap, + CommonCodeStyleSettings mySettings, + Map alignments) { final ArrayList subBlocks = new ArrayList(); final int start = node.getTextRange().getStartOffset(); final int end = node.getTextRange().getEndOffset(); - subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getNoneIndent(), myWrap, mySettings) { + subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, alignments) { @NotNull public TextRange getTextRange() { return new TextRange(start, start + 3); } }); - subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings) { + subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, alignments) { @NotNull public TextRange getTextRange() { return new TextRange(start + 3, end - 3); } }); - subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings) { + subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, alignments) { @NotNull public TextRange getTextRange() { return new TextRange(end - 3, end); @@ -322,18 +334,22 @@ public class GroovyBlockGenerator implements GroovyElementTypes { return subBlocks; } - private static List generateForMultiLineGStringBegin(ASTNode node, Alignment myAlignment, Wrap myWrap, CommonCodeStyleSettings mySettings) { + private static List generateForMultiLineGStringBegin(ASTNode node, + Alignment myAlignment, + Wrap myWrap, + CommonCodeStyleSettings mySettings, + Map alignments) { final ArrayList subBlocks = new ArrayList(); final int start = node.getTextRange().getStartOffset(); final int end = node.getTextRange().getEndOffset(); - subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getNoneIndent(), myWrap, mySettings) { + subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, alignments) { @NotNull public TextRange getTextRange() { return new TextRange(start, start + 3); } }); - subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings) { + subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, alignments) { @NotNull public TextRange getTextRange() { return new TextRange(start + 3, end); @@ -383,14 +399,17 @@ public class GroovyBlockGenerator implements GroovyElementTypes { * @return * @param node */ - private static List generateForBinaryExpr(final ASTNode node, Wrap myWrap, CommonCodeStyleSettings mySettings, Map inner) { + private static List generateForBinaryExpr(final ASTNode node, + Wrap myWrap, + CommonCodeStyleSettings mySettings, + Map alignments) { final ArrayList subBlocks = new ArrayList(); Alignment alignment = mySettings.ALIGN_MULTILINE_BINARY_OPERATION ? Alignment.createAlignment() : null; GrBinaryExpression binary = (GrBinaryExpression) node.getPsi(); - assert binary != null; - addBinaryChildrenRecursively(binary, subBlocks, Indent.getContinuationWithoutFirstIndent(), alignment, myWrap, mySettings, inner); + LOG.assertTrue(binary != null); + addBinaryChildrenRecursively(binary, subBlocks, Indent.getContinuationWithoutFirstIndent(), alignment, myWrap, mySettings, alignments); return subBlocks; } @@ -405,34 +424,39 @@ public class GroovyBlockGenerator implements GroovyElementTypes { private static void addBinaryChildrenRecursively(PsiElement elem, List list, Indent indent, - Alignment alignment, Wrap myWrap, + Alignment alignment, + Wrap myWrap, CommonCodeStyleSettings mySettings, - Map inner) { + Map alignments) { if (elem == null) return; // For binary expressions if ((elem instanceof GrBinaryExpression)) { GrBinaryExpression myExpr = ((GrBinaryExpression) elem); if (myExpr.getLeftOperand() instanceof GrBinaryExpression) { - addBinaryChildrenRecursively(myExpr.getLeftOperand(), list, Indent.getContinuationWithoutFirstIndent(), alignment, myWrap, mySettings, inner); + addBinaryChildrenRecursively(myExpr.getLeftOperand(), list, Indent.getContinuationWithoutFirstIndent(), alignment, myWrap, mySettings, alignments); } PsiElement op = ((GrBinaryExpression)elem).getOperationToken(); for (ASTNode childNode : visibleChildren(elem.getNode())) { PsiElement psi = childNode.getPsi(); if (!(psi instanceof GrBinaryExpression)) { - list.add(new GroovyBlock(childNode, op == psi ? inner.get(op) : alignment, indent, myWrap, mySettings)); + list.add(new GroovyBlock(childNode, op == psi ? alignments.get(op) : alignment, indent, myWrap, mySettings, alignments)); } } if (myExpr.getRightOperand() instanceof GrBinaryExpression) { - addBinaryChildrenRecursively(myExpr.getRightOperand(), list, Indent.getContinuationWithoutFirstIndent(), alignment, myWrap, mySettings, inner); + addBinaryChildrenRecursively(myExpr.getRightOperand(), list, Indent.getContinuationWithoutFirstIndent(), alignment, myWrap, + mySettings, alignments); } } } - private static void addNestedChildren(final PsiElement elem, List list, + private static void addNestedChildren(final PsiElement elem, + List list, @Nullable final Alignment alignment, final Wrap wrap, - final CommonCodeStyleSettings settings, final boolean topLevel) { + final CommonCodeStyleSettings settings, + final boolean topLevel, + Map alignments) { final List children = visibleChildren(elem.getNode()); if (elem instanceof GrMethodCallExpression) { GrExpression invokedExpression = ((GrMethodCallExpression)elem).getInvokedExpression(); @@ -443,11 +467,11 @@ public class GroovyBlockGenerator implements GroovyElementTypes { int i = 0; while (i < grandChildren.size() && nameElement != grandChildren.get(i).getPsi()) { i++; } if (i > 0) { - processNestedChildrenPrefix(list, alignment, wrap, settings, false, grandChildren, i); + processNestedChildrenPrefix(list, alignment, wrap, settings, false, grandChildren, i, alignments); } if (i < grandChildren.size()) { - assert nameElement == grandChildren.get(i).getPsi(); - list.add(new MethodCallWithoutQualifierBlock(nameElement, null, wrap, settings, topLevel, children, elem)); + LOG.assertTrue(nameElement == grandChildren.get(i).getPsi()); + list.add(new MethodCallWithoutQualifierBlock(nameElement, null, wrap, settings, topLevel, children, elem, alignments)); } return; } @@ -456,35 +480,41 @@ public class GroovyBlockGenerator implements GroovyElementTypes { } - processNestedChildrenPrefix(list, alignment, wrap, settings, topLevel, children, children.size()); + processNestedChildrenPrefix(list, alignment, wrap, settings, topLevel, children, children.size(), alignments); } private static void processNestedChildrenPrefix(List list, Alignment alignment, Wrap wrap, CommonCodeStyleSettings settings, - boolean topLevel, List children, int limit) { + boolean topLevel, + List children, + int limit, + Map alignments) { ASTNode fst = children.get(0); - assert limit > 0; + LOG.assertTrue(limit > 0); if (NESTED.contains(fst.getElementType())) { - addNestedChildren(fst.getPsi(), list, alignment, wrap, settings, false); + addNestedChildren(fst.getPsi(), list, alignment, wrap, settings, false, alignments); } else { - list.add(new GroovyBlock(fst, null, Indent.getContinuationWithoutFirstIndent(), wrap, settings)); + list.add(new GroovyBlock(fst, alignments.get(fst.getPsi()), Indent.getContinuationWithoutFirstIndent(), wrap, settings, alignments)); } - addNestedChildrenSuffix(list, alignment, wrap, settings, topLevel, children, limit); + addNestedChildrenSuffix(list, alignment, wrap, settings, topLevel, children, limit, alignments); } static void addNestedChildrenSuffix(List list, Alignment alignment, Wrap wrap, CommonCodeStyleSettings settings, - boolean topLevel, List children, int limit) { + boolean topLevel, + List children, + int limit, + Map alignments) { for (int i = 1; i < limit; i++) { ASTNode childNode = children.get(i); if (canBeCorrectBlock(childNode)) { IElementType type = childNode.getElementType(); Indent indent = topLevel || NESTED.contains(type) || type == mIDENT ? Indent.getContinuationWithoutFirstIndent() : Indent.getNoneIndent(); - list.add(new GroovyBlock(childNode, TokenSets.DOTS.contains(type) ? alignment : null, indent, wrap, settings)); + list.add(new GroovyBlock(childNode, TokenSets.DOTS.contains(type) ? alignment : alignments.get(childNode.getPsi()), indent, wrap, settings, alignments)); } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java index d783e28f4e49..28088b113e37 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java @@ -22,36 +22,32 @@ import com.intellij.formatting.Wrap; import com.intellij.lang.ASTNode; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; -import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** -* @author peter -*/ + * @author peter + */ public class MethodCallWithoutQualifierBlock extends GroovyBlock { private final PsiElement myNameElement; - private final Alignment myAlignment; - private final Wrap myWrap; - private final CommonCodeStyleSettings mySettings; private final boolean myTopLevel; private final List myChildren; private final PsiElement myElem; - + public MethodCallWithoutQualifierBlock(PsiElement nameElement, Alignment alignment, Wrap wrap, CommonCodeStyleSettings settings, boolean topLevel, - List children, PsiElement elem) { - super(nameElement.getNode(), alignment, Indent.getContinuationWithoutFirstIndent(), wrap, settings); + List children, + PsiElement elem, + Map innerAlignments) { + super(nameElement.getNode(), alignment, Indent.getContinuationWithoutFirstIndent(), wrap, settings, innerAlignments); myNameElement = nameElement; - myAlignment = alignment; - myWrap = wrap; - mySettings = settings; myTopLevel = topLevel; myChildren = children; myElem = elem; @@ -60,10 +56,12 @@ public class MethodCallWithoutQualifierBlock extends GroovyBlock { @NotNull @Override public List getSubBlocks() { - ArrayList blocks = new ArrayList(); - blocks.add(new GroovyBlock(myNameElement.getNode(), myAlignment, Indent.getContinuationWithoutFirstIndent(), myWrap, mySettings)); - GroovyBlockGenerator.addNestedChildrenSuffix(blocks, myAlignment, myWrap, mySettings, myTopLevel, myChildren, myChildren.size()); - return blocks; + if (mySubBlocks == null) { + mySubBlocks = new ArrayList(); + mySubBlocks.add(new GroovyBlock(myNameElement.getNode(), myInnerAlignments.get(myNameElement), Indent.getContinuationWithoutFirstIndent(), myWrap, mySettings, myInnerAlignments)); + GroovyBlockGenerator.addNestedChildrenSuffix(mySubBlocks, myAlignment, myWrap, mySettings, myTopLevel, myChildren, myChildren.size(), myInnerAlignments); + } + return mySubBlocks; } @NotNull @@ -71,4 +69,9 @@ public class MethodCallWithoutQualifierBlock extends GroovyBlock { public TextRange getTextRange() { return new TextRange(myNameElement.getTextRange().getStartOffset(), myElem.getTextRange().getEndOffset()); } + + @Override + public boolean isLeaf() { + return false; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java index 66a2909e2d55..ae02f2788dcd 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 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. @@ -28,6 +28,7 @@ import com.intellij.psi.formatter.FormatterUtil; import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.impl.source.tree.CompositeElement; import com.intellij.psi.tree.IElementType; +import org.jetbrains.plugins.groovy.formatter.GeeseUtil; import org.jetbrains.plugins.groovy.lang.editor.actions.GroovyEditorActionUtil; import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.*; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; @@ -153,8 +154,14 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { } public void visitClosure(GrClosableBlock closure) { - if ((myChild1.getElementType() == mLCURLY && myChild2.getElementType() != PARAMETERS_LIST && myChild2.getElementType() != mCLOSABLE_BLOCK_OP) - || myChild2.getElementType() == mRCURLY) { + ASTNode rBraceAtTheEnd = GeeseUtil.getClosureRBraceAtTheEnd(myChild1); + if (mySettings.USE_FLYING_GEESE_BRACES && myChild2.getElementType() == mRCURLY && rBraceAtTheEnd != null) { + myResult = Spacing.createSpacing(0, 0, 0, true, 100, 0); + } + else if ((myChild1.getElementType() == mLCURLY && + myChild2.getElementType() != PARAMETERS_LIST && + myChild2.getElementType() != mCLOSABLE_BLOCK_OP) + || myChild2.getElementType() == mRCURLY) { myResult = Spacing.createDependentLFSpacing(0, 1, closure.getTextRange(), mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); } else if (myChild1.getElementType() == mCLOSABLE_BLOCK_OP) { GrStatement[] statements = closure.getStatements(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/GroovyEnterHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/GroovyEnterHandler.java index 25b2116f8f30..8e3fb4b95211 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/GroovyEnterHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/GroovyEnterHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 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. @@ -20,7 +20,7 @@ import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegateAdapter; import com.intellij.lang.ASTNode; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.DataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorModificationUtil; @@ -35,9 +35,13 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.formatter.GeeseUtil; import org.jetbrains.plugins.groovy.lang.editor.HandlerUtils; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; @@ -94,9 +98,16 @@ public class GroovyEnterHandler extends EnterHandlerDelegateAdapter { if (afterArrow) { return Result.Stop; } + + if (editor.isInsertMode() && + !HandlerUtils.isReadOnly(editor) && + !editor.getSelectionModel().hasSelection() && + handleFlyingGeese(editor, caret, dataContext, originalHandler, file)) { + return Result.DefaultForceIndent; + } } - if (handleEnter(editor, dataContext, file.getProject(), originalHandler, file)) { + if (handleEnter(editor, dataContext, file.getProject(), originalHandler)) { return Result.Stop; } return Result.Continue; @@ -105,7 +116,7 @@ public class GroovyEnterHandler extends EnterHandlerDelegateAdapter { protected static boolean handleEnter(Editor editor, DataContext dataContext, @NotNull Project project, - EditorActionHandler originalHandler, PsiFile file) { + EditorActionHandler originalHandler) { if (HandlerUtils.isReadOnly(editor)) { return false; } @@ -118,9 +129,52 @@ public class GroovyEnterHandler extends EnterHandlerDelegateAdapter { if (handleInString(editor, caretOffset, dataContext, originalHandler)) { return true; } + return false; } + private static boolean handleFlyingGeese(Editor editor, + int caretOffset, + DataContext dataContext, + EditorActionHandler originalHandler, + PsiFile file) { + Project project = PlatformDataKeys.PROJECT.getData(dataContext); + if (project == null) return false; + + CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project); + if (!codeStyleSettings.USE_FLYING_GEESE_BRACES) return false; + + PsiElement element = file.findElementAt(caretOffset); + if (element != null && element.getNode().getElementType() == TokenType.WHITE_SPACE) { + element = GeeseUtil.getNextNonWhitespaceToken(element); + } + if (element == null || !GeeseUtil.isClosureRBrace(element)) return false; + + element = GeeseUtil.getNextNonWhitespaceToken(element); + if (element == null || + element.getNode().getElementType() != GroovyTokenTypes.mNLS || + StringUtil.countChars(element.getText(), '\n') > 1) { + return false; + } + + element = GeeseUtil.getNextNonWhitespaceToken(element); + if (element == null || !GeeseUtil.isClosureRBrace(element)) return false; + + Document document = editor.getDocument(); + PsiDocumentManager.getInstance(project).commitDocument(document); + + int toRemove = element.getTextRange().getStartOffset(); + document.deleteString(caretOffset + 1, toRemove); + + originalHandler.execute(editor, dataContext); + + String text = document.getText(); + int nextLineFeed = text.indexOf('\n', caretOffset + 1); + CodeStyleManager.getInstance(project).reformatText(file, caretOffset, nextLineFeed); + + return true; + } + private static boolean handleBetweenSquareBraces(Editor editor, int caret, DataContext context, @@ -163,7 +217,7 @@ public class GroovyEnterHandler extends EnterHandlerDelegateAdapter { private static boolean handleInString(Editor editor, int caretOffset, DataContext dataContext, EditorActionHandler originalHandler) { - Project project = DataKeys.PROJECT.getData(dataContext); + Project project = PlatformDataKeys.PROJECT.getData(dataContext); if (project == null) return false; PsiFile file = PsiManager.getInstance(project).findFile(FileDocumentManager.getInstance().getFile(editor.getDocument())); @@ -184,8 +238,6 @@ public class GroovyEnterHandler extends EnterHandlerDelegateAdapter { // For simple String literals like 'abcdef' if (mSTRING_LITERAL == node.getElementType()) { if (GroovyEditorActionUtil.isPlainStringLiteral(node)) { - String text = node.getText(); - String innerText = text.equals("''") ? "" : text.substring(1, text.length() - 1); TextRange literalRange = stringElement.getTextRange(); document.insertString(literalRange.getEndOffset(), "''"); document.insertString(literalRange.getStartOffset(), "''"); @@ -221,8 +273,6 @@ public class GroovyEnterHandler extends EnterHandlerDelegateAdapter { PsiElement exprSibling = stringElement.getNextSibling(); boolean rightFromDollar = exprSibling instanceof GrExpression && exprSibling.getTextRange().getStartOffset() == caretOffset; if (rightFromDollar) caretOffset--; - String text = parent.getText(); - String innerText = text.equals("\"\"") ? "" : text.substring(1, text.length() - 1); TextRange parentRange = parent.getTextRange(); document.insertString(parentRange.getEndOffset(), "\"\""); document.insertString(parentRange.getStartOffset(), "\"\""); From 8bd9f40f29616fc9eb07e48b7cb1ac4f7925a6c9 Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Thu, 20 Oct 2011 15:12:59 +0400 Subject: [PATCH 114/128] groovy code style settings --- .../plugins/groovy/formatter/GroovyBlock.java | 16 +++-- .../formatter/GroovyBlockGenerator.java | 67 ++++++++++--------- .../formatter/GroovyCodeStyleSettings.java | 47 +++++++++++++ .../GroovyCodeStyleSettingsProvider.java | 6 ++ .../GroovyFormattingModelBuilder.java | 3 +- ...oovyLanguageCodeStyleSettingsProvider.java | 7 ++ .../MethodCallWithoutQualifierBlock.java | 7 +- .../processors/GroovySpacingProcessor.java | 33 +++++---- .../editor/actions/GroovyEnterHandler.java | 5 +- 9 files changed, 130 insertions(+), 61 deletions(-) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyCodeStyleSettings.java diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java index d8be6c51db63..c400cc906deb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java @@ -63,6 +63,7 @@ public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { final protected Indent myIndent; final protected Wrap myWrap; final protected CommonCodeStyleSettings mySettings; + final protected GroovyCodeStyleSettings myGroovySettings; final protected Map myInnerAlignments; protected List mySubBlocks = null; @@ -71,8 +72,10 @@ public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { @Nullable final Alignment alignment, @NotNull final Indent indent, @Nullable final Wrap wrap, - final CommonCodeStyleSettings settings) { - this(node, alignment, indent, wrap, settings, CollectionFactory.hashMap()); + final CommonCodeStyleSettings settings, + GroovyCodeStyleSettings groovySettings + ) { + this(node, alignment, indent, wrap, settings, groovySettings, CollectionFactory.hashMap()); } public GroovyBlock(@NotNull final ASTNode node, @@ -80,9 +83,10 @@ public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { @NotNull final Indent indent, @Nullable final Wrap wrap, final CommonCodeStyleSettings settings, + GroovyCodeStyleSettings groovySettings, @NotNull Map innerAlignments) { myNode = node; - if (settings.USE_FLYING_GEESE_BRACES && isLeaf()) { + if (groovySettings.USE_FLYING_GEESE_BRACES && isLeaf()) { PsiElement psi = myNode.getPsi(); if (alignment == null) alignment = innerAlignments.get(psi); if (alignment == null) alignment = Alignment.createAlignment(true); @@ -98,8 +102,8 @@ public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { myIndent = indent; myWrap = wrap; mySettings = settings; + myGroovySettings = groovySettings; myInnerAlignments = innerAlignments; - } @NotNull @@ -120,7 +124,7 @@ public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { @NotNull public List getSubBlocks() { if (mySubBlocks == null) { - mySubBlocks = GroovyBlockGenerator.generateSubBlocks(myNode, myAlignment, myWrap, mySettings, this); + mySubBlocks = GroovyBlockGenerator.generateSubBlocks(myNode, myAlignment, myWrap, mySettings, myGroovySettings, this); } return mySubBlocks; } @@ -154,7 +158,7 @@ public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { return Spacing.getReadOnlySpacing(); } - Spacing spacing = new GroovySpacingProcessor(((GroovyBlock)child2).getNode(), mySettings).getSpacing(); + Spacing spacing = new GroovySpacingProcessor(((GroovyBlock)child2).getNode(), mySettings, myGroovySettings).getSpacing(); return spacing != null ? spacing : GroovySpacingProcessorBasic.getSpacing(((GroovyBlock)child1), ((GroovyBlock)child2), mySettings); } return null; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java index 982a0c54a081..185f8576b2c4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java @@ -81,6 +81,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { Alignment myAlignment, Wrap myWrap, CommonCodeStyleSettings mySettings, + GroovyCodeStyleSettings groovySettings, GroovyBlock block) { //For binary expressions PsiElement blockPsi = block.getNode().getPsi(); @@ -88,7 +89,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { if (blockPsi instanceof GrBinaryExpression && !(blockPsi.getParent() instanceof GrBinaryExpression)) { - return generateForBinaryExpr(node, myWrap, mySettings, alignments); + return generateForBinaryExpr(node, myWrap, mySettings, groovySettings, alignments); } //For multiline strings @@ -99,7 +100,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { if (text.length() > 6) { if (text.substring(0, 3).equals("'''") && text.substring(text.length() - 3).equals("'''") || text.substring(0, 3).equals("\"\"\"") & text.substring(text.length() - 3).equals("\"\"\"")) { - return generateForMultiLineString(block.getNode(), myAlignment, myWrap, mySettings, alignments); + return generateForMultiLineString(block.getNode(), myAlignment, myWrap, mySettings, groovySettings, alignments); } } } @@ -109,7 +110,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { String text = block.getNode().getText(); if (text.length() > 3) { if (text.substring(0, 3).equals("\"\"\"")) { - return generateForMultiLineGStringBegin(block.getNode(), myAlignment, myWrap, mySettings, alignments); + return generateForMultiLineGStringBegin(block.getNode(), myAlignment, myWrap, mySettings, groovySettings, alignments); } } @@ -122,7 +123,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { for (ASTNode childNode : children) { if (childNode.getTextRange().getLength() > 0) { final Indent indent = GroovyIndentProcessor.getChildIndent(block, childNode); - subBlocks.add(new GroovyBlock(childNode, myAlignment, indent, myWrap, mySettings, alignments)); + subBlocks.add(new GroovyBlock(childNode, myAlignment, indent, myWrap, mySettings, groovySettings, alignments)); } } return subBlocks; @@ -132,7 +133,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { if (NESTED.contains(block.getNode().getElementType()) && blockPsi.getParent() != null && !NESTED.contains(blockPsi.getParent().getNode().getElementType())) { final List subBlocks = new ArrayList(); Alignment dotsAlignment = mySettings.ALIGN_MULTILINE_CHAINED_METHODS ? Alignment.createAlignment() : null; - addNestedChildren(node.getPsi(), subBlocks, dotsAlignment, myWrap, mySettings, true, alignments); + addNestedChildren(node.getPsi(), subBlocks, dotsAlignment, myWrap, mySettings, groovySettings, true, alignments); return subBlocks; } @@ -143,7 +144,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final Alignment alignment = mustAlign(blockPsi, mySettings, astNodes) ? Alignment.createAlignment() : null; for (ASTNode childNode : astNodes) { final Indent indent = GroovyIndentProcessor.getChildIndent(block, childNode); - subBlocks.add(new GroovyBlock(childNode, isKeyword(childNode) ? null : alignment, indent, myWrap, mySettings, alignments)); + subBlocks.add(new GroovyBlock(childNode, isKeyword(childNode) ? null : alignment, indent, myWrap, mySettings, groovySettings, alignments)); } return subBlocks; } @@ -155,7 +156,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final ArrayList subBlocks = new ArrayList(); for (ASTNode childNode : children) { final Indent indent = GroovyIndentProcessor.getChildIndent(block, childNode); - subBlocks.add(new GroovyBlock(childNode, classLevel ? myAlignment : alignments.get(childNode.getPsi()), indent, myWrap, mySettings, alignments)); + subBlocks.add(new GroovyBlock(childNode, classLevel ? myAlignment : alignments.get(childNode.getPsi()), indent, myWrap, mySettings, groovySettings, alignments)); } return subBlocks; } @@ -164,7 +165,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final ArrayList subBlocks = new ArrayList(); for (ASTNode childNode : visibleChildren(node)) { final Indent indent = GroovyIndentProcessor.getChildIndent(block, childNode); - subBlocks.add(new GroovyBlock(childNode, alignments.get(childNode.getPsi()), indent, myWrap, mySettings, alignments)); + subBlocks.add(new GroovyBlock(childNode, alignments.get(childNode.getPsi()), indent, myWrap, mySettings, groovySettings, alignments)); } return subBlocks; } @@ -308,24 +309,24 @@ public class GroovyBlockGenerator implements GroovyElementTypes { Alignment myAlignment, Wrap myWrap, CommonCodeStyleSettings mySettings, - Map alignments) { + GroovyCodeStyleSettings groovySettings, Map alignments) { final ArrayList subBlocks = new ArrayList(); final int start = node.getTextRange().getStartOffset(); final int end = node.getTextRange().getEndOffset(); - subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, alignments) { + subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, groovySettings, alignments) { @NotNull public TextRange getTextRange() { return new TextRange(start, start + 3); } }); - subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, alignments) { + subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, groovySettings, alignments) { @NotNull public TextRange getTextRange() { return new TextRange(start + 3, end - 3); } }); - subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, alignments) { + subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, groovySettings, alignments) { @NotNull public TextRange getTextRange() { return new TextRange(end - 3, end); @@ -338,18 +339,18 @@ public class GroovyBlockGenerator implements GroovyElementTypes { Alignment myAlignment, Wrap myWrap, CommonCodeStyleSettings mySettings, - Map alignments) { + GroovyCodeStyleSettings groovySettings, Map alignments) { final ArrayList subBlocks = new ArrayList(); final int start = node.getTextRange().getStartOffset(); final int end = node.getTextRange().getEndOffset(); - subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, alignments) { + subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, groovySettings, alignments) { @NotNull public TextRange getTextRange() { return new TextRange(start, start + 3); } }); - subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, alignments) { + subBlocks.add(new GroovyBlock(node, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, groovySettings, alignments) { @NotNull public TextRange getTextRange() { return new TextRange(start + 3, end); @@ -398,18 +399,20 @@ public class GroovyBlockGenerator implements GroovyElementTypes { * * @return * @param node + * @param groovySettings */ private static List generateForBinaryExpr(final ASTNode node, Wrap myWrap, CommonCodeStyleSettings mySettings, - Map alignments) { + GroovyCodeStyleSettings groovySettings, Map alignments) { final ArrayList subBlocks = new ArrayList(); Alignment alignment = mySettings.ALIGN_MULTILINE_BINARY_OPERATION ? Alignment.createAlignment() : null; GrBinaryExpression binary = (GrBinaryExpression) node.getPsi(); LOG.assertTrue(binary != null); - addBinaryChildrenRecursively(binary, subBlocks, Indent.getContinuationWithoutFirstIndent(), alignment, myWrap, mySettings, alignments); + addBinaryChildrenRecursively(binary, subBlocks, Indent.getContinuationWithoutFirstIndent(), alignment, myWrap, mySettings, + groovySettings, alignments); return subBlocks; } @@ -420,6 +423,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { * @param list * @param indent * @param alignment + * @param groovySettings */ private static void addBinaryChildrenRecursively(PsiElement elem, List list, @@ -427,24 +431,25 @@ public class GroovyBlockGenerator implements GroovyElementTypes { Alignment alignment, Wrap myWrap, CommonCodeStyleSettings mySettings, - Map alignments) { + GroovyCodeStyleSettings groovySettings, Map alignments) { if (elem == null) return; // For binary expressions if ((elem instanceof GrBinaryExpression)) { GrBinaryExpression myExpr = ((GrBinaryExpression) elem); if (myExpr.getLeftOperand() instanceof GrBinaryExpression) { - addBinaryChildrenRecursively(myExpr.getLeftOperand(), list, Indent.getContinuationWithoutFirstIndent(), alignment, myWrap, mySettings, alignments); + addBinaryChildrenRecursively(myExpr.getLeftOperand(), list, Indent.getContinuationWithoutFirstIndent(), alignment, myWrap, mySettings, + groovySettings, alignments); } PsiElement op = ((GrBinaryExpression)elem).getOperationToken(); for (ASTNode childNode : visibleChildren(elem.getNode())) { PsiElement psi = childNode.getPsi(); if (!(psi instanceof GrBinaryExpression)) { - list.add(new GroovyBlock(childNode, op == psi ? alignments.get(op) : alignment, indent, myWrap, mySettings, alignments)); + list.add(new GroovyBlock(childNode, op == psi ? alignments.get(op) : alignment, indent, myWrap, mySettings, groovySettings, alignments)); } } if (myExpr.getRightOperand() instanceof GrBinaryExpression) { addBinaryChildrenRecursively(myExpr.getRightOperand(), list, Indent.getContinuationWithoutFirstIndent(), alignment, myWrap, - mySettings, alignments); + mySettings, groovySettings, alignments); } } } @@ -455,7 +460,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { @Nullable final Alignment alignment, final Wrap wrap, final CommonCodeStyleSettings settings, - final boolean topLevel, + GroovyCodeStyleSettings groovySettings, final boolean topLevel, Map alignments) { final List children = visibleChildren(elem.getNode()); if (elem instanceof GrMethodCallExpression) { @@ -467,11 +472,11 @@ public class GroovyBlockGenerator implements GroovyElementTypes { int i = 0; while (i < grandChildren.size() && nameElement != grandChildren.get(i).getPsi()) { i++; } if (i > 0) { - processNestedChildrenPrefix(list, alignment, wrap, settings, false, grandChildren, i, alignments); + processNestedChildrenPrefix(list, alignment, wrap, settings, groovySettings, false, grandChildren, i, alignments); } if (i < grandChildren.size()) { LOG.assertTrue(nameElement == grandChildren.get(i).getPsi()); - list.add(new MethodCallWithoutQualifierBlock(nameElement, null, wrap, settings, topLevel, children, elem, alignments)); + list.add(new MethodCallWithoutQualifierBlock(nameElement, null, wrap, settings, groovySettings, topLevel, children, elem, alignments)); } return; } @@ -480,32 +485,32 @@ public class GroovyBlockGenerator implements GroovyElementTypes { } - processNestedChildrenPrefix(list, alignment, wrap, settings, topLevel, children, children.size(), alignments); + processNestedChildrenPrefix(list, alignment, wrap, settings, groovySettings, topLevel, children, children.size(), alignments); } private static void processNestedChildrenPrefix(List list, Alignment alignment, Wrap wrap, CommonCodeStyleSettings settings, - boolean topLevel, + GroovyCodeStyleSettings groovySettings, boolean topLevel, List children, int limit, Map alignments) { ASTNode fst = children.get(0); LOG.assertTrue(limit > 0); if (NESTED.contains(fst.getElementType())) { - addNestedChildren(fst.getPsi(), list, alignment, wrap, settings, false, alignments); + addNestedChildren(fst.getPsi(), list, alignment, wrap, settings, groovySettings, false, alignments); } else { - list.add(new GroovyBlock(fst, alignments.get(fst.getPsi()), Indent.getContinuationWithoutFirstIndent(), wrap, settings, alignments)); + list.add(new GroovyBlock(fst, alignments.get(fst.getPsi()), Indent.getContinuationWithoutFirstIndent(), wrap, settings, groovySettings, alignments)); } - addNestedChildrenSuffix(list, alignment, wrap, settings, topLevel, children, limit, alignments); + addNestedChildrenSuffix(list, alignment, wrap, settings, groovySettings, topLevel, children, limit, alignments); } static void addNestedChildrenSuffix(List list, Alignment alignment, Wrap wrap, CommonCodeStyleSettings settings, - boolean topLevel, + GroovyCodeStyleSettings groovySettings, boolean topLevel, List children, int limit, Map alignments) { @@ -514,7 +519,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { if (canBeCorrectBlock(childNode)) { IElementType type = childNode.getElementType(); Indent indent = topLevel || NESTED.contains(type) || type == mIDENT ? Indent.getContinuationWithoutFirstIndent() : Indent.getNoneIndent(); - list.add(new GroovyBlock(childNode, TokenSets.DOTS.contains(type) ? alignment : alignments.get(childNode.getPsi()), indent, wrap, settings, alignments)); + list.add(new GroovyBlock(childNode, TokenSets.DOTS.contains(type) ? alignment : alignments.get(childNode.getPsi()), indent, wrap, settings, groovySettings, alignments)); } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyCodeStyleSettings.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyCodeStyleSettings.java new file mode 100644 index 000000000000..242f15746cf0 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyCodeStyleSettings.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2011 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.formatter; + +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CustomCodeStyleSettings; + +/** + * @author Max Medvedev + */ +public class GroovyCodeStyleSettings extends CustomCodeStyleSettings { + /** + * Defines if 'flying geese' style should be used for curly braces formatting, e.g. if we want to format code like + *

+ *

+   *     class Test {
+   *         {
+   *             System.out.println();
+   *         }
+   *     }
+   * 
+ * to + *
+   *     class Test { {
+   *         System.out.println();
+   *     } }
+   * 
+ */ + public boolean USE_FLYING_GEESE_BRACES = true; + + public GroovyCodeStyleSettings(CodeStyleSettings container) { + super("GroovyCodeStyleSettings", container); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyCodeStyleSettingsProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyCodeStyleSettingsProvider.java index e8275e58f0fd..219592ea6aa8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyCodeStyleSettingsProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyCodeStyleSettingsProvider.java @@ -21,6 +21,7 @@ import com.intellij.application.options.TabbedLanguageCodeStylePanel; import com.intellij.openapi.options.Configurable; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsProvider; +import com.intellij.psi.codeStyle.CustomCodeStyleSettings; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.GroovyFileType; @@ -48,4 +49,9 @@ public class GroovyCodeStyleSettingsProvider extends CodeStyleSettingsProvider { public String getConfigurableDisplayName() { return "Groovy"; } + + @Override + public CustomCodeStyleSettings createCustomSettings(CodeStyleSettings settings) { + return new GroovyCodeStyleSettings(settings); + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java index d09595567c7e..37062fe0d56a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java @@ -51,7 +51,8 @@ public class GroovyFormattingModelBuilder implements FormattingModelBuilder { ASTNode astNode = containingFile.getNode(); assert astNode != null; CommonCodeStyleSettings groovySettings = settings.getCommonSettings(GroovyFileType.GROOVY_LANGUAGE); - final GroovyBlock block = new GroovyBlock(astNode, null, Indent.getAbsoluteNoneIndent(), null, groovySettings); + GroovyCodeStyleSettings customSettings = settings.getCustomSettings(GroovyCodeStyleSettings.class); + final GroovyBlock block = new GroovyBlock(astNode, null, Indent.getAbsoluteNoneIndent(), null, groovySettings, customSettings); return new GroovyFormattingModel(containingFile, block, FormattingDocumentModelImpl.createOn(containingFile)); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyLanguageCodeStyleSettingsProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyLanguageCodeStyleSettingsProvider.java index 70bfc017167a..595ef4570439 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyLanguageCodeStyleSettingsProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyLanguageCodeStyleSettingsProvider.java @@ -41,6 +41,11 @@ public class GroovyLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSe @Override public void customizeSettings(@NotNull CodeStyleSettingsCustomizable consumer, @NotNull SettingsType settingsType) { + if (settingsType == SettingsType.WRAPPING_AND_BRACES_SETTINGS) { + consumer.showAllStandardOptions(); + consumer.showCustomOption(GroovyCodeStyleSettings.class, "USE_FLYING_GEESE_BRACES", "Use flying geese braces", CodeStyleSettingsCustomizable.WRAPPING_BRACES); + return; + } consumer.showAllStandardOptions(); } @@ -115,6 +120,8 @@ public class GroovyLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSe } }; } + + private final static String INDENT_OPTIONS_SAMPLE = /* diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java index 28088b113e37..c2c40eb4593e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java @@ -42,11 +42,12 @@ public class MethodCallWithoutQualifierBlock extends GroovyBlock { Alignment alignment, Wrap wrap, CommonCodeStyleSettings settings, + GroovyCodeStyleSettings groovySettings, boolean topLevel, List children, PsiElement elem, Map innerAlignments) { - super(nameElement.getNode(), alignment, Indent.getContinuationWithoutFirstIndent(), wrap, settings, innerAlignments); + super(nameElement.getNode(), alignment, Indent.getContinuationWithoutFirstIndent(), wrap, settings, groovySettings, innerAlignments); myNameElement = nameElement; myTopLevel = topLevel; myChildren = children; @@ -58,8 +59,8 @@ public class MethodCallWithoutQualifierBlock extends GroovyBlock { public List getSubBlocks() { if (mySubBlocks == null) { mySubBlocks = new ArrayList(); - mySubBlocks.add(new GroovyBlock(myNameElement.getNode(), myInnerAlignments.get(myNameElement), Indent.getContinuationWithoutFirstIndent(), myWrap, mySettings, myInnerAlignments)); - GroovyBlockGenerator.addNestedChildrenSuffix(mySubBlocks, myAlignment, myWrap, mySettings, myTopLevel, myChildren, myChildren.size(), myInnerAlignments); + mySubBlocks.add(new GroovyBlock(myNameElement.getNode(), myInnerAlignments.get(myNameElement), Indent.getContinuationWithoutFirstIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments)); + GroovyBlockGenerator.addNestedChildrenSuffix(mySubBlocks, myAlignment, myWrap, mySettings, myGroovySettings, myTopLevel, myChildren, myChildren.size(), myInnerAlignments); } return mySubBlocks; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java index ae02f2788dcd..753145205971 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java @@ -22,13 +22,14 @@ import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiIdentifier; import com.intellij.psi.PsiWhiteSpace; -import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.psi.formatter.FormatterUtil; import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.impl.source.tree.CompositeElement; import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.formatter.GeeseUtil; +import org.jetbrains.plugins.groovy.formatter.GroovyCodeStyleSettings; import org.jetbrains.plugins.groovy.lang.editor.actions.GroovyEditorActionUtil; import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.*; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; @@ -78,9 +79,11 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { private Spacing myResult; private ASTNode myChild1; private ASTNode myChild2; + private GroovyCodeStyleSettings myGroovySettings; - public GroovySpacingProcessor(ASTNode node, CommonCodeStyleSettings settings) { + public GroovySpacingProcessor(ASTNode node, CommonCodeStyleSettings settings, GroovyCodeStyleSettings groovySettings) { mySettings = settings; + myGroovySettings = groovySettings; _init(node); @@ -155,7 +158,7 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { public void visitClosure(GrClosableBlock closure) { ASTNode rBraceAtTheEnd = GeeseUtil.getClosureRBraceAtTheEnd(myChild1); - if (mySettings.USE_FLYING_GEESE_BRACES && myChild2.getElementType() == mRCURLY && rBraceAtTheEnd != null) { + if (myGroovySettings.USE_FLYING_GEESE_BRACES && myChild2.getElementType() == mRCURLY && rBraceAtTheEnd != null) { myResult = Spacing.createSpacing(0, 0, 0, true, 100, 0); } else if ((myChild1.getElementType() == mLCURLY && @@ -378,9 +381,7 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); } else if (myChild2.getElementType() == mLPAREN) { createSpaceInCode(mySettings.SPACE_BEFORE_IF_PARENTHESES); - } else if (myChild1.getElementType() == mLPAREN) { - createSpaceInCode(mySettings.SPACE_WITHIN_IF_PARENTHESES); - } else if (myChild2.getElementType() == mRPAREN) { + } else if (myChild1.getElementType() == mLPAREN || myChild2.getElementType() == mRPAREN) { createSpaceInCode(mySettings.SPACE_WITHIN_IF_PARENTHESES); } else if (((GrIfStatement) myParent).getThenBranch() == myChild2.getPsi()) { createSpacingBeforeElementInsideControlStatement(); @@ -419,10 +420,6 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { } } - private void createParenSpace(final boolean onNewLine, final boolean space) { - createParenSpace(onNewLine, space, myParent.getTextRange()); - } - private void createParenSpace(final boolean onNewLine, final boolean space, final TextRange dependance) { if (onNewLine) { final int spaces = space ? 1 : 0; @@ -434,6 +431,7 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { } + @Nullable private static ASTNode findFrom(ASTNode current, final IElementType expected, boolean forward) { while (current != null) { if (current.getElementType() == expected) return current; @@ -466,10 +464,8 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { private void processModifierList(ASTNode modifierList) { - if (modifierList.getLastChildNode().getElementType() == ANNOTATION && mySettings.METHOD_ANNOTATION_WRAP == CodeStyleSettings.WRAP_ALWAYS) { - myResult = Spacing.createSpacing(0, 0, 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); - } - else if (mySettings.MODIFIER_LIST_WRAP) { + if (modifierList.getLastChildNode().getElementType() == ANNOTATION && + mySettings.METHOD_ANNOTATION_WRAP == CommonCodeStyleSettings.WRAP_ALWAYS || mySettings.MODIFIER_LIST_WRAP) { myResult = Spacing.createSpacing(0, 0, 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); } else { @@ -493,11 +489,11 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { myResult = Spacing.createSpacing(space ? 1 : 0, space ? 1 : 0, 0, keepLineBreaks, keepBlankLines); } - private Spacing getSpaceBeforeLBrace(final boolean spaceBeforeLbrace, int braceStyle, TextRange dependantRange, boolean keepOneLine) { - if (dependantRange != null && braceStyle == CodeStyleSettings.NEXT_LINE_IF_WRAPPED) { + private Spacing getSpaceBeforeLBrace(final boolean spaceBeforeLbrace, int braceStyle, @Nullable TextRange dependantRange, boolean keepOneLine) { + if (dependantRange != null && braceStyle == CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED) { int space = spaceBeforeLbrace ? 1 : 0; return createNonLFSpace(space, dependantRange, false); - } else if (braceStyle == CodeStyleSettings.END_OF_LINE || braceStyle == CodeStyleSettings.NEXT_LINE_IF_WRAPPED) { + } else if (braceStyle == CommonCodeStyleSettings.END_OF_LINE || braceStyle == CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED) { int space = spaceBeforeLbrace ? 1 : 0; return createNonLFSpace(space, null, false); } else if (keepOneLine) { @@ -508,7 +504,7 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { } } - private Spacing createNonLFSpace(int spaces, final TextRange dependantRange, final boolean keepLineBreaks) { + private Spacing createNonLFSpace(int spaces, @Nullable final TextRange dependantRange, final boolean keepLineBreaks) { final ASTNode prev = getPrevElementType(myChild2); if (prev != null && prev.getElementType() == mSL_COMMENT) { return Spacing.createSpacing(0, Integer.MAX_VALUE, 1, keepLineBreaks, mySettings.KEEP_BLANK_LINES_IN_CODE); @@ -523,6 +519,7 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { return treePrev != null && (treePrev.getPsi() instanceof PsiWhiteSpace || treePrev.getTextLength() == 0); } + @Nullable static ASTNode getPrevElementType(final ASTNode child) { return FormatterUtil.getPreviousNonWhitespaceLeaf(child); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/GroovyEnterHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/GroovyEnterHandler.java index 8e3fb4b95211..f67acc08ce8f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/GroovyEnterHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/GroovyEnterHandler.java @@ -35,11 +35,11 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.formatter.GeeseUtil; +import org.jetbrains.plugins.groovy.formatter.GroovyCodeStyleSettings; import org.jetbrains.plugins.groovy.lang.editor.HandlerUtils; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; @@ -141,7 +141,8 @@ public class GroovyEnterHandler extends EnterHandlerDelegateAdapter { Project project = PlatformDataKeys.PROJECT.getData(dataContext); if (project == null) return false; - CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project); + GroovyCodeStyleSettings codeStyleSettings = + CodeStyleSettingsManager.getSettings(project).getCustomSettings(GroovyCodeStyleSettings.class); if (!codeStyleSettings.USE_FLYING_GEESE_BRACES) return false; PsiElement element = file.findElementAt(caretOffset); From 8ecde501edf006fd1b38b76a74ff9f529a6bef95 Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Thu, 20 Oct 2011 15:41:27 +0400 Subject: [PATCH 115/128] refactor GroovyBlockGenerator --- .../codeStyle/CommonCodeStyleSettings.java | 2 +- .../plugins/groovy/formatter/GroovyBlock.java | 10 +- .../formatter/GroovyBlockGenerator.java | 169 ++++++++---------- .../MethodCallWithoutQualifierBlock.java | 2 +- 4 files changed, 90 insertions(+), 93 deletions(-) diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java index 6ef026460f4c..5c81fc666951 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2011 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. diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java index c400cc906deb..22474d4d63c0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java @@ -116,6 +116,14 @@ public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { return mySettings; } + public GroovyCodeStyleSettings getGroovySettings() { + return myGroovySettings; + } + + public Map getInnerAlignments() { + return myInnerAlignments; + } + @NotNull public TextRange getTextRange() { return myNode.getTextRange(); @@ -124,7 +132,7 @@ public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { @NotNull public List getSubBlocks() { if (mySubBlocks == null) { - mySubBlocks = GroovyBlockGenerator.generateSubBlocks(myNode, myAlignment, myWrap, mySettings, myGroovySettings, this); + mySubBlocks = new GroovyBlockGenerator(this).generateSubBlocks(); } return mySubBlocks; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java index 185f8576b2c4..3a8a0ba4ada8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java @@ -76,96 +76,110 @@ public class GroovyBlockGenerator implements GroovyElementTypes { private static final Logger LOG = Logger.getInstance(GroovyBlockGenerator.class); + private final GroovyBlock myBlock; + private final ASTNode myNode; + private final Alignment myAlignment; + private final Wrap myWrap; + private final CommonCodeStyleSettings mySettings; + private final Map myInnerAlignments; + private final GroovyCodeStyleSettings myGroovySettings; + + public GroovyBlockGenerator(GroovyBlock block) { + this.myBlock = block; + myNode = myBlock.getNode(); + myAlignment = myBlock.getAlignment(); + myWrap = myBlock.getWrap(); + mySettings = myBlock.getSettings(); + myInnerAlignments = myBlock.getInnerAlignments(); + myGroovySettings = myBlock.getGroovySettings(); + } + + + public List generateSubBlocks() { - public static List generateSubBlocks(ASTNode node, - Alignment myAlignment, - Wrap myWrap, - CommonCodeStyleSettings mySettings, - GroovyCodeStyleSettings groovySettings, - GroovyBlock block) { //For binary expressions - PsiElement blockPsi = block.getNode().getPsi(); - Map alignments = block.myInnerAlignments; - - if (blockPsi instanceof GrBinaryExpression && - !(blockPsi.getParent() instanceof GrBinaryExpression)) { - return generateForBinaryExpr(node, myWrap, mySettings, groovySettings, alignments); + PsiElement blockPsi = myNode.getPsi(); + + if (blockPsi instanceof GrBinaryExpression && !(blockPsi.getParent() instanceof GrBinaryExpression)) { + return generateForBinaryExpr(); } //For multiline strings - if ((block.getNode().getElementType() == mSTRING_LITERAL || - block.getNode().getElementType() == mGSTRING_LITERAL) && - block.getTextRange().equals(block.getNode().getTextRange())) { - String text = block.getNode().getText(); + if ((myNode.getElementType() == mSTRING_LITERAL || myNode.getElementType() == mGSTRING_LITERAL) && + myBlock.getTextRange().equals(myNode.getTextRange())) { + String text = myNode.getText(); if (text.length() > 6) { if (text.substring(0, 3).equals("'''") && text.substring(text.length() - 3).equals("'''") || text.substring(0, 3).equals("\"\"\"") & text.substring(text.length() - 3).equals("\"\"\"")) { - return generateForMultiLineString(block.getNode(), myAlignment, myWrap, mySettings, groovySettings, alignments); + return generateForMultiLineString(myNode, myAlignment, myWrap, mySettings, myGroovySettings, myInnerAlignments); } } } - if (block.getNode().getElementType() == mGSTRING_BEGIN && - block.getTextRange().equals(block.getNode().getTextRange())) { - String text = block.getNode().getText(); + if (myNode.getElementType() == mGSTRING_BEGIN && + myBlock.getTextRange().equals(myNode.getTextRange())) { + String text = myNode.getText(); if (text.length() > 3) { if (text.substring(0, 3).equals("\"\"\"")) { - return generateForMultiLineGStringBegin(block.getNode(), myAlignment, myWrap, mySettings, groovySettings, alignments); + return generateForMultiLineGStringBegin(myNode, myAlignment, myWrap, mySettings, myGroovySettings, myInnerAlignments); } } } //for gstrings - if (block.getNode().getElementType() == GSTRING) { + if (myNode.getElementType() == GSTRING) { final ArrayList subBlocks = new ArrayList(); - ASTNode[] children = getGroovyChildren(node); + ASTNode[] children = getGroovyChildren(myNode); for (ASTNode childNode : children) { if (childNode.getTextRange().getLength() > 0) { - final Indent indent = GroovyIndentProcessor.getChildIndent(block, childNode); - subBlocks.add(new GroovyBlock(childNode, myAlignment, indent, myWrap, mySettings, groovySettings, alignments)); + final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); + subBlocks.add(new GroovyBlock(childNode, myAlignment, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } } return subBlocks; } // chained properties, calls, indexing, etc - if (NESTED.contains(block.getNode().getElementType()) && blockPsi.getParent() != null && !NESTED.contains(blockPsi.getParent().getNode().getElementType())) { + if (NESTED.contains(myNode.getElementType()) && blockPsi.getParent() != null && !NESTED.contains(blockPsi.getParent().getNode().getElementType())) { final List subBlocks = new ArrayList(); Alignment dotsAlignment = mySettings.ALIGN_MULTILINE_CHAINED_METHODS ? Alignment.createAlignment() : null; - addNestedChildren(node.getPsi(), subBlocks, dotsAlignment, myWrap, mySettings, groovySettings, true, alignments); + addNestedChildren(myNode.getPsi(), subBlocks, dotsAlignment, true); return subBlocks; } // For Parameter lists if (isListLikeClause(blockPsi)) { final ArrayList subBlocks = new ArrayList(); - List astNodes = visibleChildren(node); - final Alignment alignment = mustAlign(blockPsi, mySettings, astNodes) ? Alignment.createAlignment() : null; + List astNodes = visibleChildren(myNode); + final Alignment newAlignment = mustAlign(blockPsi, mySettings, astNodes) ? Alignment.createAlignment() : null; for (ASTNode childNode : astNodes) { - final Indent indent = GroovyIndentProcessor.getChildIndent(block, childNode); - subBlocks.add(new GroovyBlock(childNode, isKeyword(childNode) ? null : alignment, indent, myWrap, mySettings, groovySettings, alignments)); + final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); + subBlocks.add(new GroovyBlock(childNode, isKeyword(childNode) ? null : newAlignment, indent, myWrap, mySettings, myGroovySettings, + myInnerAlignments)); } return subBlocks; } boolean classLevel = blockPsi instanceof GrTypeDefinitionBody; if (blockPsi instanceof GrCodeBlock || blockPsi instanceof GroovyFile || classLevel) { - List children = visibleChildren(node); - calculateAlignments(children, classLevel, mySettings, alignments); + List children = visibleChildren(myNode); + calculateAlignments(children, classLevel, mySettings, myInnerAlignments); final ArrayList subBlocks = new ArrayList(); for (ASTNode childNode : children) { - final Indent indent = GroovyIndentProcessor.getChildIndent(block, childNode); - subBlocks.add(new GroovyBlock(childNode, classLevel ? myAlignment : alignments.get(childNode.getPsi()), indent, myWrap, mySettings, groovySettings, alignments)); + final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); + Alignment alignmentToUse = classLevel ? myAlignment : myInnerAlignments.get(childNode.getPsi()); + subBlocks.add(new GroovyBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } return subBlocks; } // For other cases final ArrayList subBlocks = new ArrayList(); - for (ASTNode childNode : visibleChildren(node)) { - final Indent indent = GroovyIndentProcessor.getChildIndent(block, childNode); - subBlocks.add(new GroovyBlock(childNode, alignments.get(childNode.getPsi()), indent, myWrap, mySettings, groovySettings, alignments)); + for (ASTNode childNode : visibleChildren(myNode)) { + final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); + subBlocks.add(new GroovyBlock(childNode, myInnerAlignments.get(childNode.getPsi()), indent, myWrap, mySettings, myGroovySettings, + myInnerAlignments)); } return subBlocks; } @@ -398,21 +412,15 @@ public class GroovyBlockGenerator implements GroovyElementTypes { * Generates blocks for binary expressions * * @return - * @param node - * @param groovySettings */ - private static List generateForBinaryExpr(final ASTNode node, - Wrap myWrap, - CommonCodeStyleSettings mySettings, - GroovyCodeStyleSettings groovySettings, Map alignments) { + private List generateForBinaryExpr() { final ArrayList subBlocks = new ArrayList(); Alignment alignment = mySettings.ALIGN_MULTILINE_BINARY_OPERATION ? Alignment.createAlignment() : null; - - GrBinaryExpression binary = (GrBinaryExpression) node.getPsi(); + GrBinaryExpression binary = (GrBinaryExpression)myNode.getPsi(); LOG.assertTrue(binary != null); - addBinaryChildrenRecursively(binary, subBlocks, Indent.getContinuationWithoutFirstIndent(), alignment, myWrap, mySettings, - groovySettings, alignments); + addBinaryChildrenRecursively(binary, subBlocks, Indent.getContinuationWithoutFirstIndent(), alignment + ); return subBlocks; } @@ -423,45 +431,36 @@ public class GroovyBlockGenerator implements GroovyElementTypes { * @param list * @param indent * @param alignment - * @param groovySettings */ - private static void addBinaryChildrenRecursively(PsiElement elem, - List list, - Indent indent, - Alignment alignment, - Wrap myWrap, - CommonCodeStyleSettings mySettings, - GroovyCodeStyleSettings groovySettings, Map alignments) { + private void addBinaryChildrenRecursively(PsiElement elem, List list, Indent indent, Alignment alignment) { if (elem == null) return; // For binary expressions if ((elem instanceof GrBinaryExpression)) { GrBinaryExpression myExpr = ((GrBinaryExpression) elem); if (myExpr.getLeftOperand() instanceof GrBinaryExpression) { - addBinaryChildrenRecursively(myExpr.getLeftOperand(), list, Indent.getContinuationWithoutFirstIndent(), alignment, myWrap, mySettings, - groovySettings, alignments); + addBinaryChildrenRecursively(myExpr.getLeftOperand(), list, Indent.getContinuationWithoutFirstIndent(), alignment + ); } PsiElement op = ((GrBinaryExpression)elem).getOperationToken(); for (ASTNode childNode : visibleChildren(elem.getNode())) { PsiElement psi = childNode.getPsi(); if (!(psi instanceof GrBinaryExpression)) { - list.add(new GroovyBlock(childNode, op == psi ? alignments.get(op) : alignment, indent, myWrap, mySettings, groovySettings, alignments)); + Alignment alignmentToUse = op == psi ? myInnerAlignments.get(op) : alignment; + list.add(new GroovyBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } } if (myExpr.getRightOperand() instanceof GrBinaryExpression) { - addBinaryChildrenRecursively(myExpr.getRightOperand(), list, Indent.getContinuationWithoutFirstIndent(), alignment, myWrap, - mySettings, groovySettings, alignments); + addBinaryChildrenRecursively(myExpr.getRightOperand(), list, Indent.getContinuationWithoutFirstIndent(), alignment + ); } } } - private static void addNestedChildren(final PsiElement elem, + private void addNestedChildren(final PsiElement elem, List list, @Nullable final Alignment alignment, - final Wrap wrap, - final CommonCodeStyleSettings settings, - GroovyCodeStyleSettings groovySettings, final boolean topLevel, - Map alignments) { + final boolean topLevel) { final List children = visibleChildren(elem.getNode()); if (elem instanceof GrMethodCallExpression) { GrExpression invokedExpression = ((GrMethodCallExpression)elem).getInvokedExpression(); @@ -472,11 +471,11 @@ public class GroovyBlockGenerator implements GroovyElementTypes { int i = 0; while (i < grandChildren.size() && nameElement != grandChildren.get(i).getPsi()) { i++; } if (i > 0) { - processNestedChildrenPrefix(list, alignment, wrap, settings, groovySettings, false, grandChildren, i, alignments); + processNestedChildrenPrefix(list, alignment, false, grandChildren, i); } if (i < grandChildren.size()) { LOG.assertTrue(nameElement == grandChildren.get(i).getPsi()); - list.add(new MethodCallWithoutQualifierBlock(nameElement, null, wrap, settings, groovySettings, topLevel, children, elem, alignments)); + list.add(new MethodCallWithoutQualifierBlock(nameElement, null, myWrap, mySettings, myGroovySettings, topLevel, children, elem, myInnerAlignments)); } return; } @@ -485,41 +484,31 @@ public class GroovyBlockGenerator implements GroovyElementTypes { } - processNestedChildrenPrefix(list, alignment, wrap, settings, groovySettings, topLevel, children, children.size(), alignments); + processNestedChildrenPrefix(list, alignment, topLevel, children, children.size()); } - private static void processNestedChildrenPrefix(List list, - Alignment alignment, - Wrap wrap, - CommonCodeStyleSettings settings, - GroovyCodeStyleSettings groovySettings, boolean topLevel, - List children, - int limit, - Map alignments) { + private void processNestedChildrenPrefix(List list, Alignment alignment, boolean topLevel, List children, int limit) { ASTNode fst = children.get(0); LOG.assertTrue(limit > 0); if (NESTED.contains(fst.getElementType())) { - addNestedChildren(fst.getPsi(), list, alignment, wrap, settings, groovySettings, false, alignments); - } else { - list.add(new GroovyBlock(fst, alignments.get(fst.getPsi()), Indent.getContinuationWithoutFirstIndent(), wrap, settings, groovySettings, alignments)); + addNestedChildren(fst.getPsi(), list, alignment, false); } - addNestedChildrenSuffix(list, alignment, wrap, settings, groovySettings, topLevel, children, limit, alignments); + else { + Alignment alignmentToUse = myInnerAlignments.get(fst.getPsi()); + Indent indent = Indent.getContinuationWithoutFirstIndent(); + list.add(new GroovyBlock(fst, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); + } + addNestedChildrenSuffix(list, alignment, topLevel, children, limit); } - static void addNestedChildrenSuffix(List list, - Alignment alignment, - Wrap wrap, - CommonCodeStyleSettings settings, - GroovyCodeStyleSettings groovySettings, boolean topLevel, - List children, - int limit, - Map alignments) { + void addNestedChildrenSuffix(List list, Alignment alignment, boolean topLevel, List children, int limit) { for (int i = 1; i < limit; i++) { ASTNode childNode = children.get(i); if (canBeCorrectBlock(childNode)) { IElementType type = childNode.getElementType(); Indent indent = topLevel || NESTED.contains(type) || type == mIDENT ? Indent.getContinuationWithoutFirstIndent() : Indent.getNoneIndent(); - list.add(new GroovyBlock(childNode, TokenSets.DOTS.contains(type) ? alignment : alignments.get(childNode.getPsi()), indent, wrap, settings, groovySettings, alignments)); + Alignment alignmentToUse = TokenSets.DOTS.contains(type) ? alignment : myInnerAlignments.get(childNode.getPsi()); + list.add(new GroovyBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java index c2c40eb4593e..787878b408a4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java @@ -60,7 +60,7 @@ public class MethodCallWithoutQualifierBlock extends GroovyBlock { if (mySubBlocks == null) { mySubBlocks = new ArrayList(); mySubBlocks.add(new GroovyBlock(myNameElement.getNode(), myInnerAlignments.get(myNameElement), Indent.getContinuationWithoutFirstIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments)); - GroovyBlockGenerator.addNestedChildrenSuffix(mySubBlocks, myAlignment, myWrap, mySettings, myGroovySettings, myTopLevel, myChildren, myChildren.size(), myInnerAlignments); + new GroovyBlockGenerator(this).addNestedChildrenSuffix(mySubBlocks, myAlignment, myTopLevel, myChildren, myChildren.size()); } return mySubBlocks; } From 5bc0520bf558aca7ee1bc80993611f0f6726db40 Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Fri, 21 Oct 2011 09:43:55 +0400 Subject: [PATCH 116/128] intentions for brace formatting --- .../after.groovy.template | 17 +++ .../before.groovy.template | 15 ++ .../description.html | 5 + .../after.groovy.template | 15 ++ .../before.groovy.template | 17 +++ .../description.html | 5 + plugins/groovy/src/META-INF/plugin.xml | 10 ++ .../processors/GroovySpacingProcessor.java | 4 +- .../GroovyIntentionsBundle.properties | 5 + .../groovy/intentions/base/Intention.java | 6 +- .../ConvertFromGeeseBracesIntention.java | 137 ++++++++++++++++++ .../style/ConvertToGeeseBracesIntention.java | 129 +++++++++++++++++ 12 files changed, 359 insertions(+), 6 deletions(-) create mode 100644 plugins/groovy/resources/intentionDescriptions/ConvertFromGeeseBracesIntention/after.groovy.template create mode 100644 plugins/groovy/resources/intentionDescriptions/ConvertFromGeeseBracesIntention/before.groovy.template create mode 100644 plugins/groovy/resources/intentionDescriptions/ConvertFromGeeseBracesIntention/description.html create mode 100644 plugins/groovy/resources/intentionDescriptions/ConvertToGeeseBracesIntention/after.groovy.template create mode 100644 plugins/groovy/resources/intentionDescriptions/ConvertToGeeseBracesIntention/before.groovy.template create mode 100644 plugins/groovy/resources/intentionDescriptions/ConvertToGeeseBracesIntention/description.html create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ConvertFromGeeseBracesIntention.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ConvertToGeeseBracesIntention.java diff --git a/plugins/groovy/resources/intentionDescriptions/ConvertFromGeeseBracesIntention/after.groovy.template b/plugins/groovy/resources/intentionDescriptions/ConvertFromGeeseBracesIntention/after.groovy.template new file mode 100644 index 000000000000..925d3cbaa215 --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/ConvertFromGeeseBracesIntention/after.groovy.template @@ -0,0 +1,17 @@ +swing.edt { + frame(title:'Frame', defaultCloseOperation:JFrame.EXIT_ON_CLOSE, pack:true, show:true) { + vbox { + textlabel = label("Click the button!") + button( + text:'Click Me', + actionPerformed: { + count++ + textlabel.text = "Clicked ${count} time(s)." + println "Clicked!" + } + ) + widget(sharedPanel()) + widget(sharedPanel()) + } + } +} \ No newline at end of file diff --git a/plugins/groovy/resources/intentionDescriptions/ConvertFromGeeseBracesIntention/before.groovy.template b/plugins/groovy/resources/intentionDescriptions/ConvertFromGeeseBracesIntention/before.groovy.template new file mode 100644 index 000000000000..9174be1584aa --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/ConvertFromGeeseBracesIntention/before.groovy.template @@ -0,0 +1,15 @@ +swing.edt { + frame(title:'Frame', defaultCloseOperation:JFrame.EXIT_ON_CLOSE, pack:true, show:true) { + vbox { + textlabel = label("Click the button!") + button( + text:'Click Me', + actionPerformed: { + count++ + textlabel.text = "Clicked ${count} time(s)." + println "Clicked!" + } + ) + widget(sharedPanel()) + widget(sharedPanel()) +} } } \ No newline at end of file diff --git a/plugins/groovy/resources/intentionDescriptions/ConvertFromGeeseBracesIntention/description.html b/plugins/groovy/resources/intentionDescriptions/ConvertFromGeeseBracesIntention/description.html new file mode 100644 index 000000000000..9472bb1469d5 --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/ConvertFromGeeseBracesIntention/description.html @@ -0,0 +1,5 @@ + + +This intention formats sequence of closing closure braces in separate lines + + \ No newline at end of file diff --git a/plugins/groovy/resources/intentionDescriptions/ConvertToGeeseBracesIntention/after.groovy.template b/plugins/groovy/resources/intentionDescriptions/ConvertToGeeseBracesIntention/after.groovy.template new file mode 100644 index 000000000000..9174be1584aa --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/ConvertToGeeseBracesIntention/after.groovy.template @@ -0,0 +1,15 @@ +swing.edt { + frame(title:'Frame', defaultCloseOperation:JFrame.EXIT_ON_CLOSE, pack:true, show:true) { + vbox { + textlabel = label("Click the button!") + button( + text:'Click Me', + actionPerformed: { + count++ + textlabel.text = "Clicked ${count} time(s)." + println "Clicked!" + } + ) + widget(sharedPanel()) + widget(sharedPanel()) +} } } \ No newline at end of file diff --git a/plugins/groovy/resources/intentionDescriptions/ConvertToGeeseBracesIntention/before.groovy.template b/plugins/groovy/resources/intentionDescriptions/ConvertToGeeseBracesIntention/before.groovy.template new file mode 100644 index 000000000000..925d3cbaa215 --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/ConvertToGeeseBracesIntention/before.groovy.template @@ -0,0 +1,17 @@ +swing.edt { + frame(title:'Frame', defaultCloseOperation:JFrame.EXIT_ON_CLOSE, pack:true, show:true) { + vbox { + textlabel = label("Click the button!") + button( + text:'Click Me', + actionPerformed: { + count++ + textlabel.text = "Clicked ${count} time(s)." + println "Clicked!" + } + ) + widget(sharedPanel()) + widget(sharedPanel()) + } + } +} \ No newline at end of file diff --git a/plugins/groovy/resources/intentionDescriptions/ConvertToGeeseBracesIntention/description.html b/plugins/groovy/resources/intentionDescriptions/ConvertToGeeseBracesIntention/description.html new file mode 100644 index 000000000000..10d099ac12b6 --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/ConvertToGeeseBracesIntention/description.html @@ -0,0 +1,5 @@ + + +This intention formats sequence of closing closure braces in one line ("geese braces style") + + \ No newline at end of file diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 3020361877f5..f59572ccf4f3 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -904,6 +904,16 @@ intention.category.groovy/intention.category.groovy.style org.jetbrains.plugins.groovy.intentions.style.ImportOnDemandIntention + + org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle + intention.category.groovy/intention.category.groovy.style + org.jetbrains.plugins.groovy.intentions.style.ConvertToGeeseBracesIntention + + + org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle + intention.category.groovy/intention.category.groovy.style + org.jetbrains.plugins.groovy.intentions.style.ConvertFromGeeseBracesIntention + org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle intention.category.groovy/intention.category.groovy.style diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java index 753145205971..bee01f4f655c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java @@ -515,8 +515,8 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { } } - static boolean isWhiteSpace(final ASTNode treePrev) { - return treePrev != null && (treePrev.getPsi() instanceof PsiWhiteSpace || treePrev.getTextLength() == 0); + static boolean isWhiteSpace(final ASTNode node) { + return node != null && (node.getPsi() instanceof PsiWhiteSpace || node.getTextLength() == 0); } @Nullable diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties index 776d356f7e4a..3686471ed8dd 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties @@ -129,3 +129,8 @@ replace.qualified.reference.with.import.intention.name=Replace with import replace.qualified.reference.with.import.intention.family.name=Replace qualified reference with import move.to.correct.dir.family.name=Move File to Correct Package move.to.correct.dir=Move to ''{0}'' +convert.to.geese.braces.intention.name=Use geese braces +convert.to.geese.braces.intention.family.name=Use geese braces for nested closures + +convert.from.geese.braces.intention.name=Format braces in separate lines +convert.from.geese.braces.intention.family.name=Format braces in separate lines diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/Intention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/Intention.java index acc7691449a5..26eedcb4c598 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/Intention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/Intention.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.jetbrains.plugins.groovy.intentions.base; import com.intellij.codeInsight.intention.IntentionAction; -import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; @@ -42,8 +41,7 @@ public abstract class Intention implements IntentionAction { predicate = getElementPredicate(); } - public void invoke(@NotNull Project project, Editor editor, PsiFile file) - throws IncorrectOperationException { + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { if (!QuickfixUtil.ensureFileWritable(project, file)) { return; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ConvertFromGeeseBracesIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ConvertFromGeeseBracesIntention.java new file mode 100644 index 000000000000..6296ad1e928a --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ConvertFromGeeseBracesIntention.java @@ -0,0 +1,137 @@ +/* + * Copyright 2000-2011 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.intentions.style; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.formatter.GeeseUtil; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; +import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; + +/** + * @author Max Medvedev + */ +public class ConvertFromGeeseBracesIntention extends Intention { + private static final Logger LOG = Logger.getInstance(ConvertFromGeeseBracesIntention.class); + + private static final PsiElementPredicate MY_PREDICATE = new PsiElementPredicate() { + @Override + public boolean satisfiedBy(PsiElement element) { + IElementType elementType = element.getNode().getElementType(); + if (TokenSets.WHITE_SPACES_SET.contains(elementType)) { + element = PsiTreeUtil.prevLeaf(element); + } + + if (!GeeseUtil.isClosureRBrace(element)) return false; + + String text = element.getContainingFile().getText(); + + PsiElement first = element; + PsiElement last = element; + for (PsiElement cur = getNext(element); GeeseUtil.isClosureRBrace(cur); cur = getNext(cur)) { + if (!StringUtil.contains(text, last.getTextRange().getEndOffset(), cur.getTextRange().getStartOffset(), '\n')) return true; + last = cur; + } + + for (PsiElement cur = getPrev(element); GeeseUtil.isClosureRBrace(cur); cur = getPrev(cur)) { + if (!StringUtil.contains(text, cur.getTextRange().getEndOffset(), first.getTextRange().getStartOffset(), '\n')) return true; + first = cur; + } + + return false; + } + }; + + @Nullable + private static PsiElement getPrev(PsiElement element) { + PsiElement prev = GeeseUtil.getPreviousNonWhitespaceToken(element); + if (prev != null && prev.getNode().getElementType() == GroovyTokenTypes.mNLS) { + prev = GeeseUtil.getPreviousNonWhitespaceToken(prev); + } + return prev; + } + + @Nullable + private static PsiElement getNext(PsiElement element) { + PsiElement next = GeeseUtil.getNextNonWhitespaceToken(element); + if (next != null && next.getNode().getElementType() == GroovyTokenTypes.mNLS) next = GeeseUtil.getNextNonWhitespaceToken(next); + return next; + } + + @Override + protected void processIntention(PsiElement element, Project project, Editor editor) throws IncorrectOperationException { + IElementType elementType = element.getNode().getElementType(); + if (TokenSets.WHITE_SPACES_SET.contains(elementType)) { + element = PsiTreeUtil.prevLeaf(element); + } + LOG.assertTrue(GeeseUtil.isClosureRBrace(element)); + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + PsiFile file = element.getContainingFile(); + Document document = PsiDocumentManager.getInstance(project).getDocument(file); + + PsiElement first = null; + PsiElement last = null; + for (PsiElement cur = element; GeeseUtil.isClosureRBrace(cur); cur = getNext(cur)) { + last = cur; + } + + for (PsiElement cur = element; GeeseUtil.isClosureRBrace(cur); cur = getPrev(cur)) { + first = cur; + } + + LOG.assertTrue(first != null); + LOG.assertTrue(last != null); + + + RangeMarker rangeMarker = document.createRangeMarker(first.getTextRange().getStartOffset(), last.getTextRange().getEndOffset()); + + String text = document.getText(); + for (PsiElement cur = getPrev(last); GeeseUtil.isClosureRBrace(cur); cur = getPrev(cur)) { + int offset = last.getTextRange().getStartOffset(); + if (!StringUtil.contains(text, cur.getTextRange().getEndOffset(), offset, '\n')) { + document.insertString(offset, "\n"); + } + last = cur; + } + + + CodeStyleManager.getInstance(project).reformatText(file, rangeMarker.getStartOffset(), rangeMarker.getEndOffset()); + } + + + @NotNull + @Override + protected PsiElementPredicate getElementPredicate() { + return MY_PREDICATE; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ConvertToGeeseBracesIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ConvertToGeeseBracesIntention.java new file mode 100644 index 000000000000..cae36f17c79e --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ConvertToGeeseBracesIntention.java @@ -0,0 +1,129 @@ +/* + * Copyright 2000-2011 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.intentions.style; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.formatter.GeeseUtil; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; +import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; + +/** + * @author Max Medvedev + */ +public class ConvertToGeeseBracesIntention extends Intention { + private static final Logger LOG = Logger.getInstance(ConvertToGeeseBracesIntention.class); + + private static final PsiElementPredicate MY_PREDICATE = new PsiElementPredicate() { + @Override + public boolean satisfiedBy(PsiElement element) { + IElementType elementType = element.getNode().getElementType(); + if (TokenSets.WHITE_SPACES_SET.contains(elementType)) { + element = PsiTreeUtil.prevLeaf(element); + } + + if (!GeeseUtil.isClosureRBrace(element)) return false; + + TextRange range = findRange(element); + + return StringUtil.contains(element.getContainingFile().getText(), range.getStartOffset(), range.getEndOffset(), '\n'); + } + }; + + @Nullable + private static PsiElement getPrev(PsiElement element) { + PsiElement prev = GeeseUtil.getPreviousNonWhitespaceToken(element); + if (prev != null && prev.getNode().getElementType() == GroovyTokenTypes.mNLS) { + prev = GeeseUtil.getPreviousNonWhitespaceToken(prev); + } + return prev; + } + + @Nullable + private static PsiElement getNext(PsiElement element) { + PsiElement next = GeeseUtil.getNextNonWhitespaceToken(element); + if (next != null && next.getNode().getElementType() == GroovyTokenTypes.mNLS) next = GeeseUtil.getNextNonWhitespaceToken(next); + return next; + } + + @Override + protected void processIntention(PsiElement element, Project project, Editor editor) throws IncorrectOperationException { + IElementType elementType = element.getNode().getElementType(); + if (TokenSets.WHITE_SPACES_SET.contains(elementType)) { + element = PsiTreeUtil.prevLeaf(element); + } + LOG.assertTrue(GeeseUtil.isClosureRBrace(element)); + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + PsiFile file = element.getContainingFile(); + Document document = PsiDocumentManager.getInstance(project).getDocument(file); + + TextRange textRange = findRange(element); + int startOffset = textRange.getStartOffset(); + int endOffset = textRange.getEndOffset(); + + RangeMarker rangeMarker = document.createRangeMarker(textRange); + + String text = document.getText(); + for (int i = endOffset - 1; i >= startOffset; i--) { + if (text.charAt(i) == '\n') document.deleteString(i, i + 1); + } + + CodeStyleManager.getInstance(project).reformatText(file, rangeMarker.getStartOffset(), rangeMarker.getEndOffset()); + } + + private static TextRange findRange(PsiElement element) { + PsiElement first = null; + PsiElement last = null; + for (PsiElement cur = element; GeeseUtil.isClosureRBrace(cur); cur = getNext(cur)) { + last = cur; + } + + for (PsiElement cur = element; GeeseUtil.isClosureRBrace(cur); cur = getPrev(cur)) { + first = cur; + } + + LOG.assertTrue(first != null); + LOG.assertTrue(last != null); + + + return new TextRange(first.getTextRange().getStartOffset(), last.getTextRange().getEndOffset()); + } + + + @NotNull + @Override + protected PsiElementPredicate getElementPredicate() { + return MY_PREDICATE; + } +} From 48be696fb65e705693cf76c20dc83fdb0c6307c0 Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Fri, 21 Oct 2011 09:51:56 +0400 Subject: [PATCH 117/128] simpler name for formatting intention --- .../groovy/intentions/GroovyIntentionsBundle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties index 3686471ed8dd..79465d00188e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties @@ -129,8 +129,8 @@ replace.qualified.reference.with.import.intention.name=Replace with import replace.qualified.reference.with.import.intention.family.name=Replace qualified reference with import move.to.correct.dir.family.name=Move File to Correct Package move.to.correct.dir=Move to ''{0}'' -convert.to.geese.braces.intention.name=Use geese braces -convert.to.geese.braces.intention.family.name=Use geese braces for nested closures +convert.to.geese.braces.intention.name=Format braces in one line +convert.to.geese.braces.intention.family.name=Format closing closure braces in one line convert.from.geese.braces.intention.name=Format braces in separate lines convert.from.geese.braces.intention.family.name=Format braces in separate lines From 63abcdc97d5805fd5b5eb87506e961e813e77d25 Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Fri, 21 Oct 2011 12:46:13 +0400 Subject: [PATCH 118/128] fix toString templates. Default template should overload a user's one with the same name --- .../tostring/template/DefaultBuffer.vm | 2 +- .../tostring/template/DefaultBuilder.vm | 2 +- .../tostring/template/TemplatesManager.java | 21 +++++++++++++------ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/DefaultBuffer.vm b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/DefaultBuffer.vm index 24906bdbffb1..7c4f30828d8b 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/DefaultBuffer.vm +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/DefaultBuffer.vm @@ -17,7 +17,7 @@ $member.name=")## #if ($member.primitiveArray) .append($member.name == null ? "null" : ""); for (int i = 0; $member.name != null && i < $member.name .length; ++i) - sb.append(i == 0 ? "" : ", ").append($member.name[i]); + sb.append(i == 0 ? "" : ", ").append($member.name[$i]); #elseif ($member.objectArray) .append($member.name == null ? "null" : Arrays.asList($member.name).toString()); #elseif ($member.string) diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/DefaultBuilder.vm b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/DefaultBuilder.vm index 2654d0ce945a..e424555dbf64 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/DefaultBuilder.vm +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/DefaultBuilder.vm @@ -17,7 +17,7 @@ $member.name=")## #if ($member.primitiveArray) .append($member.name == null ? "null" : ""); for (int i = 0; $member.name != null && i < $member.name .length; ++i) - sb.append(i == 0 ? "" : ", ").append($member.name[i]); + sb.append(i == 0 ? "" : ", ").append($member.name[$i]); #elseif ($member.objectArray) .append($member.name == null ? "null" : Arrays.asList($member.name).toString()); #elseif ($member.string) diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/TemplatesManager.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/TemplatesManager.java index 1cc2e591612d..5ac07766aeb3 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/TemplatesManager.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/TemplatesManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 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. @@ -69,13 +69,22 @@ public class TemplatesManager implements PersistentStateComponent getAllTemplates() { - Collection templates = new LinkedHashSet(Arrays.asList(TemplateResourceLocator.getDefaultTemplates())); - templates.addAll(myState.templates); - return templates; + public Collection getAllTemplates() { + TemplateResource[] defaultTemplates = TemplateResourceLocator.getDefaultTemplates(); + HashSet names = new HashSet(); + for (TemplateResource defaultTemplate : defaultTemplates) { + names.add(defaultTemplate.getFileName()); } + Collection templates = new LinkedHashSet(Arrays.asList(defaultTemplates)); + for (TemplateResource template : myState.templates) { + if (!names.contains(template.getFileName())) { + templates.add(template); + } + } + return templates; + } - public TemplateResource getDefaultTemplate() { + public TemplateResource getDefaultTemplate() { for (TemplateResource template : getAllTemplates()) { if (Comparing.equal(template.getFileName(), myState.defaultTempalteName)) { return template; From aa9b3b1b65e822640ea25af14f923b39d0d782f6 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Thu, 20 Oct 2011 16:04:21 +0400 Subject: [PATCH 119/128] diagnostics --- .../core-api/src/com/intellij/psi/PsiElementResolveResult.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/core-api/src/com/intellij/psi/PsiElementResolveResult.java b/platform/core-api/src/com/intellij/psi/PsiElementResolveResult.java index 2479e4c6852d..dc07cd2cb3ed 100644 --- a/platform/core-api/src/com/intellij/psi/PsiElementResolveResult.java +++ b/platform/core-api/src/com/intellij/psi/PsiElementResolveResult.java @@ -68,7 +68,8 @@ public class PsiElementResolveResult implements ResolveResult{ @NonNls public String toString() { - return "PsiElementResolveResult: " + (myElement instanceof PsiNamedElement ? ((PsiNamedElement)myElement).getName() : myElement.getText()); + return "PsiElementResolveResult with " + myElement.getClass() + ": " + + (myElement instanceof PsiNamedElement ? ((PsiNamedElement)myElement).getName() : myElement.getText()); } public static ResolveResult[] createResults(@Nullable Collection elements) { From cf9bf0e52ccfe85d6fffb39c00d0deb9a9065370 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Thu, 20 Oct 2011 19:54:36 +0400 Subject: [PATCH 120/128] Improve class loading in GroovyMethodInfo. --- .../extensions/GroovyMethodDescriptor.java | 6 ++-- .../groovy/extensions/GroovyMethodInfo.java | 8 +++-- .../groovy/util/ClassInstanceCache.java | 35 ++++--------------- 3 files changed, 14 insertions(+), 35 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodDescriptor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodDescriptor.java index d2b2b2338f1a..eae55b709bd7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodDescriptor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodDescriptor.java @@ -1,21 +1,19 @@ package org.jetbrains.plugins.groovy.extensions; +import com.intellij.openapi.extensions.AbstractExtensionPointBean; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiMethod; import com.intellij.util.xmlb.annotations.AbstractCollection; import com.intellij.util.xmlb.annotations.Attribute; import com.intellij.util.xmlb.annotations.Property; import com.intellij.util.xmlb.annotations.Tag; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; import java.util.*; /** * @author Sergey Evdokimov */ -public class GroovyMethodDescriptor { +public class GroovyMethodDescriptor extends AbstractExtensionPointBean { private static final String ATTR_NAMES_DELIMITER = " \t\n\r,;"; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java index 2e6f829b7f10..c691f51215ef 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java @@ -21,7 +21,8 @@ public class GroovyMethodInfo { private static Map>> LIGHT_METHOD_INFOS; private final List myParams; - + private final ClassLoader myClassLoader; + private final String myReturnType; private final String myReturnTypeCalculatorClassName; private PairFunction myReturnTypeCalculatorInstance; @@ -121,6 +122,7 @@ public class GroovyMethodInfo { } public GroovyMethodInfo(GroovyMethodDescriptor method) { + myClassLoader = method.getLoaderForClass(); myParams = method.getParams(); myReturnType = method.returnType; myReturnTypeCalculatorClassName = method.returnTypeCalculator; @@ -177,7 +179,7 @@ public class GroovyMethodInfo { @NotNull public PairFunction getReturnTypeCalculator() { if (myReturnTypeCalculatorInstance == null) { - myReturnTypeCalculatorInstance = ClassInstanceCache.getInstance(myReturnTypeCalculatorClassName); + myReturnTypeCalculatorInstance = ClassInstanceCache.getInstance(myReturnTypeCalculatorClassName, myClassLoader); } return myReturnTypeCalculatorInstance; } @@ -193,7 +195,7 @@ public class GroovyMethodInfo { public GroovyNamedArgumentProvider getNamedArgProvider() { if (myNamedArgProviderInstance == null) { - myNamedArgProviderInstance = ClassInstanceCache.getInstance(myNamedArgProviderClassName); + myNamedArgProviderInstance = ClassInstanceCache.getInstance(myNamedArgProviderClassName, myClassLoader); } return myNamedArgProviderInstance; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/ClassInstanceCache.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/ClassInstanceCache.java index bf536189f4b1..7a9f0554e661 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/ClassInstanceCache.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/ClassInstanceCache.java @@ -1,7 +1,5 @@ package org.jetbrains.plugins.groovy.util; -import com.intellij.ide.plugins.IdeaPluginDescriptor; -import com.intellij.ide.plugins.PluginManager; import com.intellij.util.containers.ConcurrentHashMap; import org.jetbrains.annotations.NotNull; @@ -15,34 +13,16 @@ public class ClassInstanceCache { private ClassInstanceCache() { } - private static Object createInstance(@NotNull String className) { - try { - try { - return Class.forName(className).newInstance(); - } - catch (ClassNotFoundException e) { - for (IdeaPluginDescriptor descriptor : PluginManager.getPlugins()) { - try { - return descriptor.getPluginClassLoader().loadClass(className).newInstance(); - } - catch (ClassNotFoundException ignored) { - - } - } - - throw new RuntimeException("Class not found: " + className); - } - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - @SuppressWarnings("unchecked") - public static T getInstance(@NotNull String className) { + public static T getInstance(@NotNull String className, ClassLoader classLoader) { Object res = CACHE.get(className); if (res == null) { - res = createInstance(className); + try { + res = classLoader.loadClass(className).newInstance(); + } + catch (Exception e) { + throw new RuntimeException(e); + } Object oldValue = CACHE.putIfAbsent(className, res); if (oldValue != null) { @@ -52,5 +32,4 @@ public class ClassInstanceCache { return (T)res; } - } From aa57b0c7e54208d3fbd3aa91428c82acafb05bb4 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Fri, 21 Oct 2011 14:41:06 +0400 Subject: [PATCH 121/128] Bug fix: return type for 'DomainClass.withSession()' calculates incorrectly for grails 1.3.7 --- .../GrDescriptorReturnTypeCalculator.java | 41 +----------- .../groovy/util/GroovyStdTypeCalculators.java | 67 +++++++++++++++++++ 2 files changed, 68 insertions(+), 40 deletions(-) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/util/GroovyStdTypeCalculators.java diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrDescriptorReturnTypeCalculator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrDescriptorReturnTypeCalculator.java index 92862d15a748..fe58efe81b36 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrDescriptorReturnTypeCalculator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrDescriptorReturnTypeCalculator.java @@ -1,33 +1,24 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path; -import com.intellij.openapi.util.NullableComputable; -import com.intellij.openapi.util.RecursionGuard; -import com.intellij.openapi.util.RecursionManager; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.extensions.GroovyMethodInfo; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; -import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; /** * @author Sergey Evdokimov */ public class GrDescriptorReturnTypeCalculator extends GrCallExpressionTypeCalculator { - private static final RecursionGuard ourGuard = RecursionManager.createGuard("GrDescriptorReturnTypeCalculator getClosureReturnType"); - @Override public PsiType calculateReturnType(@NotNull GrMethodCall callExpression, @NotNull PsiMethod method) { for (GroovyMethodInfo methodInfo : GroovyMethodInfo.getInfos(method)) { String returnType = methodInfo.getReturnType(); if (returnType != null) { if (methodInfo.isApplicable(method)) { - return typeFromText(returnType, callExpression); + return JavaPsiFacade.getElementFactory(callExpression.getProject()).createTypeFromText(returnType, callExpression); } } else { @@ -44,34 +35,4 @@ public class GrDescriptorReturnTypeCalculator extends GrCallExpressionTypeCalcul return null; } - - @Nullable - public static PsiType typeFromText(String typeName, GrMethodCall callExpression) { - if (typeName.equals("!closure")) { - GrExpression[] allArguments = PsiUtil.getAllArguments(callExpression); - GrClosableBlock closure = null; - - for (GrExpression argument : allArguments) { - if (argument instanceof GrClosableBlock) { - closure = (GrClosableBlock)argument; - break; - } - } - - if (closure == null) return null; - - final GrClosableBlock finalClosure = closure; - - return ourGuard.doPreventingRecursion(callExpression, true, new NullableComputable() { - @Override - public PsiType compute() { - PsiType returnType = finalClosure.getReturnType(); - if (returnType == PsiType.VOID) return null; - return returnType; - } - }); - } - - return JavaPsiFacade.getElementFactory(callExpression.getProject()).createTypeFromText(typeName, callExpression); - } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/GroovyStdTypeCalculators.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/GroovyStdTypeCalculators.java new file mode 100644 index 000000000000..b26fac13fc0f --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/GroovyStdTypeCalculators.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2011 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.util; + +import com.intellij.openapi.util.NullableComputable; +import com.intellij.openapi.util.RecursionGuard; +import com.intellij.openapi.util.RecursionManager; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiType; +import com.intellij.util.PairFunction; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; + +/** + * @author Sergey Evdokimov + */ +public class GroovyStdTypeCalculators { + + private static final RecursionGuard ourGuard = RecursionManager.createGuard("GrDescriptorReturnTypeCalculator getClosureReturnType"); + + private GroovyStdTypeCalculators() { + } + + public static class ClosureTypeExtractor implements PairFunction { + @Override + public PsiType fun(GrMethodCall methodCall, PsiMethod method) { + GrExpression[] allArguments = PsiUtil.getAllArguments(methodCall); + GrClosableBlock closure = null; + + for (GrExpression argument : allArguments) { + if (argument instanceof GrClosableBlock) { + closure = (GrClosableBlock)argument; + break; + } + } + + if (closure == null) return null; + + final GrClosableBlock finalClosure = closure; + + return ourGuard.doPreventingRecursion(methodCall, true, new NullableComputable() { + @Override + public PsiType compute() { + PsiType returnType = finalClosure.getReturnType(); + if (returnType == PsiType.VOID) return null; + return returnType; + } + }); + } + } + +} From 33ff3c82647fb7758903211da2ea6cc26a724043 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 21 Oct 2011 13:09:19 +0200 Subject: [PATCH 122/128] goto related files for tests --- .../IdeaTestAssistant/src/META-INF/plugin.xml | 1 + .../GotoTestRelatedProvider.java | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 plugins/IdeaTestAssistant/src/com/intellij/testAssistant/GotoTestRelatedProvider.java diff --git a/plugins/IdeaTestAssistant/src/META-INF/plugin.xml b/plugins/IdeaTestAssistant/src/META-INF/plugin.xml index df0a2d1ce721..460595db0e63 100644 --- a/plugins/IdeaTestAssistant/src/META-INF/plugin.xml +++ b/plugins/IdeaTestAssistant/src/META-INF/plugin.xml @@ -18,6 +18,7 @@ + diff --git a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/GotoTestRelatedProvider.java b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/GotoTestRelatedProvider.java new file mode 100644 index 000000000000..1a9d044a558e --- /dev/null +++ b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/GotoTestRelatedProvider.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2011 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.testAssistant; + +import com.intellij.navigation.GotoRelatedItem; +import com.intellij.navigation.GotoRelatedProvider; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.search.FilenameIndex; +import com.intellij.psi.search.GlobalSearchScope; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Konstantin Bulenkov + */ +public class GotoTestRelatedProvider extends GotoRelatedProvider { + @NotNull + @Override + public List getItems(@NotNull DataContext context) { + final VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(context); + final Project project = PlatformDataKeys.PROJECT.getData(context); + if (file != null && project != null) { + final String ext = file.getExtension(); + String name = file.getNameWithoutExtension(); + final String filename; + if (ext != null && ext.length() > 0 && name.length() > 0) { + if (name.endsWith("Test") && name.length() > 4) { + filename = name.substring(0, name.length() - 4) + "." + ext; + } else { + filename = name + "Test." + ext; + } + final PsiFile[] files = FilenameIndex.getFilesByName(project, filename, GlobalSearchScope.allScope(project)); + if (files.length > 0) { + List items = new ArrayList(); + for (PsiFile psiFile : files) { + items.add(new GotoRelatedItem(psiFile)); + } + return items; + } + } + } + return super.getItems(context); + } +} From 7dc0091138ae5b232b8f75b7ebf7fb4bb72827f1 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 21 Oct 2011 13:12:48 +0200 Subject: [PATCH 123/128] save console output to file (IDEA-64394) --- .../debugger/ui/DebuggerSessionTab.java | 2 +- .../configurations/RunConfigurationBase.java | 43 ++++++ .../logging/LogConfigurationPanel.form | 26 +++- .../logging/LogConfigurationPanel.java | 26 +++- .../diagnostic/logging/LogFilesManager.java | 3 + .../diagnostic/logging/OutputFileUtil.java | 125 ++++++++++++++++++ .../execution/runners/RunContentBuilder.java | 6 +- .../sm/runner/ui/SMTestRunnerResultsForm.java | 1 + .../testframework/CompositePrintable.java | 40 ++++++ .../impl/ui/DebuggerSessionTabBase.java | 3 +- .../xdebugger/impl/ui/XDebugSessionTab.java | 2 +- .../execution/junit/JUnitConfiguration.java | 5 + .../intellij/execution/junit/TestObject.java | 1 + .../configuration/TestNGConfiguration.java | 5 + .../configuration/TestNGRunnableState.java | 1 + 15 files changed, 278 insertions(+), 11 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/diagnostic/logging/OutputFileUtil.java diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java index 2f6ceacc7b10..4b9a146a7ee4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java @@ -292,7 +292,7 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos } console.setActions(consoleActions, ActionPlaces.DEBUGGER_TOOLBAR, myConsole.getPreferredFocusableComponent()); - initLogConsoles(myConfiguration, myRunContentDescriptor.getProcessHandler()); + initLogConsoles(myConfiguration, myRunContentDescriptor.getProcessHandler(), myConsole); DefaultActionGroup group = new DefaultActionGroup(); final Executor executor = DefaultDebugExecutor.getDebugExecutorInstance(); diff --git a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java index 1cf1c0873c8b..b7c8d435dbb5 100644 --- a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java +++ b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java @@ -41,9 +41,16 @@ public abstract class RunConfigurationBase extends UserDataHolderBase implements private ArrayList myLogFiles = new ArrayList(); private ArrayList myPredefinedLogFiles = new ArrayList(); + @NonNls private static final String LOG_FILE = "log_file"; @NonNls private static final String PREDEFINED_LOG_FILE_ELEMENT = "predefined_log_file"; + @NonNls private static final String FILE_OUTPUT = "output_file"; + @NonNls private static final String SAVE = "is_save"; + @NonNls private static final String OUTPUT_FILE = "path"; + private final Icon myIcon; + private boolean mySaveOutput = false; + private String myFileOutputPath = null; protected RunConfigurationBase(final Project project, final ConfigurationFactory factory, final String name) { myProject = project; @@ -97,6 +104,8 @@ public abstract class RunConfigurationBase extends UserDataHolderBase implements final RunConfigurationBase runConfiguration = (RunConfigurationBase)super.clone(); runConfiguration.myLogFiles = new ArrayList(myLogFiles); runConfiguration.myPredefinedLogFiles = new ArrayList(myPredefinedLogFiles); + runConfiguration.myFileOutputPath = myFileOutputPath; + runConfiguration.mySaveOutput = mySaveOutput; copyCopyableDataTo(runConfiguration); return runConfiguration; } @@ -167,6 +176,12 @@ public abstract class RunConfigurationBase extends UserDataHolderBase implements logFile.readExternal((Element)fileElement); myPredefinedLogFiles.add(logFile); } + final Element fileOutputElement = element.getChild(FILE_OUTPUT); + if (fileOutputElement != null) { + myFileOutputPath = fileOutputElement.getAttributeValue(OUTPUT_FILE); + final String isSave = fileOutputElement.getAttributeValue(SAVE); + mySaveOutput = isSave != null && Boolean.parseBoolean(isSave); + } } public void writeExternal(Element element) throws WriteExternalException { @@ -180,6 +195,34 @@ public abstract class RunConfigurationBase extends UserDataHolderBase implements predefinedLogFile.writeExternal(fileElement); element.addContent(fileElement); } + final Element fileOutputPathElement = new Element(FILE_OUTPUT); + if (myFileOutputPath != null) { + fileOutputPathElement.setAttribute(OUTPUT_FILE, myFileOutputPath); + } + fileOutputPathElement.setAttribute(SAVE, String.valueOf(mySaveOutput)); + if (myFileOutputPath != null || mySaveOutput) { + element.addContent(fileOutputPathElement); + } + } + + public boolean isSaveOutputToFile() { + return mySaveOutput; + } + + public void setSaveOutputToFile(boolean redirectOutput) { + mySaveOutput = redirectOutput; + } + + public String getOutputFilePath() { + return myFileOutputPath; + } + + public void setFileOutputPath(String fileOutputPath) { + myFileOutputPath = fileOutputPath; + } + + public boolean collectOutputFromProcessHandler() { + return true; } public boolean excludeCompileBeforeLaunchOption() { diff --git a/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConfigurationPanel.form b/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConfigurationPanel.form index 7c6c49816b2f..46bbd8eb0552 100644 --- a/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConfigurationPanel.form +++ b/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConfigurationPanel.form @@ -1,6 +1,6 @@
- + @@ -14,7 +14,7 @@ - + @@ -52,12 +52,32 @@ - + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConfigurationPanel.java b/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConfigurationPanel.java index 3f2509d7fee7..e694c228b26e 100644 --- a/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConfigurationPanel.java +++ b/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConfigurationPanel.java @@ -20,13 +20,18 @@ import com.intellij.diagnostic.DiagnosticBundle; import com.intellij.execution.configurations.LogFileOptions; import com.intellij.execution.configurations.PredefinedLogFile; import com.intellij.execution.configurations.RunConfigurationBase; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.ui.TextComponentAccessor; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.BooleanTableCellRenderer; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.TableUtil; +import com.intellij.ui.components.JBCheckBox; import com.intellij.ui.table.TableView; import com.intellij.util.ui.AbstractTableCellEditor; import com.intellij.util.ui.CellEditorComponentWithBrowseButton; @@ -58,6 +63,8 @@ public class LogConfigurationPanel extends Setti private JButton myRemoveButton; private JPanel myScrollPanel; private JButton myEditButton; + private JBCheckBox myRedirectOutputCb; + private TextFieldWithBrowseButton myOutputFile; private final Map myLog2Predefined = new HashMap(); private final List myUnresolvedPredefined = new ArrayList(); @@ -144,6 +151,15 @@ public class LogConfigurationPanel extends Setti scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); myScrollPanel.add(scrollPane, BorderLayout.CENTER); myWholePanel.setPreferredSize(new Dimension(-1, 150)); + myOutputFile.addBrowseFolderListener("Choose File to Save Console Output", "Console output would be saved to the specified file", null, + FileChooserDescriptorFactory.createSingleFileOrFolderDescriptor(), + TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT); + myRedirectOutputCb.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + myOutputFile.setEnabled(myRedirectOutputCb.isSelected()); + } + }); } private void setUpColumnWidth(final JTableHeader tableHeader, final int preferredWidth, int columnIdx) { @@ -220,6 +236,11 @@ public class LogConfigurationPanel extends Setti } } myModel.setItems(list); + final boolean redirectOutputToFile = configuration.isSaveOutputToFile(); + myRedirectOutputCb.setSelected(redirectOutputToFile); + final String fileOutputPath = configuration.getOutputFilePath(); + myOutputFile.setText(fileOutputPath != null ? FileUtil.toSystemDependentName(fileOutputPath) : ""); + myOutputFile.setEnabled(redirectOutputToFile); } protected void applyEditorTo(final RunConfigurationBase configuration) throws ConfigurationException { @@ -244,7 +265,10 @@ public class LogConfigurationPanel extends Setti } for (PredefinedLogFile logFile : myUnresolvedPredefined) { configuration.addPredefinedLogFile(logFile); - } + } + final String text = myOutputFile.getText(); + configuration.setFileOutputPath(StringUtil.isEmpty(text) ? null : FileUtil.toSystemIndependentName(text)); + configuration.setSaveOutputToFile(myRedirectOutputCb.isSelected()); } @NotNull diff --git a/platform/lang-impl/src/com/intellij/diagnostic/logging/LogFilesManager.java b/platform/lang-impl/src/com/intellij/diagnostic/logging/LogFilesManager.java index 63f2c53097c5..e68799b6ba44 100644 --- a/platform/lang-impl/src/com/intellij/diagnostic/logging/LogFilesManager.java +++ b/platform/lang-impl/src/com/intellij/diagnostic/logging/LogFilesManager.java @@ -20,6 +20,7 @@ import com.intellij.execution.configurations.LogFileOptions; import com.intellij.execution.configurations.RunConfigurationBase; import com.intellij.execution.process.ProcessHandler; import com.intellij.openapi.Disposable; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; @@ -35,6 +36,8 @@ import java.util.*; * Date: 01-Feb-2006 */ public class LogFilesManager implements Disposable { + public static final Logger LOG = Logger.getInstance("#" + LogFilesManager.class.getName()); + private static final int UPDATE_INTERVAL = 500; private final Map> myLogFileManagerMap = new LinkedHashMap>(); diff --git a/platform/lang-impl/src/com/intellij/diagnostic/logging/OutputFileUtil.java b/platform/lang-impl/src/com/intellij/diagnostic/logging/OutputFileUtil.java new file mode 100644 index 000000000000..765a6b882f18 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/diagnostic/logging/OutputFileUtil.java @@ -0,0 +1,125 @@ +/* + * Copyright 2000-2011 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.diagnostic.logging; + +import com.intellij.execution.configurations.RunConfigurationBase; +import com.intellij.execution.filters.Filter; +import com.intellij.execution.filters.HyperlinkInfo; +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.execution.ui.ConsoleView; +import com.intellij.execution.ui.ExecutionConsole; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintStream; + +/** + * User: anna + * Date: 10/20/11 + */ +public class OutputFileUtil { + private static final String CONSOLE_OUTPUT_FILE_MESSAGE = "Console output is saving to: "; + + private OutputFileUtil() { + } + + public static void attachDumpListener(final RunConfigurationBase base, final ProcessHandler startedProcess, ExecutionConsole console) { + if (base.isSaveOutputToFile()) { + final String outputFilePath = base.getOutputFilePath(); + if (outputFilePath != null) { + final String filePath = FileUtil.toSystemDependentName(outputFilePath); + startedProcess.addProcessListener(new ProcessAdapter() { + private PrintStream myOutput; + @Override + public void onTextAvailable(ProcessEvent event, Key outputType) { + if (base.collectOutputFromProcessHandler() && myOutput != null && outputType != ProcessOutputTypes.SYSTEM) { + myOutput.print(event.getText()); + } + } + + @Override + public void startNotified(ProcessEvent event) { + try { + myOutput = new PrintStream(new FileOutputStream(new File(filePath))); + } + catch (FileNotFoundException ignored) { + } + startedProcess.notifyTextAvailable(CONSOLE_OUTPUT_FILE_MESSAGE + filePath + "\n", ProcessOutputTypes.SYSTEM); + } + + @Override + public void processTerminated(ProcessEvent event) { + startedProcess.removeProcessListener(this); + if (myOutput != null) { + myOutput.close(); + } + } + }); + if (console instanceof ConsoleView) { + ((ConsoleView)console).addMessageFilter(new ShowOutputFileFilter()); + } + } + } + } + + private static class ShowOutputFileFilter implements Filter { + @Override + public Result applyFilter(String line, int entireLength) { + if (line.startsWith(CONSOLE_OUTPUT_FILE_MESSAGE)) { + final String filePath = StringUtil.trimEnd(line.substring(CONSOLE_OUTPUT_FILE_MESSAGE.length()), "\n"); + + return new Result(entireLength - filePath.length() - 1, entireLength, new HyperlinkInfo() { + @Override + public void navigate(final Project project) { + final VirtualFile file = + ApplicationManager.getApplication().runWriteAction(new Computable() { + @Nullable + @Override + public VirtualFile compute() { + return LocalFileSystem.getInstance().refreshAndFindFileByPath(FileUtil.toSystemIndependentName(filePath)); + } + }); + + if (file != null) { + file.refresh(false, false); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, file), true); + } + }); + } + } + }); + } + return null; + } + } +} diff --git a/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java b/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java index a637cc0668a5..5dc8d10083b1 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java @@ -15,10 +15,7 @@ */ package com.intellij.execution.runners; -import com.intellij.diagnostic.logging.AdditionalTabComponent; -import com.intellij.diagnostic.logging.LogConsoleImpl; -import com.intellij.diagnostic.logging.LogConsoleManager; -import com.intellij.diagnostic.logging.LogFilesManager; +import com.intellij.diagnostic.logging.*; import com.intellij.execution.DefaultExecutionResult; import com.intellij.execution.ExecutionResult; import com.intellij.execution.Executor; @@ -140,6 +137,7 @@ public class RunContentBuilder implements LogConsoleManager, Disposable { } if (profile instanceof RunConfigurationBase) { myManager.initLogConsoles((RunConfigurationBase)profile, myExecutionResult.getProcessHandler()); + OutputFileUtil.attachDumpListener((RunConfigurationBase)profile, myExecutionResult.getProcessHandler(), console); } } MyRunContentDescriptor contentDescriptor = new MyRunContentDescriptor(profile, myExecutionResult, myReuseProhibited, myUi.getComponent(), this); diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java index 26268edc3731..34f025b606ac 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java @@ -112,6 +112,7 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra //Create tests common suite root //noinspection HardCodedStringLiteral myTestsRootNode = new SMTestProxy.SMRootTestProxy(); + //todo myTestsRootNode.setOutputFilePath(runConfiguration.getOutputFilePath()); // Fire selection changed and move focus on SHIFT+ENTER //TODO[romeo] improve diff --git a/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java b/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java index 5e8960547fd4..efe0d7bfd6aa 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java @@ -40,6 +40,7 @@ public class CompositePrintable implements Printable, Disposable { private final PrintablesWrapper myWrapper = new PrintablesWrapper(); protected int myExceptionMark; private int myCurrentSize = 0; + private String myOutputFile = null; private static final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); public void flush() { @@ -119,6 +120,10 @@ public class CompositePrintable implements Printable, Disposable { myExceptionMark = exceptionMark; } + public void setOutputFilePath(String outputFile) { + myOutputFile = outputFile; + } + private static final Logger LOG = Logger.getInstance("#" + PrintablesWrapper.class.getName()); private class PrintablesWrapper { @@ -167,6 +172,41 @@ public class CompositePrintable implements Printable, Disposable { printable.printOn(myPrinter); } myPrinter.close(); + if (myOutputFile != null) { + PrintStream printStream = null; + try { + printStream = new PrintStream(new FileOutputStream(new File(myOutputFile), true)); + final PrintStream finalPrintStream = printStream; + for (Printable currentPrintable : currentPrintables) { + currentPrintable.printOn(new Printer() { + @Override + public void print(String text, ConsoleViewContentType contentType) { + if (contentType != ConsoleViewContentType.SYSTEM_OUTPUT) { + finalPrintStream.print(text); + } + } + + @Override + public void printHyperlink(String text, HyperlinkInfo info) { + finalPrintStream.print(text); + } + + @Override + public void onNewAvailable(@NotNull Printable printable) {} + @Override + public void mark() {} + }); + } + } + catch (FileNotFoundException e) { + LOG.error(e); + } + finally { + if (printStream != null) { + printStream.close(); + } + } + } } }; invokeInAlarm(request, ApplicationManager.getApplication().isUnitTestMode()); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java index 1b5cd0294d10..8d013ef5e41f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java @@ -80,9 +80,10 @@ public abstract class DebuggerSessionTabBase implements DebuggerLogConsoleManage } } - protected void initLogConsoles(final RunProfile runConfiguration, final ProcessHandler processHandler) { + protected void initLogConsoles(final RunProfile runConfiguration, final ProcessHandler processHandler, ExecutionConsole console) { if (runConfiguration instanceof RunConfigurationBase) { myManager.initLogConsoles((RunConfigurationBase)runConfiguration, processHandler); + OutputFileUtil.attachDumpListener((RunConfigurationBase)runConfiguration, processHandler, console); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java index d96830595c0b..efd760d40209 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java @@ -198,7 +198,7 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { if (env != null) { final RunProfile runConfiguration = env.getRunProfile(); registerFileMatcher(runConfiguration); - initLogConsoles(runConfiguration, myRunContentDescriptor.getProcessHandler()); + initLogConsoles(runConfiguration, myRunContentDescriptor.getProcessHandler(), myConsole); } rebuildViews(); diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java b/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java index dd802ac01253..f83067678aa6 100644 --- a/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java +++ b/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java @@ -357,6 +357,11 @@ public class JUnitConfiguration extends ModuleBasedConfiguration Date: Fri, 21 Oct 2011 12:38:50 +0400 Subject: [PATCH 124/128] GRADLE-1856 Tooling API: Make it possible to get IntelliJ IDEA view to the gradle project Improved gradle api exceptions reporting --- .../wizard/GradleProjectImportBuilder.java | 15 +++- .../gradle/remote/GradleApiException.java | 85 +++++++++++++++++++ .../gradle/remote/GradleProjectResolver.java | 3 +- .../impl/GradleProjectResolverImpl.java | 70 ++++----------- 4 files changed, 117 insertions(+), 56 deletions(-) create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiException.java diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/GradleProjectImportBuilder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/GradleProjectImportBuilder.java index c6214087d1ac..048babe7168c 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/GradleProjectImportBuilder.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/GradleProjectImportBuilder.java @@ -17,6 +17,7 @@ import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.packaging.artifacts.ModifiableArtifactModel; import com.intellij.projectImport.ProjectImportBuilder; import org.jetbrains.annotations.NotNull; @@ -27,6 +28,7 @@ import org.jetbrains.plugins.gradle.importing.model.GradleModule; import org.jetbrains.plugins.gradle.importing.model.GradleProject; import org.jetbrains.plugins.gradle.remote.GradleApiFacadeManager; import org.jetbrains.plugins.gradle.remote.GradleProjectResolver; +import org.jetbrains.plugins.gradle.remote.GradleApiException; import org.jetbrains.plugins.gradle.util.GradleBundle; import org.jetbrains.plugins.gradle.util.GradleIcons; import org.jetbrains.plugins.gradle.util.GradleLog; @@ -157,14 +159,21 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder + * This class allows to extract textual description of the target problem and deliver it for further processing without risking to + * get the problems mentioned above. I.e. it doesn't require anything specific can be safely delivered to IJ process then. + * + * @author Denis Zhdanov + * @since 10/21/11 11:42 AM + */ +public class GradleApiException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + private final String myOriginalReason; + + public GradleApiException() { + this(null, null); + } + + public GradleApiException(@Nullable String message) { + this(message, null); + } + + public GradleApiException(@Nullable Throwable cause) { + this("", cause); + } + + public GradleApiException(@Nullable String message, @Nullable Throwable cause) { + super(extractMessage(message, cause)); + if (cause == null) { + myOriginalReason = ""; + return; + } + + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter); + try { + cause.printStackTrace(printWriter); + } + finally { + printWriter.close(); + } + myOriginalReason = stringWriter.toString(); + } + + /** + * @return textual description of the wrapped exception (if any); empty string otherwise + */ + @NotNull + public String getOriginalReason() { + return myOriginalReason; + } + + @Override + public void printStackTrace(PrintWriter s) { + super.printStackTrace(s); + s.println(myOriginalReason); + } + + @Override + public void printStackTrace(PrintStream s) { + super.printStackTrace(s); + s.println(myOriginalReason); + } + + @Nullable + private static String extractMessage(@Nullable String message, @Nullable Throwable cause) { + if (message != null) { + return message; + } + return cause == null ? "" : cause.getMessage(); + } + +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleProjectResolver.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleProjectResolver.java index ecb0a6324858..4c70a26380e7 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleProjectResolver.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleProjectResolver.java @@ -25,11 +25,12 @@ public interface GradleProjectResolver extends Remote { * @param downloadLibraries flag that specifies if third-party libraries that are not available locally should be resolved (downloaded) * @return object-level representation of the target gradle project * @throws RemoteException in case of unexpected exception during remote communications + * @throws GradleApiException in case of unexpected exception thrown from Gradle API * @throws IllegalArgumentException if given path doesn't point to directory that contains gradle project or if gradle api * returns invalid data * @throws IllegalStateException if it's not possible to resolve target project info */ @NotNull GradleProject resolveProjectInfo(@NotNull String projectPath, boolean downloadLibraries) - throws RemoteException, IllegalArgumentException, IllegalStateException; + throws RemoteException, GradleApiException, IllegalArgumentException, IllegalStateException; } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleProjectResolverImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleProjectResolverImpl.java index 17dad9759b35..8b5ef5b420b2 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleProjectResolverImpl.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleProjectResolverImpl.java @@ -13,16 +13,13 @@ import org.gradle.tooling.model.idea.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.importing.model.*; -import org.jetbrains.plugins.gradle.remote.GradleProjectResolver; -import org.jetbrains.plugins.gradle.remote.RemoteGradleProcessSettings; -import org.jetbrains.plugins.gradle.remote.RemoteGradleService; +import org.jetbrains.plugins.gradle.remote.*; import org.jetbrains.plugins.gradle.util.GradleBundle; import org.jetbrains.plugins.gradle.util.GradleLog; import org.jetbrains.plugins.gradle.util.GradleUtil; import java.io.File; import java.rmi.RemoteException; -import java.util.Arrays; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -37,16 +34,25 @@ import java.util.concurrent.atomic.AtomicReference; */ public class GradleProjectResolverImpl extends RemoteObject implements GradleProjectResolver, RemoteGradleService { - private static final Set NON_UNIQUE_PATH_ENTRIES = new HashSet(Arrays.asList( - "src", "main", "java", "test", "resources" - )); - - private final BlockingQueue myConnections = new LinkedBlockingQueue(); - private final AtomicReference mySettings = new AtomicReference(); - + private final BlockingQueue myConnections = new LinkedBlockingQueue(); + private final AtomicReference mySettings = new AtomicReference(); + private final GradleLibraryNamesMixer myLibraryNamesMixer = new GradleLibraryNamesMixer(); + @NotNull @Override public GradleProject resolveProjectInfo(@NotNull String projectPath, boolean downloadLibraries) + throws RemoteException, GradleApiException, IllegalArgumentException, IllegalStateException + { + try { + return doResolveProjectInfo(projectPath, downloadLibraries); + } + catch (Throwable e) { + throw new GradleApiException(e); + } + } + + @NotNull + private GradleProject doResolveProjectInfo(@NotNull String projectPath, boolean downloadLibraries) throws RemoteException, IllegalArgumentException, IllegalStateException { ProjectConnection connection = getConnection(projectPath); @@ -58,7 +64,7 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro // populating dependent module object. Map> modules = createModules(project, result); populateModules(modules.values(), result); - diversifyLibraryNamesIfNecessary(result); + myLibraryNamesMixer.mixNames(result.getLibraries()); return result; } @@ -315,46 +321,6 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro return null; } - /** - * Gradle API doesn't provide library names at the moment, so, we deduce them from the path. However, it's possible to have identical - * names then. - *

- * This method solves that by diversifying duplicate library names. - * - * @param project target project which library names should be diversified if necessary - */ - private static void diversifyLibraryNamesIfNecessary(@NotNull GradleProject project) { - Map libraries = new HashMap(); - for (GradleLibrary library : project.getLibraries()) { - GradleLibrary previous = libraries.remove(library.getName()); - if (previous == null) { - libraries.put(library.getName(), library); - continue; - } - previous.setName(generateName(previous)); - libraries.put(previous.getName(), previous); - library.setName(generateName(library)); - libraries.put(library.getName(), library); - } - } - - @NotNull - private static String generateName(@NotNull GradleLibrary library) { - for (LibraryPathType pathType : LibraryPathType.values()) { - String path = library.getPath(pathType); - if (path == null) { - continue; - } - File file = new File(path).getParentFile(); - for (; file != null; file = file.getParentFile()) { - if (!NON_UNIQUE_PATH_ENTRIES.contains(file.getName())) { - return file.getName() + "-" + library.getName(); - } - } - } - return library.getName(); - } - /** * Allows to retrieve gradle api connection to use for the given project. * From 71147efe86fc05281d91cbed72c4ba170d2b58f8 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Fri, 21 Oct 2011 13:26:02 +0400 Subject: [PATCH 125/128] IDEA-75727 Gradle: support library dependencies that don't point to *.jar files --- .../importing/GradleModulesImporter.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java index 517e6e777f1e..39398cf04945 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java @@ -441,14 +441,19 @@ public class GradleModulesImporter { GradleLog.LOG.warn(String.format("Can't find %s of the library '%s' at path '%s'", pathType, gradleLibrary.getName(), path)); continue; } - VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(virtualFile); - if (jarRoot == null) { - GradleLog.LOG.warn(String.format( - "Can't parse contents of the jar file at path '%s' for the library '%s''", path, gradleLibrary.getName() - )); - continue; + if (virtualFile.isDirectory()) { + model.addRoot(virtualFile, pathType.getRootType()); + } + else { + VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(virtualFile); + if (jarRoot == null) { + GradleLog.LOG.warn(String.format( + "Can't parse contents of the jar file at path '%s' for the library '%s''", path, gradleLibrary.getName() + )); + continue; + } + model.addRoot(jarRoot, pathType.getRootType()); } - model.addRoot(jarRoot, pathType.getRootType()); } } } From c18aee77d6df9906f3dbcca65d365d52696d364f Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Fri, 21 Oct 2011 13:27:22 +0400 Subject: [PATCH 126/128] IDEA-75728 Gradle: Try to ensure that libraries of the imported project have distinct names --- .../model/AbstractGradleDependency.java | 14 +- .../remote/impl/GradleLibraryNamesMixer.java | 222 ++++++++++++++++++ .../impl/GradleLibraryNamesMixerTest.java | 71 ++++++ 3 files changed, 295 insertions(+), 12 deletions(-) create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleLibraryNamesMixer.java create mode 100644 plugins/gradle/testSources/org/jetbrains/plugins/gradle/remote/impl/GradleLibraryNamesMixerTest.java diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/AbstractGradleDependency.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/AbstractGradleDependency.java index 1a4538dc187f..5e26f0accf18 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/AbstractGradleDependency.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/AbstractGradleDependency.java @@ -35,22 +35,12 @@ public abstract class AbstractGradleDependency extends AbstractGradleEntity impl @Override public int hashCode() { - int result = myScope.hashCode(); - result = 31 * result + (myExported ? 1 : 0); - return result; + return 31; } @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - AbstractGradleDependency that = (AbstractGradleDependency)o; - - if (myExported != that.myExported) return false; - if (myScope != that.myScope) return false; - - return true; + return this == o || (o != null && getClass() == o.getClass()); } @Override diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleLibraryNamesMixer.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleLibraryNamesMixer.java new file mode 100644 index 000000000000..45413cdf04e1 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleLibraryNamesMixer.java @@ -0,0 +1,222 @@ +package org.jetbrains.plugins.gradle.remote.impl; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.containers.HashMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.gradle.importing.model.GradleLibrary; +import org.jetbrains.plugins.gradle.importing.model.LibraryPathType; + +import java.io.File; +import java.util.*; + +/** + * Encapsulates logic of checking if particular collection of gradle libraries contains libraries with the same names and + * tries to diversify them in the case of the positive answer. + *

+ * Thread-safe. + * + * @author Denis Zhdanov + * @since 10/19/11 2:04 PM + */ +public class GradleLibraryNamesMixer { + + /** + * Holds mappings like ('file name'; boolean) where 'file name' defines 'too common' file/dir + * name that should not be used during library name generation. Boolean flag indicates if 'common file name' may be used + * if 'non-common' files are the same. + *

+ * Example: consider the following file system tree: + *

+   *   module
+   *     |_src
+   *        |_main
+   *        |  |_resources
+   *        |
+   *        |_test
+   *           |_resources
+   * 
+ * Let's say we have two libraries where one of them points to 'src/main/resources' and another one + * to 'src/test/resources'. We want to generate names 'module-resources' and + * 'module-test-resources' respectively because 'test' entry at the current collection is + * stored with 'true' flag. + */ + private static final Map NON_UNIQUE_PATH_ENTRIES = new HashMap(); + static { + NON_UNIQUE_PATH_ENTRIES.put("src", false); + NON_UNIQUE_PATH_ENTRIES.put("main", false); + NON_UNIQUE_PATH_ENTRIES.put("test", true); + NON_UNIQUE_PATH_ENTRIES.put("resources", false); + NON_UNIQUE_PATH_ENTRIES.put("java", false); + NON_UNIQUE_PATH_ENTRIES.put("groovy", false); + } + private static final char NAME_SEPARATOR = '-'; + + /** + * Tries to ensure that given libraries have distinct names, i.e. traverses all of them and tries to generate + * unique name for those with equal names. + * + * @param libraries libraries to process + */ + @SuppressWarnings("MethodMayBeStatic") + public void mixNames(@NotNull Iterable libraries) { + Map names = new HashMap(); + List data = new ArrayList(); + for (GradleLibrary library : libraries) { + Wrapped wrapped = new Wrapped(library); + data.add(wrapped); + } + boolean mixed = false; + while (!mixed) { + mixed = doMixNames(data, names); + } + } + + /** + * Does the same as {@link #mixNames(Iterable)} but uses given ('library name; wrapped library'} mappings cache. + * + * @param libraries libraries to process + * @param cache cache to use + * @return true if all of the given libraries have distinct names now; false otherwise + */ + private static boolean doMixNames(@NotNull Collection libraries, @NotNull Map cache) { + cache.clear(); + for (Wrapped current : libraries) { + Wrapped previous = cache.remove(current.library.getName()); + if (previous == null) { + cache.put(current.library.getName(), current); + } + else { + mixNames(current, previous); + return current.library.getName().equals(previous.library.getName()); // Stop processing if it's not possible to generate + } + } + return true; + } + + /** + * Tries to generate distinct names for the given wrapped libraries (assuming that they have equal names at the moment). + * + * @param wrapped1 one of the libraries with equal names + * @param wrapped2 another library which name is equal to the name of the given one + */ + @SuppressWarnings("AssignmentToForLoopParameter") + private static void mixNames(@NotNull Wrapped wrapped1, @NotNull Wrapped wrapped2) { + if (!wrapped1.prepare() || !wrapped2.prepare()) { + return; + } + String wrapped1AltText = null; + String wrapped2AltText = null; + + for (File file1 = wrapped1.currentFile, file2 = wrapped2.currentFile; + file1 != null && file2 != null; + file1 = file1.getParentFile(), file2 = file2.getParentFile()) + { + while (file1 != null && !StringUtil.isEmpty(file1.getName()) && NON_UNIQUE_PATH_ENTRIES.containsKey(file1.getName())) { + if (NON_UNIQUE_PATH_ENTRIES.get(file1.getName())) { + if (StringUtil.isEmpty(wrapped1AltText)) { + wrapped1AltText = file1.getName(); + } + else { + wrapped1AltText += NAME_SEPARATOR + file1.getName(); + } + } + file1 = file1.getParentFile(); + } + while (file2 != null && !StringUtil.isEmpty(file2.getName()) && NON_UNIQUE_PATH_ENTRIES.containsKey(file2.getName())) { + if (NON_UNIQUE_PATH_ENTRIES.get(file2.getName())) { + if (StringUtil.isEmpty(wrapped2AltText)) { + wrapped2AltText = file2.getName(); + } + else { + wrapped2AltText += NAME_SEPARATOR + file2.getName(); + } + } + file2 = file2.getParentFile(); + } + + if (file1 == null) { + wrapped1.nextFile(); + } + if (file2 == null) { + wrapped2.nextFile(); + } + + if (file1 != null && file2 != null && !file1.getName().equals(file2.getName())) { + wrapped1.library.setName(file1.getName() + NAME_SEPARATOR + wrapped1.library.getName()); + wrapped2.library.setName(file2.getName() + NAME_SEPARATOR + wrapped2.library.getName()); + } + + if (wrapped1.library.getName().equals(wrapped2.library.getName())) { + if (wrapped1AltText != null) { + diversifyName(wrapped1AltText, wrapped1, file1); + return; + } + else if (wrapped2AltText != null) { + diversifyName(wrapped2AltText, wrapped2, file1); + return; + } + } + else { + return; + } + + if (file1 == null || file2 == null) { + return; + } + } + } + + @SuppressWarnings("ConstantConditions") + private static void diversifyName(@NotNull String changeText, @NotNull Wrapped wrapped, @Nullable File file) { + String name = wrapped.library.getName(); + int i = file == null ? - 1 : name.indexOf(file.getName()); + final String newName; + if (i >= 0) { + newName = name.substring(0, i + file.getName().length()) + NAME_SEPARATOR + changeText + name.substring(i + file.getName().length()); + } + else { + newName = changeText + NAME_SEPARATOR + name; + } + wrapped.library.setName(newName); + } + + /** + * Wraps target library and hold auxiliary information required for the processing. + */ + private static class Wrapped { + /** Holds list of files that may be used for name generation. */ + public final Set files = new HashSet(); + /** File that was used for the current name generation. */ + public File currentFile; + /** Target library. */ + public GradleLibrary library; + + Wrapped(@NotNull GradleLibrary library) { + this.library = library; + for (LibraryPathType pathType : LibraryPathType.values()) { + String path = library.getPath(pathType); + if (path != null) { + files.add(new File(path)); + } + } + } + + public boolean prepare() { + if (currentFile != null) { + return true; + } + return nextFile(); + } + + public boolean nextFile() { + if (files.isEmpty()) { + return false; + } + Iterator iterator = files.iterator(); + currentFile = iterator.next(); + iterator.remove(); + return true; + } + } +} diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/remote/impl/GradleLibraryNamesMixerTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/remote/impl/GradleLibraryNamesMixerTest.java new file mode 100644 index 000000000000..dc5dc5077934 --- /dev/null +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/remote/impl/GradleLibraryNamesMixerTest.java @@ -0,0 +1,71 @@ +package org.jetbrains.plugins.gradle.remote.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.gradle.importing.model.GradleLibrary; +import org.jetbrains.plugins.gradle.importing.model.LibraryPathType; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +/** + * @author Denis Zhdanov + * @since 10/19/11 5:25 PM + */ +public class GradleLibraryNamesMixerTest { + + private GradleLibraryNamesMixer myMixer; + + @Before + public void setUp() { + myMixer = new GradleLibraryNamesMixer(); + } + + @Test + public void sourceVsTest() { + doTest( + t("resources", "my-module-resources", "dir1/dir2/my-module/src/main/resources"), + t("resources", "my-module-test-resources", "dir1/dir2/my-module/src/test/resources"), + t("resources", "my-another-module-resources", "dir1/dir2/my-another-module/src/main/resources"), + t("resources", "my-another-module-test-resources", "dir1/dir2/my-another-module/src/test/resources") + ); + } + + private void doTest(TestDataEntry... entries) { + Map expected = new IdentityHashMap(); + List libraries = new ArrayList(); + for (TestDataEntry entry : entries) { + GradleLibrary library = new GradleLibrary(entry.initialName); + library.addPath(LibraryPathType.BINARY, entry.path); + libraries.add(library); + expected.put(library, entry.expectedName); + } + + myMixer.mixNames(libraries); + for (GradleLibrary library : libraries) { + assertEquals(expected.get(library), library.getName()); + } + } + + private static class TestDataEntry { + + public String initialName; + public String expectedName; + public String path; + + TestDataEntry(@NotNull String initialName, @NotNull String expectedName, @NotNull String path) { + this.initialName = initialName; + this.expectedName = expectedName; + this.path = path; + } + } + + public static TestDataEntry t(@NotNull String initialName, @NotNull String expectedName, @NotNull String path) { + return new TestDataEntry(initialName, expectedName, path); + } +} From 9de4c9d2f0d9ae3ccc7efe85871b0b8e300323c5 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Fri, 21 Oct 2011 15:17:05 +0400 Subject: [PATCH 127/128] IDEA-75560 UnmarshalException while importing a Gradle project in idea-IC-110.3 Using explicit timeout (one hour) for RMI sockets. Reason: default timeout is fifteen seconds and it was often exceeded when gradle api resolved external dependencies --- .../plugins/gradle/remote/GradleApiFacadeManager.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java index 0d5e0994dce9..a183c4e8760f 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java @@ -43,6 +43,7 @@ import java.nio.charset.Charset; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.Collection; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; /** @@ -131,6 +132,13 @@ public class GradleApiFacadeManager { params.setMainClass(MAIN_CLASS_NAME); params.getVMParametersList().addParametersString("-Djava.awt.headless=true -Xmx512m"); + + // It may take a while for gradle api to resolve external dependencies. Default RMI timeout + // is 15 seconds (http://download.oracle.com/javase/1.4.2/docs/guide/rmi/sunrmiproperties.html#connectionTimeout), + // we don't want to get EOFException because of that. + params.getVMParametersList().addParametersString( + "-Dsun.rmi.transport.connectionTimeout=" + String.valueOf(TimeUnit.HOURS.toMillis(1)) + ); //params.getVMParametersList().addParametersString("-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5009"); return params; } From 3760ab4c7efa0e5df96cfa0918f154a80f88c057 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Fri, 21 Oct 2011 15:23:13 +0400 Subject: [PATCH 128/128] inspections language --- plugins/properties/src/META-INF/plugin.xml | 8 ++++---- plugins/testng/src/META-INF/plugin.xml | 14 +++++++------- plugins/xpath/xpath-view/src/META-INF/plugin.xml | 10 +++++----- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/plugins/properties/src/META-INF/plugin.xml b/plugins/properties/src/META-INF/plugin.xml index 1a4c89778c82..6d9161c51233 100644 --- a/plugins/properties/src/META-INF/plugin.xml +++ b/plugins/properties/src/META-INF/plugin.xml @@ -46,15 +46,15 @@ - - diff --git a/plugins/testng/src/META-INF/plugin.xml b/plugins/testng/src/META-INF/plugin.xml index 061da3328313..8e67df9c8566 100644 --- a/plugins/testng/src/META-INF/plugin.xml +++ b/plugins/testng/src/META-INF/plugin.xml @@ -15,22 +15,22 @@ - - - - - - - diff --git a/plugins/xpath/xpath-view/src/META-INF/plugin.xml b/plugins/xpath/xpath-view/src/META-INF/plugin.xml index 77d163f391f5..8a85d90d12c1 100644 --- a/plugins/xpath/xpath-view/src/META-INF/plugin.xml +++ b/plugins/xpath/xpath-view/src/META-INF/plugin.xml @@ -83,15 +83,15 @@ - - - - -