diff options
author | Tor Norbye <tnorbye@google.com> | 2013-08-23 16:33:54 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2013-08-23 16:33:54 +0000 |
commit | 6de25c0bb0ca49919c07783872fd4838469f215f (patch) | |
tree | 9d2e7f0b4e2e38615e9c6780cd8f013dac8006ac | |
parent | 9aba8b126a2b899c4799da2b3fa958fac75cf422 (diff) | |
parent | e0509264c30af8183d8cafb09f640b148b5703b8 (diff) | |
download | idea-6de25c0bb0ca49919c07783872fd4838469f215f.tar.gz |
Merge "Merge remote-tracking branch 'aosp/snapshot-master' into merge"
236 files changed, 3584 insertions, 2606 deletions
diff --git a/.idea/modules.xml b/.idea/modules.xml index dfa52fcd3598..2978b5c1b4d2 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -139,7 +139,8 @@ <module fileurl="file://$PROJECT_DIR$/xml/relaxng/relaxng.iml" filepath="$PROJECT_DIR$/xml/relaxng/relaxng.iml" group="plugins" /> <module fileurl="file://$PROJECT_DIR$/platform/remote-servers/api/remote-servers-api.iml" filepath="$PROJECT_DIR$/platform/remote-servers/api/remote-servers-api.iml" group="platform" /> <module fileurl="file://$PROJECT_DIR$/platform/remote-servers/impl/remote-servers-impl.iml" filepath="$PROJECT_DIR$/platform/remote-servers/impl/remote-servers-impl.iml" group="platform" /> - <module fileurl="file://$PROJECT_DIR$/java/remote-servers/remote-servers-java.iml" filepath="$PROJECT_DIR$/java/remote-servers/remote-servers-java.iml" /> + <module fileurl="file://$PROJECT_DIR$/java/remote-servers/api/remote-servers-java-api.iml" filepath="$PROJECT_DIR$/java/remote-servers/api/remote-servers-java-api.iml" group="java" /> + <module fileurl="file://$PROJECT_DIR$/java/remote-servers/impl/remote-servers-java-impl.iml" filepath="$PROJECT_DIR$/java/remote-servers/impl/remote-servers-java-impl.iml" group="java" /> <module fileurl="file://$PROJECT_DIR$/resources/resources.iml" filepath="$PROJECT_DIR$/resources/resources.iml" /> <module fileurl="file://$PROJECT_DIR$/resources-en/resources-en.iml" filepath="$PROJECT_DIR$/resources-en/resources-en.iml" /> <module fileurl="file://$PROJECT_DIR$/../base/sdk-common/sdk-common.iml" filepath="$PROJECT_DIR$/../base/sdk-common/sdk-common.iml" group="plugins/Android/android-sdk" /> diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant index 37504c4404c9..db7427247f45 100644 --- a/build/scripts/layouts.gant +++ b/build/scripts/layouts.gant @@ -57,6 +57,7 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir "debugger-openapi", "compiler-openapi", "remote-servers-api", + "remote-servers-java-api", "dom-openapi", "execution-openapi", "jsp-openapi", @@ -66,7 +67,7 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir List<String> implementationModules = [platformImplementationModules, "compiler-impl", "remote-servers-impl", - "remote-servers-java", + "remote-servers-java-impl", "debugger-impl", "dom-impl", "execution-impl", diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarArtifactType.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarArtifactType.java index 19571e49acfe..2a0af9007963 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarArtifactType.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarArtifactType.java @@ -19,9 +19,9 @@ import com.intellij.icons.AllIcons; import com.intellij.packaging.artifacts.ArtifactTemplate; import com.intellij.packaging.artifacts.ArtifactType; import com.intellij.packaging.elements.CompositePackagingElement; +import com.intellij.packaging.elements.PackagingElementFactory; import com.intellij.packaging.elements.PackagingElementOutputKind; import com.intellij.packaging.elements.PackagingElementResolvingContext; -import com.intellij.packaging.impl.elements.ArchivePackagingElement; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -54,7 +54,7 @@ public class JarArtifactType extends ArtifactType { @NotNull @Override public CompositePackagingElement<?> createRootElement(@NotNull String artifactName) { - return new ArchivePackagingElement(ArtifactUtil.suggestArtifactFileName(artifactName) + ".jar"); + return PackagingElementFactory.getInstance().createArchive(ArtifactUtil.suggestArtifactFileName(artifactName) + ".jar"); } @NotNull diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchivePackagingElement.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchivePackagingElement.java index a144df73b600..0064ee2dfd48 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchivePackagingElement.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchivePackagingElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java index 4e30fc3fe595..2bc0a28871d8 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java @@ -81,7 +81,7 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)parent).getClassOrAnonymousClassReference(); if (classReference != null) { holder.registerProblem(classReference, - "Anonymous type can be replaced with method reference", new ReplaceWithMethodRefFix()); + "Anonymous #ref #loc can be replaced with method reference", new ReplaceWithMethodRefFix()); } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java index 067a4258b148..d80b6b590c98 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java @@ -24,7 +24,9 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.filters.FilterPositionUtil; +import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.javadoc.PsiDocTag; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; @@ -39,8 +41,6 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE @Override public void handleInsert(final InsertionContext context, final JavaPsiClassReferenceElement item) { - final char c = context.getCompletionChar(); - int offset = context.getTailOffset() - 1; final PsiFile file = context.getFile(); if (PsiTreeUtil.findElementOfClassAtOffset(file, offset, PsiImportStatementBase.class, false) != null) { @@ -57,6 +57,7 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE final Project project = context.getProject(); final Editor editor = context.getEditor(); + final char c = context.getCompletionChar(); if (c == '#') { context.setLaterRunnable(new Runnable() { @Override @@ -68,6 +69,12 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE AutoPopupController.getInstance(context.getProject()).autoPopupMemberLookup(context.getEditor(), null); } + if (PsiTreeUtil.getParentOfType(position, PsiDocComment.class, false) != null && + CodeStyleSettingsManager.getSettings(project).USE_FQ_CLASS_NAMES_IN_JAVADOC) { + AllClassesGetter.INSERT_FQN.handleInsert(context, item); + return; + } + if (position != null) { PsiElement parent = position.getParent(); if (parent instanceof PsiJavaCodeReferenceElement) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java index 6dc59284748f..bf94078ff1c1 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -842,8 +842,11 @@ public class JavaCompletionUtil { final PsiDocumentManager manager = PsiDocumentManager.getInstance(file.getProject()); manager.commitDocument(manager.getDocument(file)); final PsiReference ref = file.findReferenceAt(offset); - if (ref instanceof PsiJavaCodeReferenceElement) { - JavaCodeStyleManager.getInstance(file.getProject()).shortenClassReferences((PsiJavaCodeReferenceElement)ref); + if (ref != null) { + PsiElement element = ref.getElement(); + if (element != null) { + JavaCodeStyleManager.getInstance(file.getProject()).shortenClassReferences(element); + } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java index 2259d2bcf23c..5684bf8b0765 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java @@ -68,7 +68,7 @@ public class JavaDocCompletionContributor extends CompletionContributor { public JavaDocCompletionContributor() { extend(CompletionType.BASIC, PsiJavaPatterns.psiElement(JavaDocTokenType.DOC_TAG_NAME), new TagChooser()); - extend(CompletionType.BASIC, PsiJavaPatterns.psiElement().inside(PsiDocTagValue.class), new CompletionProvider<CompletionParameters>() { + extend(CompletionType.BASIC, PsiJavaPatterns.psiElement().inside(PsiDocComment.class), new CompletionProvider<CompletionParameters>() { @Override protected void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) { final PsiElement position = parameters.getPosition(); @@ -85,12 +85,7 @@ public class JavaDocCompletionContributor extends CompletionContributor { for (final CompletionElement _item : processor.getResults()) { final Object element = _item.getElement(); - LookupItem item = element instanceof PsiMethod ? new JavaMethodCallElement((PsiMethod)element) { - @Override - public void handleInsert(InsertionContext context) { - new MethodSignatureInsertHandler().handleInsert(context, this); - } - } : (LookupItem)LookupItemUtil.objectToLookupItem(element); + LookupItem item = createLookupItem(element); if (onlyConstants) { Object o = item.getObject(); if (!(o instanceof PsiField)) continue; @@ -109,6 +104,24 @@ public class JavaDocCompletionContributor extends CompletionContributor { JavaCompletionContributor.addAllClasses(parameters, result, new InheritorsHolder(position, result)); } } + + private LookupItem createLookupItem(final Object element) { + if (element instanceof PsiMethod) { + return new JavaMethodCallElement((PsiMethod)element) { + @Override + public void handleInsert(InsertionContext context) { + new MethodSignatureInsertHandler().handleInsert(context, this); + } + }; + } + if (element instanceof PsiClass) { + JavaPsiClassReferenceElement classElement = new JavaPsiClassReferenceElement((PsiClass)element); + classElement.setInsertHandler(JavaClassNameInsertHandler.JAVA_CLASS_INSERT_HANDLER); + return classElement; + } + + return (LookupItem)LookupItemUtil.objectToLookupItem(element); + } }); } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java index 636b0331eee1..612d4704ec10 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java @@ -81,6 +81,7 @@ public class HighlightMethodUtil { String accessModifier = PsiUtil.getAccessModifier(accessLevel); for (MethodSignatureBackedByPsiMethod superMethodSignature : superMethodSignatures) { PsiMethod superMethod = superMethodSignature.getMethod(); + if (method.hasModifierProperty(PsiModifier.ABSTRACT) && !MethodSignatureUtil.isSuperMethod(superMethod, method)) continue; if (!PsiUtil.isAccessible(containingFile.getProject(), superMethod, method, null)) continue; HighlightInfo info = isWeaker(method, modifierList, accessModifier, accessLevel, superMethod, includeRealPositionInfo); if (info != null) return info; @@ -294,9 +295,10 @@ public class HighlightMethodUtil { List<PsiClassType> checkedExceptions, PsiSubstitutor substitutorForDerivedClass) { PsiMethod superMethod = superSignature.getMethod(); PsiSubstitutor substitutorForMethod = MethodSignatureUtil.getSuperMethodSignatureSubstitutor(methodSignature, superSignature); - if (substitutorForMethod == null) return -1; for (int i = 0; i < checkedExceptions.size(); i++) { - PsiType exception = substitutorForDerivedClass.substitute(substitutorForMethod.substitute(checkedExceptions.get(i))); + final PsiClassType checkedEx = checkedExceptions.get(i); + final PsiType substituted = substitutorForMethod != null ? substitutorForMethod.substitute(checkedEx) : TypeConversionUtil.erasure(checkedEx); + PsiType exception = substitutorForDerivedClass.substitute(substituted); if (!isMethodThrows(superMethod, substitutorForMethod, exception, substitutorForDerivedClass)) { return i; } @@ -304,10 +306,10 @@ public class HighlightMethodUtil { return -1; } - private static boolean isMethodThrows(PsiMethod method, PsiSubstitutor substitutorForMethod, PsiType exception, PsiSubstitutor substitutorForDerivedClass) { + private static boolean isMethodThrows(PsiMethod method, @Nullable PsiSubstitutor substitutorForMethod, PsiType exception, PsiSubstitutor substitutorForDerivedClass) { PsiClassType[] thrownExceptions = method.getThrowsList().getReferencedTypes(); for (PsiClassType thrownException1 : thrownExceptions) { - PsiType thrownException = substitutorForMethod.substitute(thrownException1); + PsiType thrownException = substitutorForMethod != null ? substitutorForMethod.substitute(thrownException1) : TypeConversionUtil.erasure(thrownException1); thrownException = substitutorForDerivedClass.substitute(thrownException); if (TypeConversionUtil.isAssignable(thrownException, exception)) return true; } diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/JavaOverrideImplementMemberChooser.java b/java/java-impl/src/com/intellij/codeInsight/generation/JavaOverrideImplementMemberChooser.java index 3708b5ee2214..f304a06ec96c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/JavaOverrideImplementMemberChooser.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/JavaOverrideImplementMemberChooser.java @@ -23,8 +23,10 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.LinkedHashSet; /** * @author Dmitry Batkovich @@ -54,7 +56,9 @@ public class JavaOverrideImplementMemberChooser extends MemberChooser<PsiMethodM if (candidates.isEmpty() && secondary.isEmpty()) return null; final PsiMethodMember[] onlyPrimary = convertToMethodMembers(candidates); - final PsiMethodMember[] all = ArrayUtil.mergeArrays(onlyPrimary, convertToMethodMembers(secondary)); + final LinkedHashSet<CandidateInfo> allCandidates = new LinkedHashSet<CandidateInfo>(candidates); + allCandidates.addAll(secondary); + final PsiMethodMember[] all = convertToMethodMembers(allCandidates); final NotNullLazyValue<PsiMethodWithOverridingPercentMember[]> lazyElementsWithPercent = new NotNullLazyValue<PsiMethodWithOverridingPercentMember[]>() { @NotNull @@ -76,7 +80,11 @@ public class JavaOverrideImplementMemberChooser extends MemberChooser<PsiMethodM javaOverrideImplementMemberChooser.setCopyJavadocVisible(true); if (toImplement) { - javaOverrideImplementMemberChooser.selectElements(onlyPrimary); + if (onlyPrimary.length == 0) { + javaOverrideImplementMemberChooser.selectElements(new ClassMember[] {all[0]}); + } else { + javaOverrideImplementMemberChooser.selectElements(onlyPrimary); + } } if (ApplicationManager.getApplication().isUnitTestMode()) { diff --git a/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java b/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java index a37368b03d86..d5377b8fbff9 100644 --- a/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java +++ b/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java @@ -92,7 +92,7 @@ public abstract class CompilerOutputBaseIndex<K, V> { } } catch (IOException e) { - LOG.error("couldn't initialize index"); + LOG.error("couldn't initialize index", e); throw new RuntimeException(e); } myIndex = index; diff --git a/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputIndexer.java b/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputIndexer.java index e8c5ebc9a771..16275b2108de 100644 --- a/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputIndexer.java +++ b/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputIndexer.java @@ -54,7 +54,7 @@ public class CompilerOutputIndexer extends AbstractProjectComponent { private final Lock myLock = new ReentrantLock(); private final AtomicBoolean myInProgress = new AtomicBoolean(false); - private AtomicBoolean myEnabled = new AtomicBoolean(false); + private volatile boolean myEnabled = false; public static CompilerOutputIndexer getInstance(final Project project) { return project.getComponent(CompilerOutputIndexer.class); @@ -65,7 +65,7 @@ public class CompilerOutputIndexer extends AbstractProjectComponent { } public boolean isEnabled() { - return myEnabled.get(); + return myEnabled; } private ID<String, Long> getFileTimestampsIndexId() { @@ -77,15 +77,16 @@ public class CompilerOutputIndexer extends AbstractProjectComponent { Registry.get(REGISTRY_KEY).addListener(new RegistryValueListener.Adapter() { @Override public void afterValueChanged(final RegistryValue value) { - myEnabled.set(value.asBoolean()); - if (myEnabled.get()) { + final boolean asBoolean = value.asBoolean(); + myEnabled = asBoolean; + if (asBoolean) { doEnable(); } } }, myProject); - myEnabled = new AtomicBoolean(Registry.is(REGISTRY_KEY) || ApplicationManager.getApplication().isUnitTestMode()); - if (myEnabled.get()) { + myEnabled = Registry.is(REGISTRY_KEY); + if (myEnabled) { doEnable(); } } @@ -113,7 +114,7 @@ public class CompilerOutputIndexer extends AbstractProjectComponent { CompilerManager.getInstance(myProject).addCompilationStatusListener(new CompilationStatusAdapter() { @Override public void fileGenerated(final String outputRoot, final String relativePath) { - if (myEnabled.get() && StringUtil.endsWith(relativePath, CompilerOutputFilesUtil.CLASS_FILES_SUFFIX)) { + if (StringUtil.endsWith(relativePath, CompilerOutputFilesUtil.CLASS_FILES_SUFFIX) && myEnabled) { try { doIndexing(new File(outputRoot, relativePath), null); } diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java b/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java index ac8de81cf0f0..18be9cd12246 100644 --- a/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java +++ b/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java @@ -50,7 +50,7 @@ public class JavaCodeBlockModificationListener implements PsiTreeChangePreproces case CHILDREN_CHANGED: // general childrenChanged() event after each change - if (!event.isGenericChildrenChange()) { + if (!event.isGenericChange()) { processChange(event.getParent(), event.getParent(), null); } break; diff --git a/java/java-impl/src/com/intellij/refactoring/extractclass/usageInfo/RemoveField.java b/java/java-impl/src/com/intellij/refactoring/extractclass/usageInfo/RemoveField.java index f77b9bdc43ad..4216b6d8d01d 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractclass/usageInfo/RemoveField.java +++ b/java/java-impl/src/com/intellij/refactoring/extractclass/usageInfo/RemoveField.java @@ -28,6 +28,7 @@ public class RemoveField extends FixableUsageInfo { } public void fixUsage() throws IncorrectOperationException { + field.normalizeDeclaration(); field.delete(); } } diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java index 464c01ba256a..3504ef8dfb3c 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java @@ -224,8 +224,7 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations } protected void duplicateError(@NotNull PsiFile file, @NotNull String externalName, @NotNull String text) { - VirtualFile virtualFile = file.getVirtualFile(); - LOG.error(text + "; for signature: '" + externalName + "' in the file " + (virtualFile != null ? virtualFile.getPresentableUrl() : null)); + LOG.error(text + "; for signature: '" + externalName + "' in the " + file.getVirtualFile()); } @NotNull diff --git a/java/java-tests/java-tests.iml b/java/java-tests/java-tests.iml index ef3e588c0480..cc0afca03321 100644 --- a/java/java-tests/java-tests.iml +++ b/java/java-tests/java-tests.iml @@ -30,7 +30,6 @@ <orderEntry type="module" module-name="java-indexing-api" scope="TEST" /> <orderEntry type="module" module-name="external-system-impl" scope="RUNTIME" /> <orderEntry type="module" module-name="junit_rt" scope="TEST" /> - <orderEntry type="module" module-name="manifest" scope="TEST" /> </component> </module> diff --git a/java/java-tests/testData/codeInsight/completion/javadoc/QualifiedImportedClassReference.java b/java/java-tests/testData/codeInsight/completion/javadoc/QualifiedImportedClassReference.java new file mode 100644 index 000000000000..b99b8be7b692 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/javadoc/QualifiedImportedClassReference.java @@ -0,0 +1,9 @@ +import java.io.*; + +/** + * {@link FileInputStr<caret>} + */ + +class Foo { + +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/javadoc/QualifiedImportedClassReference_after.java b/java/java-tests/testData/codeInsight/completion/javadoc/QualifiedImportedClassReference_after.java new file mode 100644 index 000000000000..537f3cf9ad6b --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/javadoc/QualifiedImportedClassReference_after.java @@ -0,0 +1,9 @@ +import java.io.*; + +/** + * {@link java.io.FileInputStream<caret>} + */ + +class Foo { + +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA67584.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA67584.java new file mode 100644 index 000000000000..e5c5b453abd7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA67584.java @@ -0,0 +1,11 @@ +abstract class A +{ + abstract void foo(); +} + +interface B +{ + abstract void foo(); +} + +abstract class C extends A implements B { } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA87860.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA87860.java new file mode 100644 index 000000000000..540ec4e4195d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA87860.java @@ -0,0 +1,11 @@ +interface A { + <T extends Exception> void foo() throws T; + <T extends Exception> void bar() throws Exception; + void baz() throws Exception; +} + +interface B<T extends Throwable> extends A { + void foo() throws <error descr="'foo()' in 'B' clashes with 'foo()' in 'A'; overridden method does not throw 'T'">T</error>; + void bar() throws <error descr="'bar()' in 'B' clashes with 'bar()' in 'A'; overridden method does not throw 'java.lang.Throwable'">Throwable</error>; + void baz() throws <error descr="'baz()' in 'B' clashes with 'baz()' in 'A'; overridden method does not throw 'java.lang.Throwable'">Throwable</error>; +} diff --git a/java/java-tests/testData/refactoring/extractEnum/normalize/after/EEnum.java b/java/java-tests/testData/refactoring/extractEnum/normalize/after/EEnum.java new file mode 100644 index 000000000000..1a69466c2e3a --- /dev/null +++ b/java/java-tests/testData/refactoring/extractEnum/normalize/after/EEnum.java @@ -0,0 +1,12 @@ +public enum EEnum { + FOO(0), BAR(2); + private int value; + + public int getValue() { + return value; + } + + EEnum(int value) { + this.value = value; + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractEnum/normalize/after/Test.java b/java/java-tests/testData/refactoring/extractEnum/normalize/after/Test.java new file mode 100644 index 000000000000..c38448b383c5 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractEnum/normalize/after/Test.java @@ -0,0 +1,5 @@ +class Test { + void foo() { + System.out.println(EEnum.FOO.getValue()); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractEnum/normalize/after/Usage.java b/java/java-tests/testData/refactoring/extractEnum/normalize/after/Usage.java new file mode 100644 index 000000000000..310fdee953ef --- /dev/null +++ b/java/java-tests/testData/refactoring/extractEnum/normalize/after/Usage.java @@ -0,0 +1,15 @@ +class Usage { + void foo(EEnum i) { + switch (i) { + case FOO: + break; + case BAR: + break; + } + } + + void foobar() { + foo(EEnum.FOO); + foo(EEnum.BAR); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractEnum/normalize/before/Test.java b/java/java-tests/testData/refactoring/extractEnum/normalize/before/Test.java new file mode 100644 index 000000000000..db086475758e --- /dev/null +++ b/java/java-tests/testData/refactoring/extractEnum/normalize/before/Test.java @@ -0,0 +1,6 @@ +class Test { + public static final int FOO = 0, BAR = 2; + void foo() { + System.out.println(FOO); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractEnum/normalize/before/Usage.java b/java/java-tests/testData/refactoring/extractEnum/normalize/before/Usage.java new file mode 100644 index 000000000000..7563c64e1cb5 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractEnum/normalize/before/Usage.java @@ -0,0 +1,15 @@ +class Usage { + void foo(int i) { + switch (i) { + case Test.FOO: + break; + case Test.BAR: + break; + } + } + + void foobar() { + foo(Test.FOO); + foo(Test.BAR); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inheritanceToDelegation/scr20557/after/xxx/SCR20557.java b/java/java-tests/testData/refactoring/inheritanceToDelegation/scr20557/after/xxx/SCR20557.java index 7f586ca713b6..0a0b3cde8887 100644 --- a/java/java-tests/testData/refactoring/inheritanceToDelegation/scr20557/after/xxx/SCR20557.java +++ b/java/java-tests/testData/refactoring/inheritanceToDelegation/scr20557/after/xxx/SCR20557.java @@ -15,20 +15,154 @@ public class SCR20557 { private final MyResultSet myResultSet = new MyResultSet(); + protected abstract Object getObject(int columnIndex, Map<String, Class<?>> map) + throws SQLException; + + protected abstract Object getObject(String columnLabel, Map<String, Class<?>> map) + throws SQLException; + + protected abstract RowId getRowId(int columnIndex) throws SQLException; + + protected abstract RowId getRowId(String columnLabel) throws SQLException; + + protected abstract void updateRowId(int columnIndex, RowId x) throws SQLException; + + protected abstract void updateRowId(String columnLabel, RowId x) throws SQLException; + + protected abstract int getHoldability() throws SQLException; + + protected abstract boolean isClosed() throws SQLException; + + protected abstract void updateNString(int columnIndex, String nString) throws SQLException; + + protected abstract void updateNString(String columnLabel, String nString) throws SQLException; + + protected abstract void updateNClob(int columnIndex, NClob nClob) throws SQLException; + + protected abstract void updateNClob(String columnLabel, NClob nClob) throws SQLException; + + protected abstract NClob getNClob(int columnIndex) throws SQLException; + + protected abstract NClob getNClob(String columnLabel) throws SQLException; + + protected abstract SQLXML getSQLXML(int columnIndex) throws SQLException; + + protected abstract SQLXML getSQLXML(String columnLabel) throws SQLException; + + protected abstract void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException; + + protected abstract void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException; + + protected abstract String getNString(int columnIndex) throws SQLException; + + protected abstract String getNString(String columnLabel) throws SQLException; + + protected abstract Reader getNCharacterStream(int columnIndex) throws SQLException; + + protected abstract Reader getNCharacterStream(String columnLabel) throws SQLException; + + protected abstract void updateNCharacterStream(int columnIndex, + Reader x, + long length) throws SQLException; + + protected abstract void updateNCharacterStream(String columnLabel, + Reader reader, + long length) throws SQLException; + + protected abstract void updateAsciiStream(int columnIndex, + InputStream x, + long length) throws SQLException; + + protected abstract void updateBinaryStream(int columnIndex, + InputStream x, + long length) throws SQLException; + + protected abstract void updateCharacterStream(int columnIndex, + Reader x, + long length) throws SQLException; + + protected abstract void updateAsciiStream(String columnLabel, + InputStream x, + long length) throws SQLException; + + protected abstract void updateBinaryStream(String columnLabel, + InputStream x, + long length) throws SQLException; + + protected abstract void updateCharacterStream(String columnLabel, + Reader reader, + long length) throws SQLException; + + protected abstract void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException; + + protected abstract void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException; + + protected abstract void updateClob(int columnIndex, Reader reader, long length) throws SQLException; + + protected abstract void updateClob(String columnLabel, Reader reader, long length) throws SQLException; + + protected abstract void updateNClob(int columnIndex, Reader reader, long length) throws SQLException; + + protected abstract void updateNClob(String columnLabel, Reader reader, long length) throws SQLException; + + protected abstract void updateNCharacterStream(int columnIndex, + Reader x) throws SQLException; + + protected abstract void updateNCharacterStream(String columnLabel, + Reader reader) throws SQLException; + + protected abstract void updateAsciiStream(int columnIndex, + InputStream x) throws SQLException; + + protected abstract void updateBinaryStream(int columnIndex, + InputStream x) throws SQLException; + + protected abstract void updateCharacterStream(int columnIndex, + Reader x) throws SQLException; + + protected abstract void updateAsciiStream(String columnLabel, + InputStream x) throws SQLException; + + protected abstract void updateBinaryStream(String columnLabel, + InputStream x) throws SQLException; + + protected abstract void updateCharacterStream(String columnLabel, + Reader reader) throws SQLException; + + protected abstract void updateBlob(int columnIndex, InputStream inputStream) throws SQLException; + + protected abstract void updateBlob(String columnLabel, InputStream inputStream) throws SQLException; + + protected abstract void updateClob(int columnIndex, Reader reader) throws SQLException; + + protected abstract void updateClob(String columnLabel, Reader reader) throws SQLException; + + protected abstract void updateNClob(int columnIndex, Reader reader) throws SQLException; + + protected abstract void updateNClob(String columnLabel, Reader reader) throws SQLException; + + protected abstract <T> T getObject(int columnIndex, Class<T> type) throws SQLException; + + protected abstract <T> T getObject(String columnLabel, Class<T> type) throws SQLException; + + protected abstract <T> T unwrap(Class<T> iface) throws SQLException; + + protected abstract boolean isWrapperFor(Class<?> iface) throws SQLException; + public Date getDate(int columnIndex) throws SQLException { return myResultSet.getDate(columnIndex); } - public Date getDate(String columnName) throws SQLException { - return myResultSet.getDate(columnName); + public Date getDate(String columnLabel) throws SQLException { + return myResultSet.getDate(columnLabel); } public Date getDate(int columnIndex, Calendar cal) throws SQLException { return myResultSet.getDate(columnIndex, cal); } - public Date getDate(String columnName, Calendar cal) throws SQLException { - return myResultSet.getDate(columnName, cal); + public Date getDate(String columnLabel, Calendar cal) throws SQLException { + return myResultSet.getDate(columnLabel, cal); } private class MyResultSet implements ResultSet { @@ -528,5 +662,221 @@ public class SCR20557 { public boolean relative(int rows) throws SQLException { return false; } + + public Object getObject(int columnIndex, Map<String, Class<?>> map) throws SQLException { + return SCR20557.this.getObject(columnIndex, map); + } + + public Object getObject(String columnLabel, Map<String, Class<?>> map) throws SQLException { + return SCR20557.this.getObject(columnLabel, map); + } + + public RowId getRowId(int columnIndex) throws SQLException { + return SCR20557.this.getRowId(columnIndex); + } + + public RowId getRowId(String columnLabel) throws SQLException { + return SCR20557.this.getRowId(columnLabel); + } + + public void updateRowId(int columnIndex, RowId x) throws SQLException { + SCR20557.this.updateRowId(columnIndex, x); + } + + public void updateRowId(String columnLabel, RowId x) throws SQLException { + SCR20557.this.updateRowId(columnLabel, x); + } + + public int getHoldability() throws SQLException { + return SCR20557.this.getHoldability(); + } + + public boolean isClosed() throws SQLException { + return SCR20557.this.isClosed(); + } + + public void updateNString(int columnIndex, String nString) throws SQLException { + SCR20557.this.updateNString(columnIndex, nString); + } + + public void updateNString(String columnLabel, String nString) throws SQLException { + SCR20557.this.updateNString(columnLabel, nString); + } + + public void updateNClob(int columnIndex, NClob nClob) throws SQLException { + SCR20557.this.updateNClob(columnIndex, nClob); + } + + public void updateNClob(String columnLabel, NClob nClob) throws SQLException { + SCR20557.this.updateNClob(columnLabel, nClob); + } + + public NClob getNClob(int columnIndex) throws SQLException { + return SCR20557.this.getNClob(columnIndex); + } + + public NClob getNClob(String columnLabel) throws SQLException { + return SCR20557.this.getNClob(columnLabel); + } + + public SQLXML getSQLXML(int columnIndex) throws SQLException { + return SCR20557.this.getSQLXML(columnIndex); + } + + public SQLXML getSQLXML(String columnLabel) throws SQLException { + return SCR20557.this.getSQLXML(columnLabel); + } + + public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException { + SCR20557.this.updateSQLXML(columnIndex, xmlObject); + } + + public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException { + SCR20557.this.updateSQLXML(columnLabel, xmlObject); + } + + public String getNString(int columnIndex) throws SQLException { + return SCR20557.this.getNString(columnIndex); + } + + public String getNString(String columnLabel) throws SQLException { + return SCR20557.this.getNString(columnLabel); + } + + public Reader getNCharacterStream(int columnIndex) throws SQLException { + return SCR20557.this.getNCharacterStream(columnIndex); + } + + public Reader getNCharacterStream(String columnLabel) throws SQLException { + return SCR20557.this.getNCharacterStream(columnLabel); + } + + public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException { + SCR20557.this.updateNCharacterStream(columnIndex, x, length); + } + + public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + SCR20557.this.updateNCharacterStream(columnLabel, reader, length); + } + + public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException { + SCR20557.this.updateAsciiStream(columnIndex, x, length); + } + + public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException { + SCR20557.this.updateBinaryStream(columnIndex, x, length); + } + + public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException { + SCR20557.this.updateCharacterStream(columnIndex, x, length); + } + + public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException { + SCR20557.this.updateAsciiStream(columnLabel, x, length); + } + + public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException { + SCR20557.this.updateBinaryStream(columnLabel, x, length); + } + + public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + SCR20557.this.updateCharacterStream(columnLabel, reader, length); + } + + public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException { + SCR20557.this.updateBlob(columnIndex, inputStream, length); + } + + public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { + SCR20557.this.updateBlob(columnLabel, inputStream, length); + } + + public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { + SCR20557.this.updateClob(columnIndex, reader, length); + } + + public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { + SCR20557.this.updateClob(columnLabel, reader, length); + } + + public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { + SCR20557.this.updateNClob(columnIndex, reader, length); + } + + public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { + SCR20557.this.updateNClob(columnLabel, reader, length); + } + + public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException { + SCR20557.this.updateNCharacterStream(columnIndex, x); + } + + public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException { + SCR20557.this.updateNCharacterStream(columnLabel, reader); + } + + public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException { + SCR20557.this.updateAsciiStream(columnIndex, x); + } + + public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException { + SCR20557.this.updateBinaryStream(columnIndex, x); + } + + public void updateCharacterStream(int columnIndex, Reader x) throws SQLException { + SCR20557.this.updateCharacterStream(columnIndex, x); + } + + public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException { + SCR20557.this.updateAsciiStream(columnLabel, x); + } + + public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException { + SCR20557.this.updateBinaryStream(columnLabel, x); + } + + public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException { + SCR20557.this.updateCharacterStream(columnLabel, reader); + } + + public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { + SCR20557.this.updateBlob(columnIndex, inputStream); + } + + public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { + SCR20557.this.updateBlob(columnLabel, inputStream); + } + + public void updateClob(int columnIndex, Reader reader) throws SQLException { + SCR20557.this.updateClob(columnIndex, reader); + } + + public void updateClob(String columnLabel, Reader reader) throws SQLException { + SCR20557.this.updateClob(columnLabel, reader); + } + + public void updateNClob(int columnIndex, Reader reader) throws SQLException { + SCR20557.this.updateNClob(columnIndex, reader); + } + + public void updateNClob(String columnLabel, Reader reader) throws SQLException { + SCR20557.this.updateNClob(columnLabel, reader); + } + + public <T> T getObject(int columnIndex, Class<T> type) throws SQLException { + return SCR20557.this.getObject(columnIndex, type); + } + + public <T> T getObject(String columnLabel, Class<T> type) throws SQLException { + return SCR20557.this.getObject(columnLabel, type); + } + + public <T> T unwrap(Class<T> iface) throws SQLException { + return SCR20557.this.unwrap(iface); + } + + public boolean isWrapperFor(Class<?> iface) throws SQLException { + return SCR20557.this.isWrapperFor(iface); + } } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.groovy index 5f927147e0f9..2a1aef8aae38 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.groovy @@ -22,6 +22,12 @@ import org.jetbrains.annotations.NotNull public class JavadocCompletionTest extends LightFixtureCompletionTestCase { @Override + protected void tearDown() throws Exception { + CodeStyleSettingsManager.getSettings(getProject()).USE_FQ_CLASS_NAMES_IN_JAVADOC = true + super.tearDown() + } + + @Override protected String getBasePath() { return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/completion/javadoc/"; } @@ -155,12 +161,7 @@ public class JavadocCompletionTest extends LightFixtureCompletionTestCase { public void testShortenClassName() throws Throwable { CodeStyleSettingsManager.getSettings(getProject()).USE_FQ_CLASS_NAMES_IN_JAVADOC = false; - try { - doTest(); - } - finally { - CodeStyleSettingsManager.getSettings(getProject()).USE_FQ_CLASS_NAMES_IN_JAVADOC = true; - } + doTest(); } public void testMethodBeforeSharp() throws Throwable { @@ -171,12 +172,18 @@ public class JavadocCompletionTest extends LightFixtureCompletionTestCase { doTest(); } - public void testShortenClassReference() throws Throwable { doTest(); } + public void testShortenClassReference() throws Throwable { + CodeStyleSettingsManager.getSettings(getProject()).USE_FQ_CLASS_NAMES_IN_JAVADOC = false + doTest() + } public void testQualifiedClassReference() throws Throwable { configureByFile(getTestName(false) + ".java"); myFixture.complete(CompletionType.BASIC, 2); checkResultByFile(getTestName(false) + "_after.java"); } + + public void testQualifiedImportedClassReference() throws Throwable { doTest() } + public void testThrowsNonImported() throws Throwable { configureByFile(getTestName(false) + ".java"); myFixture.complete(CompletionType.BASIC, 2); @@ -269,23 +276,19 @@ class Impl extends Bar implements Foo {} public void testShortenMethodParameterTypes() { CodeStyleSettingsManager.getSettings(getProject()).USE_FQ_CLASS_NAMES_IN_JAVADOC = false - try { - myFixture.addClass("package foo; public class Foo {}") - myFixture.configureByText "a.java", ''' + myFixture.addClass("package foo; public class Foo {}") + myFixture.addClass("package bar; public class Bar {}") + myFixture.configureByText "a.java", ''' import foo.*; +import bar.*; /** - * {@link #go<caret> - */ -class Goo { void goo(Foo foo {} } +* {@link #go<caret> +*/ +class Goo { void goo(Foo foo, Bar bar) {} } ''' - myFixture.completeBasic() - assert myFixture.editor.document.text.contains('@link #goo(Foo)') - } - finally { - CodeStyleSettingsManager.getSettings(getProject()).USE_FQ_CLASS_NAMES_IN_JAVADOC = true - } - + myFixture.completeBasic() + assert myFixture.editor.document.text.contains('@link #goo(Foo, Bar)') } public void testCustomReferenceProvider() throws Exception { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/MethodChainsCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/MethodChainsCompletionTest.java index 176575f31e17..95f221ba5a62 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/MethodChainsCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/MethodChainsCompletionTest.java @@ -10,6 +10,7 @@ import com.intellij.compilerOutputIndex.api.fs.FileVisitorService; import com.intellij.compilerOutputIndex.api.indexer.CompilerOutputIndexer; import com.intellij.ide.util.PropertiesComponent; import com.intellij.mock.MockProgressIndicator; +import com.intellij.openapi.util.registry.Registry; import com.intellij.util.SmartList; import java.io.File; @@ -27,12 +28,14 @@ public class MethodChainsCompletionTest extends AbstractCompilerAwareTest { @Override protected void setUp() throws Exception { + Registry.get(CompilerOutputIndexer.REGISTRY_KEY).setValue(true); super.setUp(); } @Override protected void tearDown() throws Exception { super.tearDown(); + Registry.get(CompilerOutputIndexer.REGISTRY_KEY).setValue(false); } protected String getTestDataPath() { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java index 0333f9ed2769..abd6346e24ff 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -315,6 +315,8 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA67843() { doTest5(false); } public void testAmbiguousTypeParamVsConcrete() { doTest5(false); } public void testRawAssignments() throws Exception { doTest5(false); } + public void testIDEA87860() throws Exception { doTest5(false); } + public void testIDEA67584() throws Exception { doTest5(false); } public void testJavaUtilCollections_NoVerify() throws Exception { PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule())); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractEnumTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractEnumTest.java index b4962fa686a0..48d711b9593e 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractEnumTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractEnumTest.java @@ -124,6 +124,11 @@ public class ExtractEnumTest extends MultiFileTestCase { new RefactoringTestUtil.MemberDescriptor("BAR", PsiField.class, true)); } + public void testNormalize() throws Exception { + doTest(new RefactoringTestUtil.MemberDescriptor("FOO", PsiField.class, true), + new RefactoringTestUtil.MemberDescriptor("BAR", PsiField.class, true)); + } + public void testUnknownSwitchLabel() throws Exception { doTest("Unable to migrate statement to enum constant. 8 can not be replaced with enum", false, new RefactoringTestUtil.MemberDescriptor("FOO", PsiField.class, true), diff --git a/java/java-tests/testSrc/com/intellij/roots/ProjectClasspathTraversingTest.java b/java/java-tests/testSrc/com/intellij/roots/ProjectClasspathTraversingTest.java deleted file mode 100644 index f606a7f541ce..000000000000 --- a/java/java-tests/testSrc/com/intellij/roots/ProjectClasspathTraversingTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2000-2010 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.roots; - -import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.*; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.PathsList; - -/** - * @author nik - */ -@SuppressWarnings({"deprecation"}) -public class ProjectClasspathTraversingTest extends ModuleRootManagerTestCase { - public void testLibrary() throws Exception { - ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary()); - - doTest(ProjectClasspathTraversing.FULL_CLASSPATH, getRtJar(), getJDomJar()); - doTest(ProjectClasspathTraversing.FULL_CLASS_RECURSIVE_WO_JDK, getJDomJar()); - doTest(ProjectClasspathTraversing.FULL_CLASSPATH_RECURSIVE, getRtJar(), getJDomJar()); - doTest(ProjectClasspathTraversing.FULL_CLASSPATH_WITHOUT_JDK_AND_TESTS, getJDomJar()); - doTest(ProjectClasspathTraversing.FULL_CLASSPATH_WITHOUT_TESTS, getRtJar(), getJDomJar()); - } - - public void testModuleOutput() throws Exception { - addSourceRoot(myModule, false); - final VirtualFile output = setModuleOutput(myModule, false); - final VirtualFile testOutput = setModuleOutput(myModule, true); - - doTest(ProjectClasspathTraversing.FULL_CLASSPATH, getRtJar(), testOutput, output); - doTest(ProjectClasspathTraversing.FULL_CLASS_RECURSIVE_WO_JDK, testOutput, output); - doTest(ProjectClasspathTraversing.FULL_CLASSPATH_RECURSIVE, getRtJar(), testOutput, output); - doTest(ProjectClasspathTraversing.FULL_CLASSPATH_WITHOUT_JDK_AND_TESTS, output); - doTest(ProjectClasspathTraversing.FULL_CLASSPATH_WITHOUT_TESTS, getRtJar(), output); - } - - public void testLibraryScope() throws Exception { - ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary(), DependencyScope.TEST, true); - - doTest(ProjectClasspathTraversing.FULL_CLASSPATH, getRtJar(), getJDomJar()); - doTest(ProjectClasspathTraversing.FULL_CLASS_RECURSIVE_WO_JDK, getJDomJar()); - doTest(ProjectClasspathTraversing.FULL_CLASSPATH_RECURSIVE, getRtJar(), getJDomJar()); - doTest(ProjectClasspathTraversing.FULL_CLASSPATH_WITHOUT_JDK_AND_TESTS); - doTest(ProjectClasspathTraversing.FULL_CLASSPATH_WITHOUT_TESTS, getRtJar()); - } - - public void testModuleDependency() throws Exception { - final Module dep = createModule("dep"); - final VirtualFile output = setModuleOutput(dep, false); - final VirtualFile testOutput = setModuleOutput(dep, true); - ModuleRootModificationUtil.addDependency(dep, createJDomLibrary()); - ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false); - - doTest(ProjectClasspathTraversing.FULL_CLASSPATH, getRtJar()); - doTest(ProjectClasspathTraversing.FULL_CLASS_RECURSIVE_WO_JDK, testOutput, output, getJDomJar()); - doTest(ProjectClasspathTraversing.FULL_CLASSPATH_RECURSIVE, getRtJar(), testOutput, output, getJDomJar()); - doTest(ProjectClasspathTraversing.FULL_CLASSPATH_WITHOUT_JDK_AND_TESTS, output, getJDomJar()); - doTest(ProjectClasspathTraversing.FULL_CLASSPATH_WITHOUT_TESTS, getRtJar(), output, getJDomJar()); - } - - private void doTest(ProjectRootsTraversing.RootTraversePolicy policy, VirtualFile... roots) { - assertRoots(ProjectRootsTraversing.collectRoots(myModule, policy), roots); - assertRoots(collectByOrderEnumerator(policy), roots); - } - - private PathsList collectByOrderEnumerator(ProjectRootsTraversing.RootTraversePolicy policy) { - if (policy == ProjectClasspathTraversing.FULL_CLASSPATH) { - return OrderEnumerator.orderEntries(myModule).withoutDepModules().getPathsList(); - } - if (policy == ProjectClasspathTraversing.FULL_CLASS_RECURSIVE_WO_JDK) { - return OrderEnumerator.orderEntries(myModule).withoutSdk().recursively().getPathsList(); - } - if (policy == ProjectClasspathTraversing.FULL_CLASSPATH_RECURSIVE) { - return OrderEnumerator.orderEntries(myModule).recursively().getPathsList(); - } - if (policy == ProjectClasspathTraversing.FULL_CLASSPATH_WITHOUT_JDK_AND_TESTS) { - return OrderEnumerator.orderEntries(myModule).withoutSdk().productionOnly().recursively().getPathsList(); - } - if (policy == ProjectClasspathTraversing.FULL_CLASSPATH_WITHOUT_TESTS) { - return OrderEnumerator.orderEntries(myModule).productionOnly().recursively().getPathsList(); - } - throw new AssertionError(policy); - } -} diff --git a/java/java-tests/testSrc/com/intellij/roots/ProjectRootsTraversingTest.java b/java/java-tests/testSrc/com/intellij/roots/ProjectRootsTraversingTest.java deleted file mode 100644 index c25e1b2cc031..000000000000 --- a/java/java-tests/testSrc/com/intellij/roots/ProjectRootsTraversingTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.intellij.roots; - -import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.DependencyScope; -import com.intellij.openapi.roots.ModuleRootModificationUtil; -import com.intellij.openapi.roots.OrderEnumerator; -import com.intellij.openapi.roots.ProjectRootsTraversing; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.PathsList; - -/** - * @author nik - */ -@SuppressWarnings({"deprecation"}) -public class ProjectRootsTraversingTest extends ModuleRootManagerTestCase { - - public void testLibrary() throws Exception { - ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary()); - doTest(ProjectRootsTraversing.LIBRARIES_AND_JDK, getRtJar(), getJDomJar()); - doTest(ProjectRootsTraversing.PROJECT_LIBRARIES, getJDomJar()); - doTest(ProjectRootsTraversing.PROJECT_SOURCES); - } - - public void testModuleSources() throws Exception { - final VirtualFile srcRoot = addSourceRoot(myModule, false); - final VirtualFile testRoot = addSourceRoot(myModule, true); - - doTest(ProjectRootsTraversing.LIBRARIES_AND_JDK, getRtJar()); - doTest(ProjectRootsTraversing.PROJECT_SOURCES, srcRoot, testRoot); - } - - public void testModuleOutput() throws Exception { - setModuleOutput(myModule, false); - setModuleOutput(myModule, true); - - doTest(ProjectRootsTraversing.LIBRARIES_AND_JDK, getRtJar()); - doTest(ProjectRootsTraversing.PROJECT_SOURCES); - } - - public void testModuleDependency() throws Exception { - final Module dep = createModule("b"); - setModuleOutput(dep, false); - setModuleOutput(dep, true); - addSourceRoot(dep, false); - addSourceRoot(dep, true); - ModuleRootModificationUtil.addDependency(dep, createJDomLibrary()); - ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false); - - doTest(ProjectRootsTraversing.PROJECT_LIBRARIES, getJDomJar()); - doTest(ProjectRootsTraversing.PROJECT_SOURCES); - } - - private void doTest(final ProjectRootsTraversing.RootTraversePolicy policy, VirtualFile... roots) { - assertRoots(ProjectRootsTraversing.collectRoots(myModule, policy), roots); - assertRoots(collectByOrderEnumerator(policy), roots); - } - - private PathsList collectByOrderEnumerator(ProjectRootsTraversing.RootTraversePolicy policy) { - if (policy == ProjectRootsTraversing.LIBRARIES_AND_JDK) { - return OrderEnumerator.orderEntries(myModule).withoutDepModules().withoutModuleSourceEntries().getPathsList(); - } - if (policy == ProjectRootsTraversing.PROJECT_SOURCES) { - return OrderEnumerator.orderEntries(myModule).withoutSdk().withoutLibraries().withoutDepModules().getSourcePathsList(); - } - if (policy == ProjectRootsTraversing.PROJECT_LIBRARIES) { - return OrderEnumerator.orderEntries(myModule).withoutSdk().withoutModuleSourceEntries().recursively().getPathsList(); - } - throw new AssertionError(policy); - } -} diff --git a/java/manifest/src/META-INF/ManifestSupport.xml b/java/manifest/src/META-INF/ManifestSupport.xml new file mode 100644 index 000000000000..d0351b3ba04a --- /dev/null +++ b/java/manifest/src/META-INF/ManifestSupport.xml @@ -0,0 +1,22 @@ +<idea-plugin> + <extensionPoints> + <extensionPoint name="manifest.parser.provider" interface="org.jetbrains.lang.manifest.header.HeaderParserProvider"/> + </extensionPoints> + <extensions defaultExtensionNs="com.intellij"> + <fileTypeFactory implementation="org.jetbrains.lang.manifest.ManifestFileTypeFactory"/> + <lang.parserDefinition language="Manifest" implementationClass="org.jetbrains.lang.manifest.parser.ManifestParserDefinition"/> + <lang.syntaxHighlighterFactory key="Manifest" implementationClass="org.jetbrains.lang.manifest.highlighting.ManifestSyntaxHighlighterFactory"/> + <annotator language="Manifest" implementationClass="org.jetbrains.lang.manifest.highlighting.HeaderAnnotator"/> + <lang.elementManipulator forClass="org.jetbrains.lang.manifest.psi.HeaderValuePart" + implementationClass="org.jetbrains.lang.manifest.psi.impl.HeaderValuePartManipulator"/> + <completion.contributor language="Manifest" implementationClass="org.jetbrains.lang.manifest.completion.ManifestCompletionContributor"/> + <manifest.parser.provider implementation="org.jetbrains.lang.manifest.header.impl.StandardManifestHeaderParsers"/> + + <applicationService serviceImplementation="org.jetbrains.lang.manifest.header.HeaderParserRepository"/> + + <localInspection language="Manifest" displayName="Missing Final New Line" groupName="Manifest" + enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.lang.manifest.highlighting.MissingFinalNewlineInspection"/> + <localInspection language="Manifest" displayName="Unknown or Misspelled Header Name" groupName="Manifest" + enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.lang.manifest.highlighting.MisspelledHeaderInspection"/> + </extensions> +</idea-plugin>
\ No newline at end of file diff --git a/java/mockJDK-1.7/jre/lib/rt.jar b/java/mockJDK-1.7/jre/lib/rt.jar Binary files differindex a5c48d188c90..3a3995e2d9cf 100644 --- a/java/mockJDK-1.7/jre/lib/rt.jar +++ b/java/mockJDK-1.7/jre/lib/rt.jar diff --git a/java/mockJDK-1.7/src.zip b/java/mockJDK-1.7/src.zip Binary files differindex 8c2036694bcd..f84498d42375 100644 --- a/java/mockJDK-1.7/src.zip +++ b/java/mockJDK-1.7/src.zip diff --git a/java/remote-servers/remote-servers-java.iml b/java/remote-servers/api/remote-servers-java-api.iml index 994a29fa3b87..5e59a857cbe0 100644 --- a/java/remote-servers/remote-servers-java.iml +++ b/java/remote-servers/api/remote-servers-java-api.iml @@ -7,14 +7,14 @@ </content> <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> - <orderEntry type="module" module-name="remote-servers-api" /> + <orderEntry type="module" module-name="remote-servers-api" exported="" /> <orderEntry type="module" module-name="debugger-impl" /> <orderEntry type="module" module-name="core-api" /> <orderEntry type="module" module-name="lang-api" /> <orderEntry type="module" module-name="xdebugger-api" /> <orderEntry type="module" module-name="lang-impl" /> <orderEntry type="module" module-name="execution-openapi" /> - <orderEntry type="module" module-name="remote-servers-impl" scope="RUNTIME" /> + <orderEntry type="module" module-name="compiler-impl" /> </component> </module> diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/deployment/ArtifactDeploymentSource.java b/java/remote-servers/api/src/com/intellij/remoteServer/configuration/deployment/ArtifactDeploymentSource.java index f7cfc524112d..f7cfc524112d 100644 --- a/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/deployment/ArtifactDeploymentSource.java +++ b/java/remote-servers/api/src/com/intellij/remoteServer/configuration/deployment/ArtifactDeploymentSource.java diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/deployment/DeploymentSourceUtil.java b/java/remote-servers/api/src/com/intellij/remoteServer/configuration/deployment/JavaDeploymentSourceUtil.java index 72d978f70aee..d096d8eef166 100644 --- a/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/deployment/DeploymentSourceUtil.java +++ b/java/remote-servers/api/src/com/intellij/remoteServer/configuration/deployment/JavaDeploymentSourceUtil.java @@ -16,11 +16,9 @@ package com.intellij.remoteServer.configuration.deployment; import com.intellij.openapi.components.ServiceManager; -import com.intellij.openapi.module.ModulePointer; import com.intellij.openapi.project.Project; import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.artifacts.ArtifactPointer; -import org.jdom.Element; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -29,9 +27,9 @@ import java.util.List; /** * @author nik */ -public abstract class DeploymentSourceUtil { - public static DeploymentSourceUtil getInstance() { - return ServiceManager.getService(DeploymentSourceUtil.class); +public abstract class JavaDeploymentSourceUtil { + public static JavaDeploymentSourceUtil getInstance() { + return ServiceManager.getService(JavaDeploymentSourceUtil.class); } @NotNull @@ -40,11 +38,4 @@ public abstract class DeploymentSourceUtil { @NotNull public abstract List<DeploymentSource> createArtifactDeploymentSources(@NotNull Project project, @NotNull Collection<? extends Artifact> artifacts); - - @NotNull - public abstract ModuleDeploymentSource createModuleDeploymentSource(@NotNull ModulePointer modulePointer); - - public abstract DeploymentSource loadDeploymentSource(@NotNull Element element, @NotNull Project project); - - public abstract void saveDeploymentSource(@NotNull DeploymentSource source, @NotNull Element element, @NotNull Project project); } diff --git a/java/remote-servers/impl/remote-servers-java-impl.iml b/java/remote-servers/impl/remote-servers-java-impl.iml new file mode 100644 index 000000000000..c98f909fbfd8 --- /dev/null +++ b/java/remote-servers/impl/remote-servers-java-impl.iml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$"> + <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="module" module-name="remote-servers-java-api" /> + <orderEntry type="module" module-name="compiler-impl" /> + <orderEntry type="module" module-name="debugger-impl" /> + <orderEntry type="module" module-name="execution-openapi" /> + <orderEntry type="module" module-name="lang-impl" /> + <orderEntry type="module" module-name="remote-servers-impl" scope="RUNTIME" /> + </component> +</module> + diff --git a/java/remote-servers/impl/src/META-INF/RemoteServersJava.xml b/java/remote-servers/impl/src/META-INF/RemoteServersJava.xml new file mode 100644 index 000000000000..cec87d9643f2 --- /dev/null +++ b/java/remote-servers/impl/src/META-INF/RemoteServersJava.xml @@ -0,0 +1,7 @@ +<idea-plugin> + <extensions defaultExtensionNs="com.intellij"> + <applicationService serviceInterface="com.intellij.remoteServer.configuration.deployment.JavaDeploymentSourceUtil" + serviceImplementation="com.intellij.remoteServer.impl.configuration.deployment.JavaDeploymentSourceUtilImpl"/> + <remoteServer.deploymentSource.type implementation="com.intellij.remoteServer.impl.configuration.deployment.ArtifactDeploymentSourceType"/> + </extensions> +</idea-plugin>
\ No newline at end of file diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/ArtifactDeploymentSourceImpl.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/ArtifactDeploymentSourceImpl.java index 6791811689bc..0f401706473e 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/ArtifactDeploymentSourceImpl.java +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/ArtifactDeploymentSourceImpl.java @@ -6,6 +6,7 @@ import com.intellij.packaging.artifacts.ArtifactPointer; import com.intellij.packaging.elements.ArtifactRootElement; import com.intellij.packaging.elements.CompositePackagingElement; import com.intellij.remoteServer.configuration.deployment.ArtifactDeploymentSource; +import com.intellij.remoteServer.configuration.deployment.DeploymentSourceType; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -90,4 +91,10 @@ public class ArtifactDeploymentSourceImpl implements ArtifactDeploymentSource { public int hashCode() { return myPointer.hashCode(); } + + @NotNull + @Override + public DeploymentSourceType<?> getType() { + return DeploymentSourceType.EP_NAME.findExtension(ArtifactDeploymentSourceType.class); + } } diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/ArtifactDeploymentSourceType.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/ArtifactDeploymentSourceType.java new file mode 100644 index 000000000000..292e27241217 --- /dev/null +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/ArtifactDeploymentSourceType.java @@ -0,0 +1,68 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.remoteServer.impl.configuration.deployment; + +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.openapi.project.Project; +import com.intellij.packaging.artifacts.Artifact; +import com.intellij.packaging.artifacts.ArtifactPointerManager; +import com.intellij.packaging.impl.run.BuildArtifactsBeforeRunTaskProvider; +import com.intellij.remoteServer.configuration.deployment.ArtifactDeploymentSource; +import com.intellij.remoteServer.configuration.deployment.DeploymentSourceType; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +/** + * @author nik + */ +public class ArtifactDeploymentSourceType extends DeploymentSourceType<ArtifactDeploymentSource> { + private static final String NAME_ATTRIBUTE = "name"; + + public ArtifactDeploymentSourceType() { + super("artifact"); + } + + @NotNull + @Override + public ArtifactDeploymentSource load(@NotNull Element tag, @NotNull Project project) { + return new ArtifactDeploymentSourceImpl(ArtifactPointerManager.getInstance(project).createPointer(tag.getAttributeValue(NAME_ATTRIBUTE))); + } + + @Override + public void save(@NotNull ArtifactDeploymentSource source, @NotNull Element tag) { + tag.setAttribute(NAME_ATTRIBUTE, source.getArtifactPointer().getArtifactName()); + } + + @Override + public void setBuildBeforeRunTask(@NotNull RunConfiguration configuration, + @NotNull ArtifactDeploymentSource source) { + Artifact artifact = source.getArtifact(); + if (artifact != null) { + BuildArtifactsBeforeRunTaskProvider.setBuildArtifactBeforeRun(configuration.getProject(), configuration, artifact); + } + } + + @Override + public void updateBuildBeforeRunOption(@NotNull JComponent runConfigurationEditorComponent, @NotNull Project project, + @NotNull ArtifactDeploymentSource source, boolean select) { + Artifact artifact = source.getArtifact(); + if (artifact != null) { + BuildArtifactsBeforeRunTaskProvider.setBuildArtifactBeforeRunOption(runConfigurationEditorComponent, project, artifact, select); + } + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeploymentSourceUtilImpl.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/JavaDeploymentSourceUtilImpl.java index 6cc425ee0670..25f2229e9c2a 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeploymentSourceUtilImpl.java +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/JavaDeploymentSourceUtilImpl.java @@ -15,17 +15,13 @@ */ package com.intellij.remoteServer.impl.configuration.deployment; -import com.intellij.openapi.module.ModulePointer; -import com.intellij.openapi.module.ModulePointerManager; import com.intellij.openapi.project.Project; import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.artifacts.ArtifactPointer; import com.intellij.packaging.artifacts.ArtifactPointerManager; import com.intellij.remoteServer.configuration.deployment.ArtifactDeploymentSource; import com.intellij.remoteServer.configuration.deployment.DeploymentSource; -import com.intellij.remoteServer.configuration.deployment.DeploymentSourceUtil; -import com.intellij.remoteServer.configuration.deployment.ModuleDeploymentSource; -import org.jdom.Element; +import com.intellij.remoteServer.configuration.deployment.JavaDeploymentSourceUtil; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -35,7 +31,7 @@ import java.util.List; /** * @author nik */ -public class DeploymentSourceUtilImpl extends DeploymentSourceUtil { +public class JavaDeploymentSourceUtilImpl extends JavaDeploymentSourceUtil { @NotNull @Override public ArtifactDeploymentSource createArtifactDeploymentSource(@NotNull ArtifactPointer artifactPointer) { @@ -53,34 +49,4 @@ public class DeploymentSourceUtilImpl extends DeploymentSourceUtil { } return sources; } - - @Override - @NotNull - public ModuleDeploymentSource createModuleDeploymentSource(@NotNull ModulePointer modulePointer) { - return new ModuleDeploymentSourceImpl(modulePointer); - } - - @Override - public DeploymentSource loadDeploymentSource(@NotNull Element element, @NotNull Project project) { - ArtifactPointerManager artifactPointerManager = ArtifactPointerManager.getInstance(project); - Element artifact = element.getChild("artifact"); - if (artifact != null) { - return createArtifactDeploymentSource(artifactPointerManager.createPointer(artifact.getAttributeValue("name"))); - } - Element module = element.getChild("module"); - ModulePointerManager modulePointerManager = ModulePointerManager.getInstance(project); - return createModuleDeploymentSource(modulePointerManager.create(module.getAttributeValue("name"))); - } - - @Override - public void saveDeploymentSource(@NotNull DeploymentSource source, @NotNull Element element, @NotNull Project project) { - if (source instanceof ArtifactDeploymentSource) { - String artifactName = ((ArtifactDeploymentSource)source).getArtifactPointer().getArtifactName(); - element.addContent(new Element("artifact").setAttribute("name", artifactName)); - } - else if (source instanceof ModuleDeploymentSource) { - String moduleName = ((ModuleDeploymentSource)source).getModulePointer().getModuleName(); - element.addContent(new Element("module").setAttribute("name", moduleName)); - } - } } diff --git a/java/remote-servers/src/com/intellij/remoteServer/impl/runtime/deployment/debug/JavaDebuggerLauncherImpl.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/debug/JavaDebuggerLauncherImpl.java index 3ec24ef56075..3ec24ef56075 100644 --- a/java/remote-servers/src/com/intellij/remoteServer/impl/runtime/deployment/debug/JavaDebuggerLauncherImpl.java +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/debug/JavaDebuggerLauncherImpl.java diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsElementFactory.java b/jps/model-api/src/org/jetbrains/jps/model/JpsElementFactory.java index d4f046194d15..da5fc2b752af 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/JpsElementFactory.java +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsElementFactory.java @@ -23,9 +23,7 @@ import org.jetbrains.jps.model.library.sdk.JpsSdkType; import org.jetbrains.jps.model.library.JpsTypedLibrary; import org.jetbrains.jps.model.library.sdk.JpsSdk; import org.jetbrains.jps.model.library.sdk.JpsSdkReference; -import org.jetbrains.jps.model.module.JpsModule; -import org.jetbrains.jps.model.module.JpsModuleReference; -import org.jetbrains.jps.model.module.JpsModuleType; +import org.jetbrains.jps.model.module.*; import org.jetbrains.jps.service.JpsServiceManager; /** @@ -46,6 +44,9 @@ public abstract class JpsElementFactory { @NotNull JpsSdkType<P> type, @NotNull P properties); @NotNull + public abstract <P extends JpsElement> JpsModuleSourceRoot createModuleSourceRoot(@NotNull String url, @NotNull JpsModuleSourceRootType<P> type, @NotNull P properties); + + @NotNull public abstract JpsModuleReference createModuleReference(@NotNull String moduleName); @NotNull diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java index e11ca1c0fc18..3a1df16d5267 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java @@ -52,6 +52,8 @@ public interface JpsModule extends JpsNamedElement, JpsReferenceableElement<JpsM <P extends JpsElement> JpsModuleSourceRoot addSourceRoot(@NotNull String url, @NotNull JpsModuleSourceRootType<P> rootType, @NotNull P properties); + void addSourceRoot(@NotNull JpsModuleSourceRoot root); + void removeSourceRoot(@NotNull String url, @NotNull JpsModuleSourceRootType rootType); JpsDependenciesList getDependenciesList(); diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementFactoryImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementFactoryImpl.java index 9876c6c3db55..2afdcec93ccc 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementFactoryImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementFactoryImpl.java @@ -28,11 +28,10 @@ import org.jetbrains.jps.model.library.impl.sdk.JpsSdkImpl; import org.jetbrains.jps.model.library.sdk.JpsSdk; import org.jetbrains.jps.model.library.sdk.JpsSdkType; import org.jetbrains.jps.model.library.sdk.JpsSdkReference; -import org.jetbrains.jps.model.module.JpsModule; -import org.jetbrains.jps.model.module.JpsModuleReference; -import org.jetbrains.jps.model.module.JpsModuleType; +import org.jetbrains.jps.model.module.*; import org.jetbrains.jps.model.module.impl.JpsModuleImpl; import org.jetbrains.jps.model.module.impl.JpsModuleReferenceImpl; +import org.jetbrains.jps.model.module.impl.JpsModuleSourceRootImpl; /** * @author nik @@ -73,6 +72,14 @@ public class JpsElementFactoryImpl extends JpsElementFactory { @NotNull @Override + public <P extends JpsElement> JpsModuleSourceRoot createModuleSourceRoot(@NotNull String url, + @NotNull JpsModuleSourceRootType<P> type, + @NotNull P properties) { + return new JpsModuleSourceRootImpl<P>(url, type, properties); + } + + @NotNull + @Override public JpsModuleReference createModuleReference(@NotNull String moduleName) { return new JpsModuleReferenceImpl(moduleName); } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java index 68fa7674ebda..eff6c274eec7 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java @@ -121,7 +121,13 @@ public class JpsModuleImpl<P extends JpsElement> extends JpsNamedCompositeElemen public <P extends JpsElement> JpsModuleSourceRoot addSourceRoot(@NotNull String url, @NotNull JpsModuleSourceRootType<P> rootType, @NotNull P properties) { final JpsModuleSourceRootImpl root = new JpsModuleSourceRootImpl<P>(url, rootType, properties); - return myContainer.getChild(JpsModuleSourceRootRole.ROOT_COLLECTION_ROLE).addChild(root); + addSourceRoot(root); + return root; + } + + @Override + public void addSourceRoot(@NotNull JpsModuleSourceRoot root) { + myContainer.getChild(JpsModuleSourceRootRole.ROOT_COLLECTION_ROLE).addChild(root); } @Override diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelSerializerExtension.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelSerializerExtension.java index a5049e49a4f7..b35b6063301a 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelSerializerExtension.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelSerializerExtension.java @@ -31,6 +31,7 @@ import org.jetbrains.jps.model.serialization.library.JpsLibraryRootTypeSerialize import org.jetbrains.jps.model.serialization.library.JpsSdkPropertiesSerializer; import org.jetbrains.jps.model.serialization.module.JpsModuleClasspathSerializer; import org.jetbrains.jps.model.serialization.module.JpsModulePropertiesSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleSourceRootPropertiesSerializer; import org.jetbrains.jps.model.serialization.runConfigurations.JpsRunConfigurationPropertiesSerializer; import org.jetbrains.jps.service.JpsServiceManager; @@ -97,6 +98,10 @@ public abstract class JpsModelSerializerExtension { return Collections.emptyList(); } + public List<? extends JpsModuleSourceRootPropertiesSerializer<?>> getModuleSourceRootPropertiesSerializers() { + return Collections.emptyList(); + } + @NotNull public List<? extends JpsLibraryPropertiesSerializer<?>> getLibraryPropertiesSerializers() { return Collections.emptyList(); diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelSerializerExtension.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelSerializerExtension.java index fe8eb48de1a7..c4396c4f209c 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelSerializerExtension.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelSerializerExtension.java @@ -21,17 +21,21 @@ import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.JpsElementFactory; import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.model.JpsSimpleElement; import org.jetbrains.jps.model.JpsUrlList; import org.jetbrains.jps.model.java.*; import org.jetbrains.jps.model.library.JpsOrderRootType; import org.jetbrains.jps.model.module.JpsDependencyElement; import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.module.JpsModuleReference; +import org.jetbrains.jps.model.module.JpsModuleSourceRootType; import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension; import org.jetbrains.jps.model.serialization.JpsProjectExtensionSerializer; import org.jetbrains.jps.model.serialization.artifact.JpsPackagingElementSerializer; import org.jetbrains.jps.model.serialization.java.compiler.*; import org.jetbrains.jps.model.serialization.library.JpsLibraryRootTypeSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleSourceRootPropertiesSerializer; import java.util.Arrays; import java.util.List; @@ -79,6 +83,12 @@ public class JpsJavaModelSerializerExtension extends JpsModelSerializerExtension } @Override + public List<? extends JpsModuleSourceRootPropertiesSerializer<?>> getModuleSourceRootPropertiesSerializers() { + return Arrays.asList(new JavaSourceRootPropertiesSerializer(JavaSourceRootType.SOURCE, JpsModuleRootModelSerializer.JAVA_SOURCE_ROOT_TYPE_ID), + new JavaSourceRootPropertiesSerializer(JavaSourceRootType.TEST_SOURCE, JpsModuleRootModelSerializer.JAVA_TEST_ROOT_TYPE_ID)); + } + + @Override public void loadModuleDependencyProperties(JpsDependencyElement dependency, Element entry) { boolean exported = entry.getAttributeValue(EXPORTED_ATTRIBUTE) != null; String scopeName = entry.getAttributeValue(SCOPE_ATTRIBUTE); @@ -287,4 +297,26 @@ public class JpsJavaModelSerializerExtension extends JpsModelSerializerExtension componentTag.setAttribute("jdk-15", Boolean.toString(level.compareTo(LanguageLevel.JDK_1_5) >= 0)); } } + + private static class JavaSourceRootPropertiesSerializer extends JpsModuleSourceRootPropertiesSerializer<JpsSimpleElement<JavaSourceRootProperties>> { + private JavaSourceRootPropertiesSerializer(JpsModuleSourceRootType<JpsSimpleElement<JavaSourceRootProperties>> type, String typeId) { + super(type, typeId); + } + + @Override + public JpsSimpleElement<JavaSourceRootProperties> loadProperties(@NotNull Element sourceRootTag) { + String packagePrefix = StringUtil.notNullize(sourceRootTag.getAttributeValue(JpsModuleRootModelSerializer.PACKAGE_PREFIX_ATTRIBUTE)); + return JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties(packagePrefix)); + } + + @Override + public void saveProperties(@NotNull JpsSimpleElement<JavaSourceRootProperties> properties, @NotNull Element sourceRootTag) { + String isTestSource = Boolean.toString(getType().equals(JavaSourceRootType.TEST_SOURCE)); + sourceRootTag.setAttribute(JpsModuleRootModelSerializer.IS_TEST_SOURCE_ATTRIBUTE, isTestSource); + String packagePrefix = properties.getData().getPackagePrefix(); + if (!packagePrefix.isEmpty()) { + sourceRootTag.setAttribute(JpsModuleRootModelSerializer.PACKAGE_PREFIX_ATTRIBUTE, packagePrefix); + } + } + } } diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleRootModelSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleRootModelSerializer.java index 183ad94d0b8f..e5adc2275384 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleRootModelSerializer.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleRootModelSerializer.java @@ -16,16 +16,14 @@ package org.jetbrains.jps.model.serialization.module; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.text.UniqueNameGenerator; import org.jdom.Element; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.JpsCompositeElement; +import org.jetbrains.jps.model.JpsElement; import org.jetbrains.jps.model.JpsElementFactory; import org.jetbrains.jps.model.JpsElementReference; -import org.jetbrains.jps.model.JpsSimpleElement; -import org.jetbrains.jps.model.java.JavaSourceRootProperties; -import org.jetbrains.jps.model.java.JavaSourceRootType; import org.jetbrains.jps.model.java.JpsJavaSdkType; import org.jetbrains.jps.model.java.JpsJavaSdkTypeWrapper; import org.jetbrains.jps.model.library.JpsLibrary; @@ -37,7 +35,9 @@ import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension; import org.jetbrains.jps.model.serialization.library.JpsLibraryTableSerializer; import org.jetbrains.jps.model.serialization.library.JpsSdkTableSerializer; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import static com.intellij.openapi.util.JDOMUtil.getChildren; @@ -65,6 +65,9 @@ public class JpsModuleRootModelSerializer { public static final String MODULE_LIBRARY_TYPE = "module-library"; public static final String MODULE_TYPE = "module"; public static final String MODULE_NAME_ATTRIBUTE = "module-name"; + private static final String SOURCE_ROOT_TYPE_ATTRIBUTE = "type"; + public static final String JAVA_SOURCE_ROOT_TYPE_ID = "java-source"; + public static final String JAVA_TEST_ROOT_TYPE_ID = "java-test"; private static final String GENERATED_LIBRARY_NAME_PREFIX = "#"; public static void loadRootModel(JpsModule module, @Nullable Element rootModelComponent, @Nullable JpsSdkType<?> projectSdkType) { @@ -74,11 +77,7 @@ public class JpsModuleRootModelSerializer { final String url = contentElement.getAttributeValue(URL_ATTRIBUTE); module.getContentRootsList().addUrl(url); for (Element sourceElement : getChildren(contentElement, SOURCE_FOLDER_TAG)) { - final String sourceUrl = sourceElement.getAttributeValue(URL_ATTRIBUTE); - final String packagePrefix = StringUtil.notNullize(sourceElement.getAttributeValue(PACKAGE_PREFIX_ATTRIBUTE)); - final boolean testSource = Boolean.parseBoolean(sourceElement.getAttributeValue(IS_TEST_SOURCE_ATTRIBUTE)); - final JavaSourceRootType rootType = testSource ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE; - module.addSourceRoot(sourceUrl, rootType, JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties(packagePrefix))); + module.addSourceRoot(loadSourceRoot(sourceElement)); } for (Element excludeElement : getChildren(contentElement, EXCLUDE_FOLDER_TAG)) { module.getExcludeRootsList().addUrl(excludeElement.getAttributeValue(URL_ATTRIBUTE)); @@ -140,6 +139,36 @@ public class JpsModuleRootModelSerializer { } } + @NotNull + public static JpsModuleSourceRoot loadSourceRoot(Element sourceElement) { + final String sourceUrl = sourceElement.getAttributeValue(URL_ATTRIBUTE); + JpsModuleSourceRootPropertiesSerializer<?> serializer = getSourceRootPropertiesSerializer(sourceElement); + return createSourceRoot(sourceUrl, serializer, sourceElement); + } + + @NotNull + private static <P extends JpsElement> JpsModuleSourceRoot createSourceRoot(@NotNull String url, + @NotNull JpsModuleSourceRootPropertiesSerializer<P> serializer, + @NotNull Element sourceElement) { + return JpsElementFactory.getInstance().createModuleSourceRoot(url, serializer.getType(), serializer.loadProperties(sourceElement)); + } + + @NotNull + private static JpsModuleSourceRootPropertiesSerializer<?> getSourceRootPropertiesSerializer(@NotNull Element sourceElement) { + String typeAttribute = sourceElement.getAttributeValue(SOURCE_ROOT_TYPE_ATTRIBUTE); + if (typeAttribute == null) { + typeAttribute = Boolean.parseBoolean(sourceElement.getAttributeValue(IS_TEST_SOURCE_ATTRIBUTE)) ? JAVA_TEST_ROOT_TYPE_ID : JAVA_SOURCE_ROOT_TYPE_ID; + } + for (JpsModelSerializerExtension extension : JpsModelSerializerExtension.getExtensions()) { + for (JpsModuleSourceRootPropertiesSerializer<?> serializer : extension.getModuleSourceRootPropertiesSerializers()) { + if (serializer.getTypeId().equals(typeAttribute)) { + return serializer; + } + } + } + return null; + } + public static void saveRootModel(JpsModule module, Element rootModelElement) { List<JpsModuleSourceRoot> sourceRoots = module.getSourceRoots(); List<String> excludedUrls = getSortedList(module.getExcludeRootsList().getUrls()); @@ -149,20 +178,7 @@ public class JpsModuleRootModelSerializer { rootModelElement.addContent(contentElement); for (JpsModuleSourceRoot root : sourceRoots) { if (FileUtil.startsWith(root.getUrl(), url)) { - Element sourceElement = new Element(SOURCE_FOLDER_TAG); - sourceElement.setAttribute(URL_ATTRIBUTE, root.getUrl()); - JpsModuleSourceRootType<?> type = root.getRootType(); - sourceElement.setAttribute(IS_TEST_SOURCE_ATTRIBUTE, Boolean.toString(type.equals(JavaSourceRootType.TEST_SOURCE))); - if (type instanceof JavaSourceRootType) { - JpsSimpleElement<JavaSourceRootProperties> properties = root.getProperties((JavaSourceRootType)type); - if (properties != null) { - String packagePrefix = properties.getData().getPackagePrefix(); - if (packagePrefix.length() > 0) { - sourceElement.setAttribute(PACKAGE_PREFIX_ATTRIBUTE, packagePrefix); - } - } - } - contentElement.addContent(sourceElement); + saveSourceRoot(contentElement, (JpsTypedModuleSourceRoot<?>)root); } } for (String excludedUrl : excludedUrls) { @@ -225,6 +241,32 @@ public class JpsModuleRootModelSerializer { } } + public static <P extends JpsElement> void saveSourceRoot(Element contentElement, JpsTypedModuleSourceRoot<P> root) { + Element sourceElement = new Element(SOURCE_FOLDER_TAG); + sourceElement.setAttribute(URL_ATTRIBUTE, root.getUrl()); + JpsModuleSourceRootPropertiesSerializer<P> serializer = getSerializer(root.getRootType()); + if (serializer != null) { + String typeId = serializer.getTypeId(); + if (!typeId.equals(JAVA_SOURCE_ROOT_TYPE_ID) && !typeId.equals(JAVA_TEST_ROOT_TYPE_ID)) { + sourceElement.setAttribute(SOURCE_ROOT_TYPE_ATTRIBUTE, typeId); + } + serializer.saveProperties(root.getProperties(), sourceElement); + } + contentElement.addContent(sourceElement); + } + + @Nullable + private static <P extends JpsElement> JpsModuleSourceRootPropertiesSerializer<P> getSerializer(JpsModuleSourceRootType<P> type) { + for (JpsModelSerializerExtension extension : JpsModelSerializerExtension.getExtensions()) { + for (JpsModuleSourceRootPropertiesSerializer<?> serializer : extension.getModuleSourceRootPropertiesSerializers()) { + if (serializer.getType().equals(type)) { + return (JpsModuleSourceRootPropertiesSerializer<P>)serializer; + } + } + } + return null; + } + private static boolean isGeneratedName(String libraryName) { return libraryName.startsWith(GENERATED_LIBRARY_NAME_PREFIX); } diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleSourceRootPropertiesSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleSourceRootPropertiesSerializer.java new file mode 100644 index 000000000000..1190dde27d48 --- /dev/null +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleSourceRootPropertiesSerializer.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.jps.model.serialization.module; + +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElement; +import org.jetbrains.jps.model.module.JpsModuleSourceRootType; +import org.jetbrains.jps.model.serialization.JpsElementPropertiesSerializer; + +/** + * @author nik + */ +public abstract class JpsModuleSourceRootPropertiesSerializer<P extends JpsElement> extends JpsElementPropertiesSerializer<P, JpsModuleSourceRootType<P>> { + public JpsModuleSourceRootPropertiesSerializer(JpsModuleSourceRootType<P> type, String typeId) { + super(type, typeId); + } + + public abstract P loadProperties(@NotNull Element sourceRootTag); + + public abstract void saveProperties(@NotNull P properties, @NotNull Element sourceRootTag); +} diff --git a/platform/bootstrap/src/com/intellij/ide/Bootstrap.java b/platform/bootstrap/src/com/intellij/ide/Bootstrap.java index bc938beda8ff..ff6693c244c5 100644 --- a/platform/bootstrap/src/com/intellij/ide/Bootstrap.java +++ b/platform/bootstrap/src/com/intellij/ide/Bootstrap.java @@ -18,9 +18,6 @@ package com.intellij.ide; import com.intellij.util.lang.UrlClassLoader; import java.lang.reflect.Method; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; /** * @author max @@ -31,11 +28,8 @@ public class Bootstrap { private Bootstrap() { } public static void main(String[] args, String mainClass, String methodName) throws Exception { - main(args, mainClass, methodName, new ArrayList<URL>()); - } + UrlClassLoader newClassLoader = BootstrapClassLoaderUtil.initClassLoader(args.length == 0); - public static void main(String[] args, String mainClass, String methodName, List<URL> classpathElements) throws Exception { - UrlClassLoader newClassLoader = ClassloaderUtil.initClassloader(classpathElements, args.length == 0); WindowsCommandLineProcessor.ourMirrorClass = Class.forName(WindowsCommandLineProcessor.class.getName(), true, newClassLoader); Class<?> klass = Class.forName(PLUGIN_MANAGER, true, newClassLoader); @@ -43,4 +37,4 @@ public class Bootstrap { startMethod.setAccessible(true); startMethod.invoke(null, mainClass, methodName, args); } -}
\ No newline at end of file +} diff --git a/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java b/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java new file mode 100644 index 000000000000..179d0d3c20e3 --- /dev/null +++ b/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java @@ -0,0 +1,196 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @author max + */ +package com.intellij.ide; + +import com.intellij.ide.startup.StartupActionScriptManager; +import com.intellij.idea.Main; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.lang.UrlClassLoader; +import com.intellij.util.text.StringTokenizer; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.regex.Pattern; + +@SuppressWarnings({"HardCodedStringLiteral"}) +public class BootstrapClassLoaderUtil extends ClassUtilCore { + @NonNls public static final String PROPERTY_IGNORE_CLASSPATH = "ignore.classpath"; + + private BootstrapClassLoaderUtil() { } + + private static Logger getLogger() { + return Logger.getInstance(BootstrapClassLoaderUtil.class); + } + + @NotNull + public static UrlClassLoader initClassLoader(boolean updatePlugins) throws Exception { + PathManager.loadProperties(); + + List<URL> classpath = new ArrayList<URL>(); + addParentClasspath(classpath); + addIDEALibraries(classpath); + addAdditionalClassPath(classpath); + UrlClassLoader newClassLoader = UrlClassLoader.build() + .urls(filterClassPath(classpath)) + .nativeLibs("IdeaWin32", "focusKiller", "jumpListBridge") + .allowLock().useCache().get(); + + // prepare plugins + if (updatePlugins && !isLoadingOfExternalPluginsDisabled()) { + try { + StartupActionScriptManager.executeActionScript(); + } + catch (IOException e) { + Main.showMessage("Plugin Installation Error", e); + } + } + + Thread.currentThread().setContextClassLoader(newClassLoader); + return newClassLoader; + } + + private static List<URL> filterClassPath(List<URL> classpathElements) { + String ignoreProperty = System.getProperty(PROPERTY_IGNORE_CLASSPATH); + if (ignoreProperty != null) { + Pattern pattern = Pattern.compile(ignoreProperty); + for (Iterator<URL> i = classpathElements.iterator(); i.hasNext(); ) { + String url = i.next().toExternalForm(); + if (pattern.matcher(url).matches()) { + i.remove(); + } + } + } + return classpathElements; + } + + private static void addParentClasspath(List<URL> aClasspathElements) throws MalformedURLException { + ClassLoader loader = BootstrapClassLoaderUtil.class.getClassLoader(); + if (loader instanceof URLClassLoader) { + URLClassLoader urlClassLoader = (URLClassLoader)loader; + ContainerUtil.addAll(aClasspathElements, urlClassLoader.getURLs()); + } + else { + String loaderName = loader.getClass().getName(); + try { + Class<?> antClassLoaderClass = Class.forName("org.apache.tools.ant.AntClassLoader"); + if (antClassLoaderClass.isInstance(loader) || + "org.apache.tools.ant.AntClassLoader".equals(loaderName) || "org.apache.tools.ant.loader.AntClassLoader2".equals(loaderName)) { + String classpath = (String)antClassLoaderClass + .getDeclaredMethod("getClasspath", ArrayUtil.EMPTY_CLASS_ARRAY) + .invoke(loader, ArrayUtil.EMPTY_OBJECT_ARRAY); + StringTokenizer tokenizer = new StringTokenizer(classpath, File.separator, false); + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + aClasspathElements.add(new File(token).toURI().toURL()); + } + } + else { + getLogger().warn("Unknown class loader: " + loaderName); + } + } + catch (ClassCastException e) { + logException(loaderName, e); + } + catch (ClassNotFoundException e) { + logException(loaderName, e); + } + catch (NoSuchMethodException e) { + logException(loaderName, e); + } + catch (IllegalAccessException e) { + logException(loaderName, e); + } + catch (InvocationTargetException e) { + logException(loaderName, e); + } + } + } + + private static void logException(String loaderName, Exception e) { + getLogger().warn("Unknown class loader '" + loaderName + "'", e); + } + + private static void addIDEALibraries(List<URL> classpathElements) { + final String ideaHomePath = PathManager.getHomePath(); + addAllFromLibFolder(ideaHomePath, classpathElements); + } + + private static void addAllFromLibFolder(String folderPath, List<URL> classPath) { + try { + Class<BootstrapClassLoaderUtil> aClass = BootstrapClassLoaderUtil.class; + String selfRoot = PathManager.getResourceRoot(aClass, "/" + aClass.getName().replace('.', '/') + ".class"); + assert selfRoot != null; + URL selfRootUrl = new File(selfRoot).getAbsoluteFile().toURI().toURL(); + classPath.add(selfRootUrl); + + File libFolder = new File(folderPath + File.separator + "lib"); + addLibraries(classPath, libFolder, selfRootUrl); + + File extLib = new File(libFolder, "ext"); + addLibraries(classPath, extLib, selfRootUrl); + + File antLib = new File(new File(libFolder, "ant"), "lib"); + addLibraries(classPath, antLib, selfRootUrl); + } + catch (MalformedURLException e) { + getLogger().error(e); + } + } + + private static void addLibraries(List<URL> classPath, File fromDir, URL selfRootUrl) throws MalformedURLException { + File[] files = fromDir.listFiles(); + if (files == null) return; + + for (File file : files) { + if (FileUtil.isJarOrZip(file)) { + URL url = file.toURI().toURL(); + if (!selfRootUrl.equals(url)) { + classPath.add(url); + } + } + } + } + + private static void addAdditionalClassPath(List<URL> classPath) { + try { + StringTokenizer tokenizer = new StringTokenizer(System.getProperty("idea.additional.classpath", ""), File.pathSeparator, false); + while (tokenizer.hasMoreTokens()) { + String pathItem = tokenizer.nextToken(); + classPath.add(new File(pathItem).toURI().toURL()); + } + } + catch (MalformedURLException e) { + getLogger().error(e); + } + } +} diff --git a/platform/bootstrap/src/com/intellij/ide/ClassloaderUtil.java b/platform/bootstrap/src/com/intellij/ide/ClassloaderUtil.java deleted file mode 100644 index 801c459303a3..000000000000 --- a/platform/bootstrap/src/com/intellij/ide/ClassloaderUtil.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2000-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @author max - */ -package com.intellij.ide; - -import com.intellij.ide.startup.StartupActionScriptManager; -import com.intellij.idea.Main; -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.util.ArrayUtil; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.lang.UrlClassLoader; -import com.intellij.util.text.StringTokenizer; -import org.jetbrains.annotations.NonNls; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.Iterator; -import java.util.List; -import java.util.regex.Pattern; - -public class ClassloaderUtil extends ClassUtilCore { - @NonNls public static final String PROPERTY_IGNORE_CLASSPATH = "ignore.classpath"; - - private ClassloaderUtil() {} - - public static Logger getLogger() { - return Logger.getInstance("ClassloaderUtil"); - } - - public static UrlClassLoader initClassloader(final List<URL> classpathElements, boolean updatePlugins) throws Exception { - PathManager.loadProperties(); - - addParentClasspath(classpathElements); - addIDEALibraries(classpathElements); - addAdditionalClassPath(classpathElements); - - filterClassPath(classpathElements); - UrlClassLoader newClassLoader = new UrlClassLoader(classpathElements, null, true, true); - - // prepare plugins - if (updatePlugins && !isLoadingOfExternalPluginsDisabled()) { - try { - StartupActionScriptManager.executeActionScript(); - } - catch (IOException e) { - Main.showMessage("Plugin Installation Error", e); - } - } - - Thread.currentThread().setContextClassLoader(newClassLoader); - return newClassLoader; - } - - public static void filterClassPath(final List<URL> classpathElements) { - final String ignoreProperty = System.getProperty(PROPERTY_IGNORE_CLASSPATH); - if (ignoreProperty == null) return; - - final Pattern pattern = Pattern.compile(ignoreProperty); - - for (Iterator<URL> i = classpathElements.iterator(); i.hasNext();) { - URL url = i.next(); - final String u = url.toExternalForm(); - if (pattern.matcher(u).matches()) { - i.remove(); - } - } - } - - public static void addParentClasspath(List<URL> aClasspathElements) throws MalformedURLException { - final ClassLoader loader = ClassloaderUtil.class.getClassLoader(); - if (loader instanceof URLClassLoader) { - URLClassLoader urlClassLoader = (URLClassLoader)loader; - ContainerUtil.addAll(aClasspathElements, urlClassLoader.getURLs()); - } - else { - try { - Class antClassLoaderClass = Class.forName("org.apache.tools.ant.AntClassLoader"); - if (antClassLoaderClass.isInstance(loader) || - loader.getClass().getName().equals("org.apache.tools.ant.AntClassLoader") || - loader.getClass().getName().equals("org.apache.tools.ant.loader.AntClassLoader2")) { - //noinspection HardCodedStringLiteral - final String classpath = - (String)antClassLoaderClass.getDeclaredMethod("getClasspath", ArrayUtil.EMPTY_CLASS_ARRAY).invoke(loader, ArrayUtil.EMPTY_OBJECT_ARRAY); - final StringTokenizer tokenizer = new StringTokenizer(classpath, File.separator, false); - while (tokenizer.hasMoreTokens()) { - final String token = tokenizer.nextToken(); - aClasspathElements.add(new File(token).toURI().toURL()); - } - } - else { - getLogger().warn("Unknown classloader: " + loader.getClass().getName()); - } - } - catch (ClassCastException e) { - getLogger().warn("Unknown classloader [CCE]: " + e.getMessage()); - } - catch (ClassNotFoundException e) { - getLogger().warn("Unknown classloader [CNFE]: " + loader.getClass().getName()); - } - catch (NoSuchMethodException e) { - getLogger().warn("Unknown classloader [NSME]: " + e.getMessage()); - } - catch (IllegalAccessException e) { - getLogger().warn("Unknown classloader [IAE]: " + e.getMessage()); - } - catch (InvocationTargetException e) { - getLogger().warn("Unknown classloader [ITE]: " + e.getMessage()); - } - } - } - - public static void addIDEALibraries(List<URL> classpathElements) { - final String ideaHomePath = PathManager.getHomePath(); - addAllFromLibFolder(ideaHomePath, classpathElements); - } - - @SuppressWarnings({"HardCodedStringLiteral"}) - public static void addAllFromLibFolder(final String aFolderPath, List<URL> classPath) { - try { - final Class<ClassloaderUtil> aClass = ClassloaderUtil.class; - final String selfRoot = PathManager.getResourceRoot(aClass, "/" + aClass.getName().replace('.', '/') + ".class"); - - final URL selfRootUrl = new File(selfRoot).getAbsoluteFile().toURI().toURL(); - classPath.add(selfRootUrl); - - final File libFolder = new File(aFolderPath + File.separator + "lib"); - addLibraries(classPath, libFolder, selfRootUrl); - - final File extLib = new File(libFolder, "ext"); - addLibraries(classPath, extLib, selfRootUrl); - - final File antLib = new File(new File(libFolder, "ant"), "lib"); - addLibraries(classPath, antLib, selfRootUrl); - } - catch (MalformedURLException e) { - getLogger().error(e); - } - } - - public static void addLibraries(List<URL> classPath, File fromDir, final URL selfRootUrl) throws MalformedURLException { - final File[] files = fromDir.listFiles(); - if (files != null) { - for (final File file : files) { - if (!FileUtil.isJarOrZip(file)) { - continue; - } - final URL url = file.toURI().toURL(); - if (selfRootUrl.equals(url)) { - continue; - } - classPath.add(url); - } - } - } - - public static void addAdditionalClassPath(List<URL> classPath) { - try { - //noinspection HardCodedStringLiteral - final StringTokenizer tokenizer = new StringTokenizer(System.getProperty("idea.additional.classpath", ""), File.pathSeparator, false); - while (tokenizer.hasMoreTokens()) { - String pathItem = tokenizer.nextToken(); - classPath.add(new File(pathItem).toURI().toURL()); - } - } - catch (MalformedURLException e) { - getLogger().error(e); - } - } -} diff --git a/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader.java b/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader.java index 9f43eee07f1c..e5e0e9685658 100644 --- a/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader.java +++ b/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.ide.plugins.cl; import com.intellij.diagnostic.PluginException; @@ -48,7 +47,7 @@ public class PluginClassLoader extends UrlClassLoader { final PluginId pluginId, final String version, final File pluginRoot) { - super(urls, null, true, true); + super(build().urls(urls).allowLock().useCache()); myParents = parents; myPluginId = pluginId; myPluginVersion = version; @@ -120,73 +119,44 @@ public class PluginClassLoader extends UrlClassLoader { return aClass != null && aClass.getClassLoader() == this; } + @Override public URL findResource(final String name) { - final long started = myDebugTime ? System.nanoTime():0; + final URL resource = findResourceImpl(name); + if (resource != null) return resource; - try { - final URL resource = findResourceImpl(name); - if (resource != null) { - return resource; - } - - for (ClassLoader parent : myParents) { - final URL parentResource = fetchResource(parent, name); - if (parentResource != null) { - return parentResource; - } - } - return null; - } - finally { - long doneFor = myDebugTime ? (System.nanoTime() - started):0; - if (doneFor > NS_THRESHOLD) { - System.out.println((doneFor / 1000000) + " ms for " + (myPluginId != null?myPluginId.getIdString():null)+ ", resource:"+name); - } + for (ClassLoader parent : myParents) { + final URL parentResource = fetchResource(parent, name); + if (parentResource != null) return parentResource; } + + return null; } @Nullable @Override public InputStream getResourceAsStream(final String name) { - final long started = myDebugTime ? System.nanoTime():0; - - try { - final InputStream stream = super.getResourceAsStream(name); - if (stream != null) return stream; + final InputStream stream = super.getResourceAsStream(name); + if (stream != null) return stream; - for (ClassLoader parent : myParents) { - final InputStream inputStream = parent.getResourceAsStream(name); - if (inputStream != null) return inputStream; - } - - return null; - } - finally { - long doneFor = myDebugTime ? System.nanoTime() - started:0; - if (doneFor > NS_THRESHOLD) { - System.out.println((doneFor/1000000) + " ms for " + (myPluginId != null?myPluginId.getIdString():null)+ ", resource as stream:"+name); - } + for (ClassLoader parent : myParents) { + final InputStream inputStream = parent.getResourceAsStream(name); + if (inputStream != null) return inputStream; } + + return null; } + @Override public Enumeration<URL> findResources(final String name) throws IOException { - final long started = myDebugTime ? System.nanoTime() : 0; - try { - final Enumeration[] resources = new Enumeration[myParents.length + 1]; - resources[0] = super.findResources(name); - for (int idx = 0; idx < myParents.length; idx++) { - resources[idx + 1] = fetchResources(myParents[idx], name); - } - return new CompoundEnumeration<URL>(resources); - } - finally { - long doneFor = myDebugTime ? System.nanoTime() - started:0; - if (doneFor > NS_THRESHOLD) { - System.out.println((doneFor / 1000000) + " ms for " + (myPluginId != null?myPluginId.getIdString():null)+ ", find resources:"+name); - } + final Enumeration[] resources = new Enumeration[myParents.length + 1]; + resources[0] = super.findResources(name); + for (int idx = 0; idx < myParents.length; idx++) { + resources[idx + 1] = fetchResources(myParents[idx], name); } + return new CompoundEnumeration<URL>(resources); } + @Override protected String findLibrary(String libName) { if (myLibDirectory == null) { return null; diff --git a/platform/core-impl/src/com/intellij/pom/tree/events/impl/TreeChangeImpl.java b/platform/core-impl/src/com/intellij/pom/tree/events/impl/TreeChangeImpl.java index 0bf3eed20209..806fe7ca6b44 100644 --- a/platform/core-impl/src/com/intellij/pom/tree/events/impl/TreeChangeImpl.java +++ b/platform/core-impl/src/com/intellij/pom/tree/events/impl/TreeChangeImpl.java @@ -78,6 +78,7 @@ public class TreeChangeImpl implements TreeChange { if(current != null && current.getChangeType() == ChangeInfo.REMOVED){ if(changeInfo.getChangeType() == ChangeInfo.ADD){ if (!(child instanceof LeafElement)) { + // remove/add -> changed changeInfo = ChangeInfoImpl.create(ChangeInfo.CONTENTS_CHANGED, child); ((ChangeInfoImpl)changeInfo).setOldLength(current.getOldLength()); myChanges.put(child, changeInfo); diff --git a/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java b/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java index dd4200a5d80a..871273330f36 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java +++ b/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java @@ -53,7 +53,7 @@ public abstract class AbstractModificationTracker implements PsiTreeChangePrepro } case CHILDREN_CHANGED : - if (event.isGenericChildrenChange()) return; + if (event.isGenericChange()) return; changedInsideCodeBlock = isInsideCodeBlock(event.getParent()); break; diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangeEventImpl.java b/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangeEventImpl.java index d54121f74866..e06474d46298 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangeEventImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangeEventImpl.java @@ -22,7 +22,7 @@ import com.intellij.psi.PsiManager; import com.intellij.psi.PsiTreeChangeEvent; public class PsiTreeChangeEventImpl extends PsiTreeChangeEvent{ - private boolean isGeneric; + private boolean isGenericChange; public enum PsiEventType { BEFORE_CHILD_ADDITION, @@ -115,11 +115,11 @@ public class PsiTreeChangeEventImpl extends PsiTreeChangeEvent{ // this is a generic event which is send after all events for concrete PSI changes in a file (e.g. childAdded(), childReplaced() etc). // this event means "something changed in the file", not the "this PSI element changed in the file" - public boolean isGenericChildrenChange() { - return isGeneric; + public boolean isGenericChange() { + return isGenericChange; } - public void setGeneric(boolean generic) { - isGeneric = generic; + public void setGenericChange(boolean genericChange) { + isGenericChange = genericChange; } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessorBase.java b/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessorBase.java index fad5f62205e9..520a684dbb15 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessorBase.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessorBase.java @@ -43,7 +43,7 @@ public abstract class PsiTreeChangePreprocessorBase implements PsiTreeChangePrep } case CHILDREN_CHANGED : - if (event.isGenericChildrenChange()) { + if (event.isGenericChange()) { return; } changedInsideCodeBlock = isInsideCodeBlock(event.getParent()); diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java index 9519314ef1d8..1452ed0d53a4 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java @@ -83,7 +83,7 @@ public class BlockSupportImpl extends BlockSupport { final FileElement treeFileElement = fileImpl.getTreeElement(); final CharTable charTable = treeFileElement.getCharTable(); - + final int textLength = newFileText.length(); int lengthShift = textLength - treeFileElement.getTextLength(); @@ -184,7 +184,7 @@ public class BlockSupportImpl extends BlockSupport { final FileElement newFileElement = (FileElement)newFile.getNode(); final FileElement oldFileElement = (FileElement)fileImpl.getNode(); - + assert oldFileElement != null && newFileElement != null; DiffLog diffLog = mergeTrees(fileImpl, oldFileElement, newFileElement, indicator); @@ -313,7 +313,7 @@ public class BlockSupportImpl extends BlockSupport { event.setOffset(scope.getTextRange().getStartOffset()); event.setOldLength(scope.getTextLength()); // the "generic" event is being sent on every PSI change. It does not carry any specific info except the fact that "something has changed" - event.setGeneric(isGenericChange); + event.setGenericChange(isGenericChange); manager.beforeChildrenChange(event); } @@ -330,7 +330,7 @@ public class BlockSupportImpl extends BlockSupport { event.setFile(scope); event.setOffset(0); event.setOldLength(oldLength); - event.setGeneric(isGenericChange); + event.setGenericChange(isGenericChange); manager.childrenChanged(event); } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/ChangeUtil.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/ChangeUtil.java index b72ce1e1f1a8..de5a817b4531 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/ChangeUtil.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/ChangeUtil.java @@ -25,14 +25,10 @@ import com.intellij.pom.PomModel; import com.intellij.pom.event.PomModelEvent; import com.intellij.pom.impl.PomTransactionBase; import com.intellij.pom.tree.TreeAspect; -import com.intellij.pom.tree.events.ChangeInfo; import com.intellij.pom.tree.events.TreeChangeEvent; -import com.intellij.pom.tree.events.impl.ChangeInfoImpl; import com.intellij.pom.tree.events.impl.TreeChangeEventImpl; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; -import com.intellij.psi.impl.PsiManagerEx; import com.intellij.psi.impl.source.DummyHolder; import com.intellij.psi.impl.source.DummyHolderFactory; import com.intellij.psi.impl.source.SourceTreeToPsiMap; @@ -50,22 +46,6 @@ public class ChangeUtil { private ChangeUtil() { } - public static void changeElementInPlace(final ASTNode element, final ChangeAction action){ - prepareAndRunChangeAction(new ChangeAction() { - @Override - public void makeChange(TreeChangeEvent destinationTreeChange) { - destinationTreeChange.addElementaryChange(element, ChangeInfoImpl.create(ChangeInfo.CONTENTS_CHANGED, element)); - action.makeChange(destinationTreeChange); - ASTNode node = element; - while (node != null) { - ASTNode parent = node.getTreeParent(); - ((TreeElement)node).clearCaches(); - node = parent; - } - } - }, (TreeElement)element); - } - public static void encodeInformation(TreeElement element) { encodeInformation(element, element); } @@ -180,13 +160,6 @@ public class ChangeUtil { final PomModelEvent event = new PomModelEvent(model); final TreeChangeEvent destinationTreeChange = new TreeChangeEventImpl(treeAspect, changedFile); event.registerChangeSet(treeAspect, destinationTreeChange); - final PsiManagerEx psiManager = (PsiManagerEx) manager; - final PsiFile file = (PsiFile)changedFile.getPsi(); - - //if (file.isPhysical()) { - // SmartPointerManagerImpl.fastenBelts(file, changedElement.getStartOffset()); - //} - action.makeChange(destinationTreeChange); TreeUtil.clearCaches(changedElement); diff --git a/platform/dvcs/dvcs.iml b/platform/dvcs/dvcs.iml index 77c1b31af2d5..2aab285e56da 100644 --- a/platform/dvcs/dvcs.iml +++ b/platform/dvcs/dvcs.iml @@ -10,9 +10,11 @@ <orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="library" name="Groovy" level="project" /> <orderEntry type="module" module-name="core-api" /> - <orderEntry type="module" module-name="testFramework" /> + <orderEntry type="module" module-name="testFramework" scope="TEST" /> <orderEntry type="module" module-name="vcs-impl" /> <orderEntry type="library" name="Guava" level="project" /> + <orderEntry type="module" module-name="core-impl" /> + <orderEntry type="module" module-name="platform-impl" /> </component> </module> diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java index 7ce253cd727d..d9d6916cceb0 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java @@ -270,7 +270,7 @@ public class ExternalSystemApiUtil { } return result; } - + @SuppressWarnings("unchecked") @NotNull public static <T> Collection<DataNode<T>> getChildren(@NotNull DataNode<?> node, @NotNull Key<T> key) { @@ -341,7 +341,7 @@ public class ExternalSystemApiUtil { } }); } - + public static void executeOnEdt(boolean synchronous, @NotNull Runnable task) { if (synchronous) { if (ApplicationManager.getApplication().isDispatchThread()) { @@ -393,7 +393,7 @@ public class ExternalSystemApiUtil { * </pre> * This method allows to differentiate between them (e.g. we don't want to change language level when new module is imported to * an existing project). - * + * * @return <code>true</code> if new project is being imported; <code>false</code> if new module is being imported */ public static boolean isNewProjectConstruction() { @@ -441,7 +441,7 @@ public class ExternalSystemApiUtil { * module. * <p/> * This method tries to find root project's config path assuming that given path points to a sub-project's config path. - * + * * @param externalProjectPath external sub-project's config path * @param externalSystemId target external system * @param project target ide project @@ -554,17 +554,17 @@ public class ExternalSystemApiUtil { /** * There is a possible case that methods of particular object should be executed with classpath different from the one implied - * by the current class' classloader. External system offers {@link ParametersEnhancer#enhanceLocalProcessing(List)} method + * by the current class' class loader. External system offers {@link ParametersEnhancer#enhanceLocalProcessing(List)} method * for defining that custom classpath. * <p/> * It's also possible that particular implementation of {@link ParametersEnhancer} is compiled using dependency to classes * which are provided by the {@link ParametersEnhancer#enhanceLocalProcessing(List) expanded classpath}. E.g. a class * <code>'A'</code> might use method of class <code>'B'</code> and 'A' is located at the current (system/plugin) classpath but - * <code>'B'</code> is not. We need to reload <code>'A'</code> using its expanded classpath then, i.e. create new classloaded + * <code>'B'</code> is not. We need to reload <code>'A'</code> using its expanded classpath then, i.e. create new class loaded * with that expanded classpath and load <code>'A'</code> by it. * <p/> * This method allows to do that. - * + * * @param clazz custom classpath-aware class which instance should be created (is assumed to have a no-args constructor) * @param <T> target type * @return newly created instance of the given class loaded by custom classpath-aware loader @@ -591,7 +591,7 @@ public class ExternalSystemApiUtil { //noinspection unchecked urls.addAll((Collection<? extends URL>)method.invoke(baseLoader)); } - UrlClassLoader loader = new UrlClassLoader(urls, baseLoader.getParent()) { + UrlClassLoader loader = new UrlClassLoader(UrlClassLoader.build().urls(urls).parent(baseLoader.getParent())) { @Override protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { if (name.equals(clazz.getName())) { diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/settings/LocationSettingType.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/settings/LocationSettingType.java index c0679322ac78..305bca7046ef 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/settings/LocationSettingType.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/settings/LocationSettingType.java @@ -24,9 +24,9 @@ public enum LocationSettingType { UNKNOWN("setting.type.location.unknown"), /** User defined gradle location but it's incorrect. */ - EXPLICIT_INCORRECT("setting.type.location.explicit.correct"), + EXPLICIT_INCORRECT("setting.type.location.explicit.incorrect"), - EXPLICIT_CORRECT("setting.type.location.explicit.incorrect"); + EXPLICIT_CORRECT("setting.type.location.explicit.correct"); @NotNull private final String myDescriptionKey; @NotNull private final Color myColor; diff --git a/platform/lang-api/src/com/intellij/codeInspection/ui/ListWrappingTableModel.java b/platform/lang-api/src/com/intellij/codeInspection/ui/ListWrappingTableModel.java index 48db4531f747..3317506dedcb 100644 --- a/platform/lang-api/src/com/intellij/codeInspection/ui/ListWrappingTableModel.java +++ b/platform/lang-api/src/com/intellij/codeInspection/ui/ListWrappingTableModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2007-2010 Bas Leijdekkers + * Copyright 2007-2013 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,15 +47,19 @@ public class ListWrappingTableModel extends AbstractTableModel { } public void addRow(String... values) { - if (list.size() != values.length) { + if (list.size() < values.length) { throw new IllegalArgumentException("number of table columns: " + list.size() + " does not match number of argument " + "columns: " + values.length); } - for (int i = 0; i < values.length; i++) { + int i = 0; + for (; i < values.length; i++) { final String value = values[i]; list.get(i).add(value); } + for (int max = list.size();i < max; i++) { + list.get(i).add(""); + } final int index = list.get(0).size() - 1; fireTableRowsInserted(index, index); } @@ -117,7 +121,7 @@ public class ListWrappingTableModel extends AbstractTableModel { @Override public void setValueAt(Object value, int rowIndex, int columnIndex) { - List<String> strings = list.get(columnIndex); + final List<String> strings = list.get(columnIndex); if (rowIndex >= 0 && rowIndex < strings.size()) { strings.set(rowIndex, String.valueOf(value)); fireTableCellUpdated(rowIndex, columnIndex); diff --git a/platform/lang-api/src/com/intellij/openapi/roots/ProjectClasspathTraversing.java b/platform/lang-api/src/com/intellij/openapi/roots/ProjectClasspathTraversing.java deleted file mode 100644 index 39d71b57f425..000000000000 --- a/platform/lang-api/src/com/intellij/openapi/roots/ProjectClasspathTraversing.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2000-2009 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.roots; - -import com.intellij.openapi.module.Module; -import com.intellij.openapi.util.Comparing; -import com.intellij.util.SmartList; - -import java.util.List; - -/** - * @deprecated use {@link com.intellij.openapi.roots.OrderEnumerator} instead - */ -@Deprecated -public class ProjectClasspathTraversing { - public static final AddModuleOutput ALL_OUTPUTS = new AddModuleOutput(true); - public static final AddModuleOutput GENERAL_OUTPUT = new AddModuleOutput(false); - - /** - * @deprecated use <code>OrderEnumerator.orderEntries().withoutDepModules().getPathsList()</code> instead - */ - public static final ProjectRootsTraversing.RootTraversePolicy FULL_CLASSPATH = - new ProjectRootsTraversing.RootTraversePolicy(ALL_OUTPUTS, ProjectRootsTraversing.RootTraversePolicy.ADD_CLASSES, ProjectRootsTraversing.RootTraversePolicy.ADD_CLASSES, null); - - /** - * @deprecated use <code>OrderEnumerator.orderEntries(module).withoutSdk().recursively().getPathsList()</code> or - * <code>OrderEnumerator.orderEntries(project).withoutSdk().getPathsList()</code> instead - */ - public static final ProjectRootsTraversing.RootTraversePolicy FULL_CLASS_RECURSIVE_WO_JDK = - new ProjectRootsTraversing.RootTraversePolicy(ALL_OUTPUTS, null, ProjectRootsTraversing.RootTraversePolicy.ADD_CLASSES, ProjectRootsTraversing.RootTraversePolicy.RECURSIVE); - - /** - * @deprecated use <code>OrderEnumerator.orderEntries(module).recursively().getPathsList()</code> or - * <code>OrderEnumerator.orderEntries(project).getPathsList()</code> instead - */ - public static final ProjectRootsTraversing.RootTraversePolicy FULL_CLASSPATH_RECURSIVE = - new ProjectRootsTraversing.RootTraversePolicy(ALL_OUTPUTS, ProjectRootsTraversing.RootTraversePolicy.ADD_CLASSES, ProjectRootsTraversing.RootTraversePolicy.ADD_CLASSES, ProjectRootsTraversing.RootTraversePolicy.RECURSIVE); - - /** - * @deprecated use <code>OrderEnumerator.orderEntries(module).withoutSdk().productionOnly().recursively().getPathsList()</code> - * or <code>OrderEnumerator.orderEntries(project).withoutSdk().productionOnly().getPathsList()</code> instead - */ - public static final ProjectRootsTraversing.RootTraversePolicy FULL_CLASSPATH_WITHOUT_JDK_AND_TESTS = - new ProjectRootsTraversing.RootTraversePolicy(GENERAL_OUTPUT, null, ProjectRootsTraversing.RootTraversePolicy.ADD_CLASSES_WITHOUT_TESTS, ProjectRootsTraversing.RootTraversePolicy.RECURSIVE_WITHOUT_TESTS); - - /** - * @deprecated use <code>OrderEnumerator.orderEntries(module).productionOnly().recursively().getPathsList()</code> - * or <code>OrderEnumerator.orderEntries(project).productionOnly().getPathsList()</code> instead - */ - public static final ProjectRootsTraversing.RootTraversePolicy FULL_CLASSPATH_WITHOUT_TESTS = - new ProjectRootsTraversing.RootTraversePolicy(GENERAL_OUTPUT, ProjectRootsTraversing.RootTraversePolicy.ADD_CLASSES_WITHOUT_TESTS, ProjectRootsTraversing.RootTraversePolicy.ADD_CLASSES_WITHOUT_TESTS, ProjectRootsTraversing.RootTraversePolicy.RECURSIVE_WITHOUT_TESTS); - - private ProjectClasspathTraversing() { - } - - public static class AddModuleOutput implements ProjectRootsTraversing.RootTraversePolicy.Visit<ModuleSourceOrderEntry> { - private final boolean myIncludeTests; - - public AddModuleOutput(boolean includeTests) { - myIncludeTests = includeTests; - } - - @Override - public void visit(ModuleSourceOrderEntry sourceEntry, ProjectRootsTraversing.TraverseState traverseState, RootPolicy<ProjectRootsTraversing.TraverseState> policy) { - traverseState.addAllUrls(getOutputs(traverseState.getCurrentModuleManager().getModule())); - } - - public List<String> getOutputs(Module module) { - List<String> outputs = new SmartList<String>(); - final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module); - if (compilerModuleExtension != null) { - String testOutput = compilerModuleExtension.getCompilerOutputUrlForTests(); - if (myIncludeTests && testOutput != null) outputs.add(testOutput); - String output = compilerModuleExtension.getCompilerOutputUrl(); - if ((!Comparing.equal(output, testOutput) || !myIncludeTests) && output != null) { - outputs.add(output); - } - } - return outputs; - } - } -} diff --git a/platform/lang-api/src/com/intellij/openapi/roots/ProjectRootsTraversing.java b/platform/lang-api/src/com/intellij/openapi/roots/ProjectRootsTraversing.java deleted file mode 100644 index 993c14e83072..000000000000 --- a/platform/lang-api/src/com/intellij/openapi/roots/ProjectRootsTraversing.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 2000-2009 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.roots; - -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleManager; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.UserDataHolder; -import com.intellij.openapi.util.UserDataHolderBase; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.PathUtil; -import com.intellij.util.PathsList; -import org.jetbrains.annotations.NotNull; - -import java.util.HashSet; -import java.util.List; - -/** - * @deprecated use {@link com.intellij.openapi.roots.OrderEnumerator} instead - */ -@Deprecated -public class ProjectRootsTraversing { - /** - * @deprecated use <code>OrderEnumerator.orderEntries(module).withoutDepModules().withoutThisModuleContent().getPathsList()</code> - * or <code>OrderEnumerator.orderEntries(project).withoutThisModuleContent().getPathsList()</code> instead - */ - public static final RootTraversePolicy LIBRARIES_AND_JDK = - new RootTraversePolicy(null, RootTraversePolicy.ADD_CLASSES, RootTraversePolicy.ADD_CLASSES, null); - - /** - * @deprecated use <code>OrderEnumerator.orderEntries(module).withoutSdk().withoutLibraries().withoutDepModules().getSourcePathsList()</code> - * or <code>OrderEnumerator.orderEntries(project).withoutSdk().withoutLibraries().getSourcePathsList()</code> instead - */ - public static final RootTraversePolicy PROJECT_SOURCES = - new RootTraversePolicy(RootTraversePolicy.SOURCES, null, null, null); - - /** - * @deprecated use <code>OrderEnumerator.orderEntries().withoutSdk().withoutThisModuleContent().recursively().getPathsList()</code> - * or <code>OrderEnumerator.orderEntries().withoutSdk().withoutThisModuleContent().getPathsList()</code> instead - */ - public static final RootTraversePolicy PROJECT_LIBRARIES = - new RootTraversePolicy(null, null, RootTraversePolicy.ADD_CLASSES, RootTraversePolicy.RECURSIVE); - - private ProjectRootsTraversing() { - } - - public static PathsList collectRoots(Project project, RootTraversePolicy policy) { - PathsList listBuilder = new PathsList(); - collectRoots(project, policy, listBuilder); - return listBuilder; - } - - public static void collectRoots(final Project project, final RootTraversePolicy policy, final PathsList listBuilder) { - traverseOrder(project, policy, new TraverseState(listBuilder)); - } - - public static PathsList collectRoots(Module module, RootTraversePolicy policy) { - final PathsList listBuilder = new PathsList(); - collectRoots(module, policy, listBuilder); - return listBuilder; - } - - public static void collectRoots(Module module, RootTraversePolicy policy, PathsList listBuilder) { - traverseOrder(module, policy, new TraverseState(listBuilder)); - } - - private static void traverseOrder(Project project, RootPolicy<TraverseState> policy, TraverseState state) { - final Module[] sortedModules = ModuleManager.getInstance(project).getSortedModules(); - for (Module sortedModule : sortedModules) { - traverseOrder(sortedModule, policy, state); - } - } - - private static void traverseOrder(Module module, RootPolicy<TraverseState> policy, TraverseState state) { - if (!state.beforeVisitModule(module)) { - return; - } - state.getCurrentModuleManager().processOrder(policy, state); - } - - public static class TraverseState implements UserDataHolder { - private final UserDataHolderBase myUserData = new UserDataHolderBase(); - private final PathsList myCollectedPath; - private final HashSet<Module> myKnownModules = new HashSet<Module>(); - private ModuleRootManager myCurrentModuleManager; - - private TraverseState(PathsList listBuilder) { - myCollectedPath = listBuilder; - } - - public PathsList getCollectedPath() { - return myCollectedPath; - } - - public boolean beforeVisitModule(Module module) { - if (myKnownModules.contains(module)) { - return false; - } - myKnownModules.add(module); - myCurrentModuleManager = ModuleRootManager.getInstance(module); - return true; - } - - public void addAll(VirtualFile... items) { - for (VirtualFile item : items) { - add(item); - } - } - - private void add(VirtualFile item) { - if (item != null && item.isValid()) { - myCollectedPath.add(item); - } - } - - private void addUrl(String url) { - if (url != null) { - myCollectedPath.add(PathUtil.toPresentableUrl(url)); - } - } - - public ModuleRootManager getCurrentModuleManager() { - return myCurrentModuleManager; - } - - public void restoreCurrentModuleManager(ModuleRootManager restored) { - myCurrentModuleManager = restored; - } - - @Override - public <T> T getUserData(@NotNull Key<T> key) { - return myUserData.getUserData(key); - } - - @Override - public <T> void putUserData(@NotNull Key<T> key, T value) { - myUserData.putUserData(key, value); - } - - public void addAllUrls(String[] urls) { - for (String url : urls) addUrl(url); - } - - public void addAllUrls(List<String> urls) { - for (String url : urls) { - addUrl(url); - } - } - } - - public static class RootTraversePolicy extends RootPolicy<TraverseState> { - private static final Key<Boolean> JDK_PROCESSED = Key.create("jdkProcessed"); - private final Visit<ModuleSourceOrderEntry> myVisitSource; - private final Visit<OrderEntry> myVisitJdk; - private final Visit<OrderEntry> myVisitLibrary; - private final Visit<ModuleOrderEntry> myVisitModule; - - public RootTraversePolicy(Visit<ModuleSourceOrderEntry> visitSource, Visit<OrderEntry> visitJdk, Visit<OrderEntry> visitLibrary, Visit<ModuleOrderEntry> visitModule) { - myVisitSource = visitSource; - myVisitJdk = visitJdk; - myVisitLibrary = visitLibrary; - myVisitModule = visitModule; - } - - @Override - public TraverseState visitJdkOrderEntry(JdkOrderEntry jdkOrderEntry, TraverseState state) { - Boolean jdkProcessed = state.getUserData(JDK_PROCESSED); - if (jdkProcessed != null && jdkProcessed.booleanValue()) return state; - state.putUserData(JDK_PROCESSED, Boolean.TRUE); - if (myVisitJdk != null) myVisitJdk.visit(jdkOrderEntry, state, this); - return state; - } - - @Override - public TraverseState visitLibraryOrderEntry(LibraryOrderEntry libraryOrderEntry, TraverseState traverseState) { - if (myVisitLibrary != null) myVisitLibrary.visit(libraryOrderEntry, traverseState, this); - return traverseState; - } - - @Override - public TraverseState visitModuleSourceOrderEntry(ModuleSourceOrderEntry sourceEntry, - TraverseState traverseState) { - if (myVisitSource != null) myVisitSource.visit(sourceEntry, traverseState, this); - return traverseState; - } - - @Override - public TraverseState visitModuleOrderEntry(ModuleOrderEntry moduleOrderEntry, TraverseState traverseState) { - if (myVisitModule != null) myVisitModule.visit(moduleOrderEntry, traverseState, this); - return traverseState; - } - - public Visit<ModuleSourceOrderEntry> getVisitSource() { - return myVisitSource; - } - - public Visit<OrderEntry> getVisitJdk() { - return myVisitJdk; - } - - public Visit<OrderEntry> getVisitLibrary() { - return myVisitLibrary; - } - - public Visit<ModuleOrderEntry> getVisitModule() { - return myVisitModule; - } - - public interface Visit<T extends OrderEntry> { - void visit(T entry, TraverseState state, RootPolicy<TraverseState> policy); - } - - public static final AddModuleSource SOURCES = new AddModuleSource(); - public static final AddModuleSource PRODUCTION_SOURCES = new AddModuleSource(true); - - public static final Visit<OrderEntry> ADD_CLASSES = new Visit<OrderEntry>() { - @Override - public void visit(OrderEntry orderEntry, TraverseState state, RootPolicy<TraverseState> policy) { - state.addAllUrls(orderEntry.getUrls(OrderRootType.CLASSES)); - } - }; - - public static final Visit<OrderEntry> ADD_CLASSES_WITHOUT_TESTS = new Visit<OrderEntry>() { - @Override - public void visit(OrderEntry orderEntry, TraverseState state, RootPolicy<TraverseState> policy) { - if (orderEntry instanceof ExportableOrderEntry) { - final DependencyScope scope = ((ExportableOrderEntry)orderEntry).getScope(); - if (!scope.isForProductionCompile() && !scope.isForProductionRuntime()) return; - } - state.addAllUrls(orderEntry.getUrls(OrderRootType.CLASSES)); - } - }; - - public static final Visit<ModuleOrderEntry> RECURSIVE = new RecursiveModules(true); - public static final Visit<ModuleOrderEntry> RECURSIVE_WITHOUT_TESTS = new RecursiveModules(false); - - public static class AddModuleSource implements Visit<ModuleSourceOrderEntry> { - private final boolean myExcludeTests; - - public AddModuleSource() { - this(false); - } - - public AddModuleSource(final boolean excludeTests) { - myExcludeTests = excludeTests; - } - - @Override - public void visit(ModuleSourceOrderEntry orderEntry, TraverseState state, RootPolicy<TraverseState> policy) { - state.addAll(ModuleRootManager.getInstance(orderEntry.getOwnerModule()).getSourceRoots(!myExcludeTests)); - } - } - - public static class RecursiveModules implements Visit<ModuleOrderEntry> { - private final boolean myIncludeTests; - - public RecursiveModules(boolean includeTests) { - myIncludeTests = includeTests; - } - - @Override - public void visit(ModuleOrderEntry moduleOrderEntry, TraverseState state, RootPolicy<TraverseState> policy) { - final DependencyScope scope = moduleOrderEntry.getScope(); - if (!myIncludeTests && !scope.isForProductionCompile() && !scope.isForProductionRuntime()) return; - Module module = moduleOrderEntry.getModule(); - if (module == null) return; - ModuleRootManager moduleRootManager = state.getCurrentModuleManager(); - traverseOrder(module, policy, state); - state.restoreCurrentModuleManager(moduleRootManager); - } - } - } -} diff --git a/platform/lang-api/src/com/intellij/openapi/roots/RecursiveRootPolicy.java b/platform/lang-api/src/com/intellij/openapi/roots/RecursiveRootPolicy.java deleted file mode 100644 index ed9c59331036..000000000000 --- a/platform/lang-api/src/com/intellij/openapi/roots/RecursiveRootPolicy.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2000-2009 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.roots; - -import com.intellij.openapi.module.Module; -import com.intellij.util.containers.HashSet; - -import java.util.Set; - -/** - * @deprecated use {@link OrderEnumerator#orderEntries(com.intellij.openapi.module.Module)} with {@link OrderEnumerator#recursively()} - * option instead instead - * - * @author yole - */ -public class RecursiveRootPolicy<R> extends RootPolicy<R> { - private final Set<Module> myProcessedModules = new HashSet<Module>(); - - @Override - public R visitModuleOrderEntry(final ModuleOrderEntry moduleOrderEntry, final R value) { - final Module module = moduleOrderEntry.getModule(); - if (module != null && !myProcessedModules.contains(module)) { - myProcessedModules.add(module); - return ModuleRootManager.getInstance(module).processOrder(this, value); - } - return value; - } -} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java index b1db442a5162..f07d31847302 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java @@ -143,7 +143,7 @@ public class PsiChangeHandler extends PsiTreeChangeAdapter implements Disposable @Override public void childrenChanged(@NotNull PsiTreeChangeEvent event) { - if (((PsiTreeChangeEventImpl)event).isGenericChildrenChange()) { + if (((PsiTreeChangeEventImpl)event).isGenericChange()) { return; } queueElement(event.getParent(), true, event); diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java index c69fe0433394..a420eebc9bf7 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java @@ -35,6 +35,7 @@ import com.intellij.openapi.project.Project; import com.intellij.util.ArrayUtil; import com.intellij.util.CommonProcessors; import com.intellij.util.Processor; +import com.intellij.util.SynchronizedCollectConsumer; import com.intellij.util.containers.ConcurrentHashMap; import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; @@ -150,7 +151,7 @@ public abstract class ContributorsBasedGotoByModel implements EfficientChooseByN public String[] getNames(final boolean checkBoxState) { final THashSet<String> allNames = ContainerUtil.newTroveSet(); - processNames(new CommonProcessors.CollectProcessor<String>(allNames), checkBoxState); + processNames(new CommonProcessors.CollectProcessor<String>(Collections.synchronizedCollection(allNames)), checkBoxState); if (LOG.isDebugEnabled()) { LOG.debug("getNames(): (got "+allNames.size()+" elements)"); } diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultFileNavigationContributor.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultFileNavigationContributor.java index 0a4de0b002c6..6addfa11b6d9 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultFileNavigationContributor.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultFileNavigationContributor.java @@ -18,6 +18,7 @@ package com.intellij.ide.util.gotoByName; import com.intellij.navigation.EfficientChooseByNameContributor; import com.intellij.navigation.NavigationItem; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ContentIterator; @@ -76,6 +77,7 @@ public class DefaultFileNavigationContributor implements EfficientChooseByNameCo idSet.set( ((VirtualFileWithId)fileOrDir).getId() ); + ProgressManager.checkCanceled(); return true; } }; diff --git a/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java b/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java index 363c62248b61..e5d645260359 100644 --- a/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java +++ b/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java @@ -107,7 +107,7 @@ public class PsiEventWrapperAspect implements PomModelAspect{ psiEvent.setOffset(treeElement.getStartOffset()); psiEvent.setParent(psiChild); psiEvent.setOldLength(changeByChild.getOldLength()); - psiEvent.setGeneric(treeElement instanceof CompositeElement); + psiEvent.setGenericChange(treeElement instanceof CompositeElement); manager.childrenChanged(psiEvent); break; case ChangeInfo.REMOVED: diff --git a/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletion.java b/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletion.java index 2690a2ac8991..dbf84851abec 100644 --- a/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletion.java +++ b/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletion.java @@ -130,21 +130,6 @@ public class TextFieldWithAutoCompletion<T> extends LanguageTextField { return editor; } - @Nullable - private static String getCompletionShortcutText() { - final AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_CODE_COMPLETION); - if (action != null) { - final ShortcutSet shortcutSet = action.getShortcutSet(); - if (shortcutSet != null) { - final Shortcut[] shortcuts = shortcutSet.getShortcuts(); - if (shortcuts.length > 0) { - return KeymapUtil.getShortcutText(shortcuts[0]); - } - } - } - return null; - } - public static class StringsCompletionProvider extends TextFieldWithAutoCompletionListProvider<String> { @Nullable private final Icon myIcon; diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java index 0448c65d006b..2cac3e55e14a 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java @@ -17,6 +17,7 @@ package com.intellij.util.indexing; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.util.LowMemoryWatcher; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.CommonProcessors; @@ -252,6 +253,7 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu public boolean process(int[] key) { if (!idFilter.contains(key[1])) return true; hashMaskSet.add(key[0]); + ProgressManager.checkCanceled(); return true; } }); diff --git a/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java b/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java index 20f8c249f105..7ad29052fd64 100644 --- a/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java +++ b/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java @@ -16,6 +16,7 @@ package com.intellij.execution.configurations; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.EnvironmentUtil; import com.intellij.util.SmartList; @@ -32,6 +33,7 @@ import java.util.List; public class PathEnvironmentVariableUtil { private static final Logger LOG = Logger.getInstance(PathEnvironmentVariableUtil.class); + private static final String PATH_ENV_VAR_NAME = "PATH"; private PathEnvironmentVariableUtil() { } @@ -52,12 +54,32 @@ public class PathEnvironmentVariableUtil { * listed in PATH environment variable. * * @param fileBaseName file base name - * @param logFindDetails true if extra logging is needed + * @param logDetails true if extra logging is needed * @return {@code File} instance or null if not found */ @Nullable - public static File findInPath(@NotNull String fileBaseName, boolean logFindDetails) { - List<File> exeFiles = findExeFilesInPath(fileBaseName, true, logFindDetails); + public static File findInPath(@NotNull String fileBaseName, boolean logDetails) { + List<File> exeFiles = findExeFilesInPath(fileBaseName, true, logDetails); + return exeFiles.size() > 0 ? exeFiles.get(0) : null; + } + + /** + * Finds an executable file with the specified base name, that is located in a directory + * listed in an original PATH environment variable. + * Original PATH environment variable value is a value returned by <code>System.getenv("PATH")</code>. + * + * @param fileBaseName file base name + * @return {@code File} instance or null if not found + */ + public static File findInOriginalPath(@NotNull String fileBaseName) { + String originalPath; + if (SystemInfo.isMac) { + originalPath = System.getenv(PATH_ENV_VAR_NAME); + } + else { + originalPath = EnvironmentUtil.getValue(PATH_ENV_VAR_NAME); + } + List<File> exeFiles = doFindExeFilesInPath(originalPath, fileBaseName, true, false); return exeFiles.size() > 0 ? exeFiles.get(0) : null; } @@ -76,19 +98,27 @@ public class PathEnvironmentVariableUtil { @NotNull private static List<File> findExeFilesInPath(@NotNull String fileBaseName, boolean stopAfterFirstMatch, - boolean logFindDetails) { - String systemPath = EnvironmentUtil.getValue("PATH"); - if (logFindDetails) { - LOG.info("Finding files in PATH (base name=" + fileBaseName + ", PATH=" + systemPath + ")."); + boolean logDetails) { + String systemPath = EnvironmentUtil.getValue(PATH_ENV_VAR_NAME); + return doFindExeFilesInPath(systemPath, fileBaseName, stopAfterFirstMatch, logDetails); + } + + @NotNull + private static List<File> doFindExeFilesInPath(@Nullable String pathEnvVarValue, + @NotNull String fileBaseName, + boolean stopAfterFirstMatch, + boolean logDetails) { + if (logDetails) { + LOG.info("Finding files in PATH (base name=" + fileBaseName + ", PATH=" + StringUtil.notNullize(pathEnvVarValue) + ")."); } - if (systemPath == null) { + if (pathEnvVarValue == null) { return Collections.emptyList(); } List<File> result = new SmartList<File>(); - List<String> paths = StringUtil.split(systemPath, File.pathSeparator, true, true); + List<String> paths = StringUtil.split(pathEnvVarValue, File.pathSeparator, true, true); for (String path : paths) { File dir = new File(path); - if (logFindDetails) { + if (logDetails) { File file = new File(dir, fileBaseName); LOG.info("path:" + path + ", path.isAbsolute:" + dir.isAbsolute() + ", path.isDirectory:" + dir.isDirectory() + ", file.isFile:" + file.isFile() + ", file.canExecute:" + file.canExecute()); diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeNode.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeNode.java index b01489f05d3a..b66cebe75084 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeNode.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeNode.java @@ -141,7 +141,7 @@ public abstract class AbstractTreeNode<T> extends PresentableNodeDescriptor<Abst return myParentDescriptor; } - public final T getValue() { + public T getValue() { if (myValue == null) { return null; } diff --git a/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java b/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java index 94a0f4b485d9..0b84ea50b956 100644 --- a/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java +++ b/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java @@ -19,13 +19,17 @@ import com.intellij.execution.ExecutionBundle; import com.intellij.execution.ExecutionException; import com.intellij.execution.KillableProcess; import com.intellij.execution.configurations.GeneralCommandLine; +import com.intellij.execution.configurations.PathEnvironmentVariableUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Conditions; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.encoding.EncodingManager; +import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -98,18 +102,6 @@ public final class ScriptRunnerUtil { return outputBuilder.toString(); } - @Nullable - private static File getShell() { - final String shell = System.getenv("SHELL"); - if (shell != null && (shell.contains("bash") || shell.contains("zsh"))) { - File file = new File(shell); - if (file.isAbsolute() && file.isFile() && file.canExecute()) { - return file; - } - } - return null; - } - @NotNull public static OSProcessHandler execute(@NotNull String exePath, @Nullable String workingDirectory, @@ -124,6 +116,42 @@ public final class ScriptRunnerUtil { @Nullable VirtualFile scriptFile, String[] parameters, @Nullable Charset charset) throws ExecutionException { + ExecutionException ex; + try { + return doExecute(exePath, workingDirectory, scriptFile, parameters, charset); + } + catch (ExecutionException e) { + ex = e; + } + boolean rerun = SystemInfo.isMac; + if (rerun) { + File exeFile = new File(exePath); + rerun = !exeFile.isAbsolute(); + } + if (rerun) { + File originalExeFile = PathEnvironmentVariableUtil.findInOriginalPath(exePath); + rerun = originalExeFile == null; + } + if (rerun) { + File exeFile = PathEnvironmentVariableUtil.findInPath(exePath); + if (exeFile != null) { + try { + return doExecute(exeFile.getAbsolutePath(), workingDirectory, scriptFile, parameters, charset); + } catch (ExecutionException e) { + LOG.info("Standby command failed too", e); + throw ex; + } + } + } + throw ex; + } + + @NotNull + private static OSProcessHandler doExecute(@NotNull String exePath, + @Nullable String workingDirectory, + @Nullable VirtualFile scriptFile, + String[] parameters, + @Nullable Charset charset) throws ExecutionException { GeneralCommandLine commandLine = new GeneralCommandLine(); commandLine.setExePath(exePath); commandLine.setPassParentEnvironment(true); @@ -139,10 +167,12 @@ public final class ScriptRunnerUtil { LOG.debug("Command line: " + commandLine.getCommandLineString()); LOG.debug("Command line env: " + commandLine.getEnvironment()); - final OSProcessHandler processHandler = new ColoredProcessHandler(commandLine.createProcess(), commandLine.getCommandLineString(), - charset == null - ? EncodingManager.getInstance().getDefaultCharset() - : charset); + if (charset == null) { + charset = ObjectUtils.notNull(EncodingManager.getInstance().getDefaultCharset(), CharsetToolkit.UTF8_CHARSET); + } + final OSProcessHandler processHandler = new ColoredProcessHandler(commandLine.createProcess(), + commandLine.getCommandLineString(), + charset); if (LOG.isDebugEnabled()) { processHandler.addProcessListener(new ProcessAdapter() { @Override @@ -152,7 +182,6 @@ public final class ScriptRunnerUtil { }); } - //ProcessTerminatedListener.attach(processHandler, project); return processHandler; } diff --git a/platform/platform-impl/src/com/intellij/ide/CharToVKeyMap.java b/platform/platform-impl/src/com/intellij/ide/CharToVKeyMap.java new file mode 100644 index 000000000000..0b8961e655e0 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/CharToVKeyMap.java @@ -0,0 +1,166 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide; + +import java.awt.event.KeyEvent; +import java.util.HashMap; + +/** + * @author Denis Fokin + */ +class CharToVKeyMap { + + private CharToVKeyMap() {} + + private static HashMap<Character, Integer> charToVKeyMap = + new HashMap<Character, Integer>(); + + public static Integer get (Character ch) { + return charToVKeyMap.get(ch); + } + + static { + charToVKeyMap.put(',', KeyEvent.VK_COMMA); + charToVKeyMap.put('-',KeyEvent.VK_MINUS); + charToVKeyMap.put('.',KeyEvent.VK_PERIOD); + charToVKeyMap.put('/',KeyEvent.VK_SLASH); + charToVKeyMap.put(';',KeyEvent.VK_SEMICOLON); + charToVKeyMap.put('=',KeyEvent.VK_EQUALS); + charToVKeyMap.put('[',KeyEvent.VK_OPEN_BRACKET); + charToVKeyMap.put('\\',KeyEvent.VK_BACK_SLASH); + charToVKeyMap.put(']',KeyEvent.VK_CLOSE_BRACKET); + charToVKeyMap.put('`',KeyEvent.VK_BACK_QUOTE); + charToVKeyMap.put('\'',KeyEvent.VK_QUOTE); + charToVKeyMap.put('&',KeyEvent.VK_AMPERSAND); + charToVKeyMap.put('*',KeyEvent.VK_ASTERISK); + charToVKeyMap.put('"',KeyEvent.VK_QUOTEDBL); + charToVKeyMap.put('<',KeyEvent.VK_LESS); + charToVKeyMap.put('>',KeyEvent.VK_GREATER); + charToVKeyMap.put('{',KeyEvent.VK_BRACELEFT); + charToVKeyMap.put('}',KeyEvent.VK_BRACERIGHT); + charToVKeyMap.put('@',KeyEvent.VK_AT); + charToVKeyMap.put(';',KeyEvent.VK_COLON); + charToVKeyMap.put('$',KeyEvent.VK_DOLLAR); + charToVKeyMap.put('€',KeyEvent.VK_EURO_SIGN); + charToVKeyMap.put('!',KeyEvent.VK_EXCLAMATION_MARK); + charToVKeyMap.put('¡',KeyEvent.VK_INVERTED_EXCLAMATION_MARK); + charToVKeyMap.put('(',KeyEvent.VK_LEFT_PARENTHESIS); + charToVKeyMap.put('#',KeyEvent.VK_NUMBER_SIGN); + charToVKeyMap.put('+',KeyEvent.VK_PLUS); + charToVKeyMap.put(')',KeyEvent.VK_RIGHT_PARENTHESIS); + charToVKeyMap.put('_',KeyEvent.VK_UNDERSCORE); + + // All these keys should be similar + + //charToVKeyMap.put('',KeyEvent.VK_ENTER); + //charToVKeyMap.put('',KeyEvent.VK_BACK_SPACE); + //charToVKeyMap.put('',KeyEvent.VK_TAB); + //charToVKeyMap.put('',KeyEvent.VK_CANCEL); + //charToVKeyMap.put('',KeyEvent.VK_CLEAR); + //charToVKeyMap.put('',KeyEvent.VK_SHIFT); + //charToVKeyMap.put('',KeyEvent.VK_CONTROL); + //charToVKeyMap.put('',KeyEvent.VK_ALT); + //charToVKeyMap.put('',KeyEvent.VK_PAUSE); + //charToVKeyMap.put('',KeyEvent.VK_CAPS_LOCK); + //charToVKeyMap.put('',KeyEvent.VK_ESCAPE); + //charToVKeyMap.put('',KeyEvent.VK_SPACE); + //charToVKeyMap.put('',KeyEvent.VK_PAGE_UP); + //charToVKeyMap.put('',KeyEvent.VK_PAGE_DOWN); + //charToVKeyMap.put('',KeyEvent.VK_END); + //charToVKeyMap.put('',KeyEvent.VK_HOME); + //charToVKeyMap.put('',KeyEvent.VK_LEFT); + //charToVKeyMap.put('',KeyEvent.VK_UP); + //charToVKeyMap.put('',KeyEvent.VK_RIGHT); + //charToVKeyMap.put('',KeyEvent.VK_DOWN); + //charToVKeyMap.put('0',KeyEvent.VK_0); + //charToVKeyMap.put('1',KeyEvent.VK_1); + //charToVKeyMap.put('2',KeyEvent.VK_2); + //charToVKeyMap.put('3',KeyEvent.VK_3); + //charToVKeyMap.put('4',KeyEvent.VK_4); + //charToVKeyMap.put('5',KeyEvent.VK_5); + //charToVKeyMap.put('6',KeyEvent.VK_6); + //charToVKeyMap.put('7',KeyEvent.VK_7); + //charToVKeyMap.put('8',KeyEvent.VK_8); + //charToVKeyMap.put('9',KeyEvent.VK_9); + + //charToVKeyMap.put('a',KeyEvent.VK_A); + //charToVKeyMap.put('b',KeyEvent.VK_B); + //charToVKeyMap.put('c',KeyEvent.VK_C); + //charToVKeyMap.put('d',KeyEvent.VK_D); + //charToVKeyMap.put('e',KeyEvent.VK_E); + //charToVKeyMap.put('f',KeyEvent.VK_F); + //charToVKeyMap.put('g',KeyEvent.VK_G); + //charToVKeyMap.put('h',KeyEvent.VK_H); + //charToVKeyMap.put('i',KeyEvent.VK_I); + //charToVKeyMap.put('j',KeyEvent.VK_J); + //charToVKeyMap.put('k',KeyEvent.VK_K); + //charToVKeyMap.put('l',KeyEvent.VK_L); + //charToVKeyMap.put('m',KeyEvent.VK_M); + //charToVKeyMap.put('n',KeyEvent.VK_N); + //charToVKeyMap.put('o',KeyEvent.VK_O); + //charToVKeyMap.put('p',KeyEvent.VK_P); + //charToVKeyMap.put('q',KeyEvent.VK_Q); + //charToVKeyMap.put('r',KeyEvent.VK_R); + //charToVKeyMap.put('s',KeyEvent.VK_S); + //charToVKeyMap.put('t',KeyEvent.VK_T); + //charToVKeyMap.put('u',KeyEvent.VK_U); + //charToVKeyMap.put('v',KeyEvent.VK_V); + //charToVKeyMap.put('w',KeyEvent.VK_W); + //charToVKeyMap.put('x',KeyEvent.VK_X); + //charToVKeyMap.put('y',KeyEvent.VK_Y); + //charToVKeyMap.put('z',KeyEvent.VK_Z); + + //charToVKeyMap.put('A',KeyEvent.VK_A); + //charToVKeyMap.put('B',KeyEvent.VK_B); + //charToVKeyMap.put('C',KeyEvent.VK_C); + //charToVKeyMap.put('D',KeyEvent.VK_D); + //charToVKeyMap.put('E',KeyEvent.VK_E); + //charToVKeyMap.put('F',KeyEvent.VK_F); + //charToVKeyMap.put('G',KeyEvent.VK_G); + //charToVKeyMap.put('H',KeyEvent.VK_H); + //charToVKeyMap.put('I',KeyEvent.VK_I); + //charToVKeyMap.put('J',KeyEvent.VK_J); + //charToVKeyMap.put('K',KeyEvent.VK_K); + //charToVKeyMap.put('L',KeyEvent.VK_L); + //charToVKeyMap.put('M',KeyEvent.VK_M); + //charToVKeyMap.put('N',KeyEvent.VK_N); + //charToVKeyMap.put('O',KeyEvent.VK_O); + //charToVKeyMap.put('P',KeyEvent.VK_P); + //charToVKeyMap.put('Q',KeyEvent.VK_Q); + //charToVKeyMap.put('R',KeyEvent.VK_R); + //charToVKeyMap.put('S',KeyEvent.VK_S); + //charToVKeyMap.put('T',KeyEvent.VK_T); + //charToVKeyMap.put('U',KeyEvent.VK_U); + //charToVKeyMap.put('V',KeyEvent.VK_V); + //charToVKeyMap.put('W',KeyEvent.VK_W); + //charToVKeyMap.put('X',KeyEvent.VK_X); + //charToVKeyMap.put('Y',KeyEvent.VK_Y); + //charToVKeyMap.put('Z',KeyEvent.VK_Z); + //charToVKeyMap.put('',KeyEvent.VK_NUMPAD0); + //charToVKeyMap.put('',KeyEvent.VK_NUMPAD1); + //charToVKeyMap.put('',KeyEvent.VK_NUMPAD2); + //charToVKeyMap.put('',KeyEvent.VK_NUMPAD3); + //charToVKeyMap.put('',KeyEvent.VK_NUMPAD4); + //charToVKeyMap.put('',KeyEvent.VK_NUMPAD5); + //charToVKeyMap.put('',KeyEvent.VK_NUMPAD6); + //charToVKeyMap.put('',KeyEvent.VK_NUMPAD7); + //charToVKeyMap.put('',KeyEvent.VK_NUMPAD8); + //charToVKeyMap.put('',KeyEvent.VK_NUMPAD9); + //charToVKeyMap.put('',KeyEvent.VK_WINDOWS); + //charToVKeyMap.put('',KeyEvent.VK_CONTEXT_MENU); + //charToVKeyMap.put('',KeyEvent.VK_CIRCUMFLEX); + } +} diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java index 8004e5e6b71d..9e67590713ef 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java @@ -321,6 +321,9 @@ public class IdeEventQueue extends EventQueue { @Override public void dispatchEvent(AWTEvent e) { + + fixNonEnglishKeyboardLayouts(e); + e = mapEvent(e); boolean wasInputEvent = myIsInInputEvent; @@ -350,6 +353,20 @@ public class IdeEventQueue extends EventQueue { } } + private static void fixNonEnglishKeyboardLayouts(AWTEvent e) { + if (!Registry.is("ide.non.english.keyboard.layout.fix")) return; + if (e instanceof KeyEvent) { + KeyEvent ke = (KeyEvent)e; + Integer keyCodeFromChar = CharToVKeyMap.get(ke.getKeyChar()); + if (keyCodeFromChar != null) { + if (keyCodeFromChar != ke.getKeyCode()) { + // non-english layout + ke.setKeyCode(keyCodeFromChar); + } + } + } + } + private static AWTEvent mapEvent(AWTEvent e) { if (SystemInfo.isXWindow && e instanceof MouseEvent && ((MouseEvent)e).getButton() > 3) { MouseEvent src = (MouseEvent)e; @@ -631,9 +648,9 @@ public class IdeEventQueue extends EventQueue { public static boolean isMouseEventAhead(@Nullable AWTEvent e) { IdeEventQueue queue = getInstance(); return e instanceof MouseEvent || - queue.peekEvent(MouseEvent.MOUSE_PRESSED) != null || - queue.peekEvent(MouseEvent.MOUSE_RELEASED) != null || - queue.peekEvent(MouseEvent.MOUSE_CLICKED) != null; + queue.peekEvent(MouseEvent.MOUSE_PRESSED) != null || + queue.peekEvent(MouseEvent.MOUSE_RELEASED) != null || + queue.peekEvent(MouseEvent.MOUSE_CLICKED) != null; } private void enterSuspendModeIfNeeded(AWTEvent e) { diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java index d8c1f084d494..2417910a504b 100644 --- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java +++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java @@ -165,7 +165,7 @@ public class StartupUtil { new ProcessBuilder(ideTempFile.getAbsolutePath()).start().waitFor() == 0; } - tempAccessible = tempExecutable && FileUtil.delete(ideTempFile); + tempAccessible = tempExecutable && ideTempFile.delete(); } catch (Exception ignored) { } } @@ -246,7 +246,7 @@ public class StartupUtil { if (SystemInfo.isWin2kOrNewer && !Main.isHeadless()) { try { - System.loadLibrary(SystemInfo.isAMD64 ? "focusKiller64" : "focusKiller"); + System.loadLibrary("focusKiller"); log.info("Using \"FocusKiller\" library to prevent focus stealing."); } catch (Throwable t) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java index 36fbeae94c9b..762aaaa807d4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java @@ -118,11 +118,18 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener, @Override public void updateFinished(@NotNull Document doc) { if (doc != myEditor.getDocument() || myIsInUpdate) return; - if (savedBeforeBulkCaretMarker != null && savedBeforeBulkCaretMarker.isValid() - && savedBeforeBulkCaretMarker.getStartOffset() != myOffset && !myReportCaretMoves) { - moveToOffset(savedBeforeBulkCaretMarker.getStartOffset()); + LOG.assertTrue(!myReportCaretMoves); + + if (savedBeforeBulkCaretMarker != null) { + if(savedBeforeBulkCaretMarker.isValid()) { + if(savedBeforeBulkCaretMarker.getStartOffset() != myOffset) { + moveToOffset(savedBeforeBulkCaretMarker.getStartOffset()); + } + } else if (myOffset > doc.getTextLength()) { + moveToOffset(doc.getTextLength()); + } + releaseBulkCaretMarker(); } - releaseBulkCaretMarker(); } }; ApplicationManager.getApplication().getMessageBus().connect(this).subscribe(DocumentBulkUpdateListener.TOPIC, bulkUpdateListener); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java index ef257f5aa01d..9b31fd72a250 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java @@ -110,7 +110,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse installDnD(); } setOpaque(true); - if (isDestructionFreeMode()) { + if (isDistractionFreeMode()) { editor.getComponent().addComponentListener(new ComponentAdapter(){ @Override public void componentResized(ComponentEvent event) { @@ -287,7 +287,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse if (w == 0) return; - final Color background = isDestructionFreeMode() ? myEditor.getBackgroundColor() : getBackground(); + final Color background = isDistractionFreeMode() ? myEditor.getBackgroundColor() : getBackground(); paintBackground(g, clip, getAnnotationsAreaOffset(), w, background); Color color = myEditor.getColorsScheme().getColor(EditorColors.ANNOTATIONS_COLOR); @@ -327,7 +327,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse x += myTextAnnotationGutterSizes.get(i); } - if (!isDestructionFreeMode()) { + if (!isDistractionFreeMode()) { UIUtil.drawVDottedLine((Graphics2D)g, getAnnotationsAreaOffset() + w - 1, clip.y, clip.y + clip.height, null, getOutlineColor(false)); } } @@ -391,14 +391,14 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse public Color getBackground() { if (myBackgroundColor == null) { EditorColorsScheme colorsScheme = myEditor.getColorsScheme(); - boolean distractionMode = isDestructionFreeMode(); + boolean distractionMode = isDistractionFreeMode(); Color color = distractionMode ? colorsScheme.getDefaultBackground() : colorsScheme.getColor(EditorColors.GUTTER_BACKGROUND); myBackgroundColor = color == null ? new Color(0xF0F0F0) : color; } return myBackgroundColor; } - private boolean isDestructionFreeMode() { + private boolean isDistractionFreeMode() { return Registry.is("editor.distraction.free.mode"); } @@ -571,22 +571,22 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse myTextAnnotationGuttersSize += gutterSize; } - if (myEditor.getComponent().isShowing() && isDestructionFreeMode() && !isMirrored()) { + if (myEditor.getComponent().isShowing() && isDistractionFreeMode() && !isMirrored()) { centerEditorByAnnotationArea(); } } private void centerEditorByAnnotationArea() { + EditorSettings settings = myEditor.getSettings(); + int rightMargin = settings.getRightMargin(myEditor.getProject()); + if (rightMargin <= 0) return; + IdeFrame ideFrame = WindowManager.getInstance().getIdeFrame(myEditor.getProject()); JComponent editorComponent = myEditor.getComponent(); RelativePoint point = new RelativePoint(editorComponent, new Point(0, 0)); Point editorLocationInWindow = point.getPoint(ideFrame.getComponent()); - EditorSettings settings = myEditor.getSettings(); - int rightMargin = settings.getRightMargin(myEditor.getProject()); - if (rightMargin <= 0) return; - int editorLocationX = (int)editorLocationInWindow.getX(); int rightMarginX = rightMargin * EditorUtil.getSpaceWidth(Font.PLAIN, myEditor) + editorLocationX; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java index 232b0c3afeb6..8817e1434ddc 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java @@ -97,8 +97,10 @@ public class IdeFrameImpl extends JFrame implements IdeFrameEx, DataProvider { setBackground(UIUtil.getPanelBackground()); AppUIUtil.updateWindowIcon(this); final Dimension size = ScreenUtil.getMainScreenBounds().getSize(); - size.width-=20; - size.height -=40; + + size.width = Math.min(1400, size.width - 20); + size.height= Math.min(1000, size.height - 40); + setSize(size); setLocationRelativeTo(null); diff --git a/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java b/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java new file mode 100644 index 000000000000..fe649b3a9330 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java @@ -0,0 +1,238 @@ +package com.intellij.ui; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.editor.ex.*; +import com.intellij.openapi.editor.impl.EditorImpl; +import com.intellij.openapi.editor.impl.LineSet; +import com.intellij.openapi.editor.impl.RangeMarkerTree; +import com.intellij.openapi.fileTypes.FileTypes; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.UserDataHolderBase; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.ArrayUtil; +import com.intellij.util.ObjectUtils; +import com.intellij.util.Processor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.table.TableCellRenderer; +import java.awt.*; +import java.beans.PropertyChangeListener; +import java.util.Collections; +import java.util.List; + +/** + * @author gregsh + */ +public abstract class EditorTextFieldCellRenderer extends JPanel implements TableCellRenderer, Disposable { + + private EditorEx myEditor; + + public EditorTextFieldCellRenderer(Disposable parent) { + Disposer.register(parent, this); + } + + protected abstract EditorColorsScheme getColorScheme(); + + protected abstract String getText(JTable table, Object value, int row, int column); + + protected void customizeEditor(EditorEx editor, Object value, boolean selected, int row, int col) { + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + String text = getText(table, value, row, column); + EditorEx editor = getEditor(); + int tableFontSize = table.getFont().getSize(); + if (editor.getColorsScheme().getEditorFontSize() != tableFontSize) { + editor.getColorsScheme().setEditorFontSize(tableFontSize); + } + setText(text); + + if (isSelected) { + ((EditorImpl)editor).setPaintSelection(true); + editor.getColorsScheme().setColor(EditorColors.SELECTION_BACKGROUND_COLOR, table.getSelectionBackground()); + editor.getColorsScheme().setColor(EditorColors.SELECTION_FOREGROUND_COLOR, table.getSelectionForeground()); + editor.getSelectionModel().setSelection(0, editor.getDocument().getTextLength()); + editor.setBackgroundColor(table.getSelectionBackground()); + } + else { + ((EditorImpl)editor).setPaintSelection(false); + editor.getSelectionModel().setSelection(0, 0); + boolean selectedRow = table.getSelectedRowCount() > 0 && table.getSelectedRows()[table.getSelectedRowCount() - 1] == row; + editor.setBackgroundColor(!selectedRow ? table.getBackground() : getColorScheme().getColor(EditorColors.CARET_ROW_COLOR)); + } + customizeEditor(editor, value, isSelected, row, column); + return this; + } + + @NotNull + private EditorEx getEditor() { + if (myEditor != null) return myEditor; + + // reuse EditorTextField initialization logic + EditorTextField field = new EditorTextField(new MyDocument(), null, FileTypes.PLAIN_TEXT); + field.setSupplementary(true); + field.addNotify(); // creates editor + + EditorEx editor = (EditorEx)ObjectUtils.assertNotNull(field.getEditor()); + editor.setRendererMode(true); + + editor.setColorsScheme(editor.createBoundColorSchemeDelegate(getColorScheme())); + editor.getColorsScheme().setColor(EditorColors.CARET_ROW_COLOR, null); + + editor.getScrollPane().setBorder(null); + + add(editor.getContentComponent()); + + myEditor = editor; + return myEditor; + } + + @Override + public void dispose() { + if (myEditor != null) { + EditorFactory.getInstance().releaseEditor(myEditor); + } + } + + protected void setText(String text) { + EditorEx editor = getEditor(); + editor.getMarkupModel().removeAllHighlighters(); + + editor.getDocument().setText(text); + editor.getHighlighter().setText(text); + ((EditorImpl)editor).resetSizes(); + } + + // BEGIN no validation methods -------------- + @Override + public void doLayout() { + if (getComponentCount() != 1) return; + getComponent(0).setBounds(0, 0, getWidth(), getHeight()); + } + + @Override + public Dimension getPreferredSize() { + if (getComponentCount() != 1) return super.getPreferredSize(); + return getComponent(0).getPreferredSize(); + } + + public void invalidate() { + } + + public void validate() { + doLayout(); + } + + public void revalidate() { + } + + public void repaint(long tm, int x, int y, int width, int height) { + } + + public void repaint(Rectangle r) { + } + + public void repaint() { + } + +// END no validation methods -------------- + + private static class MyDocument extends UserDataHolderBase implements DocumentEx { + + RangeMarkerTree<RangeMarkerEx> myRangeMarkers = new RangeMarkerTree<RangeMarkerEx>(this) {}; + LineSet myLineSet = new LineSet(); + + char[] myChars = ArrayUtil.EMPTY_CHAR_ARRAY; + String myString = ""; + + @Override + public void setText(@NotNull CharSequence text) { + String s = StringUtil.convertLineSeparators(text.toString()); + myChars = new char[s.length()]; + s.getChars(0, s.length(), myChars, 0); + myString = new String(myChars); + myLineSet.documentCreated(this); + } + + @Override + public void setStripTrailingSpacesEnabled(boolean isEnabled) { + } + + @NotNull + @Override + public LineIterator createLineIterator() { + return myLineSet.createIterator(); + } + + @Override public void setModificationStamp(long modificationStamp) { } + @Override public void addEditReadOnlyListener(@NotNull EditReadOnlyListener listener) { } + @Override public void removeEditReadOnlyListener(@NotNull EditReadOnlyListener listener) { } + @Override public void replaceText(@NotNull CharSequence chars, long newModificationStamp) { } + @Override public void moveText(int srcStart, int srcEnd, int dstOffset) { } + @Override public int getListenersCount() { return 0; } + @Override public void suppressGuardedExceptions() { } + @Override public void unSuppressGuardedExceptions() { } + @Override public boolean isInEventsHandling() { return false; } + @Override public void clearLineModificationFlags() { } + @Override public boolean removeRangeMarker(@NotNull RangeMarkerEx rangeMarker) { return myRangeMarkers.removeInterval(rangeMarker); } + + @Override + public void registerRangeMarker(@NotNull RangeMarkerEx rangeMarker, + int start, + int end, + boolean greedyToLeft, + boolean greedyToRight, + int layer) { + myRangeMarkers.addInterval(rangeMarker, start, end, greedyToLeft, greedyToRight, layer); + } + + @Override public boolean isInBulkUpdate() { return false; } + @Override public void setInBulkUpdate(boolean value) { } + @NotNull @Override public List<RangeMarker> getGuardedBlocks() { return Collections.emptyList(); } + @Override public boolean processRangeMarkers(@NotNull Processor<RangeMarker> processor) { return myRangeMarkers.process(processor); } + @Override public boolean processRangeMarkersOverlappingWith(int start, int end, @NotNull Processor<RangeMarker> processor) { return myRangeMarkers.processOverlappingWith(start, end, processor); } + @Override public String getText() { return myString; } + @NotNull @Override public String getText(@NotNull TextRange range) { return range.substring(getText()); } + @NotNull @Override public CharSequence getCharsSequence() { return myString; } + @NotNull @Override public char[] getChars() { return myChars; } + @Override public int getTextLength() { return myChars.length; } + @Override public int getLineCount() { return myLineSet.findLineIndex(myChars.length) + 1; } + @Override public int getLineNumber(int offset) { return myLineSet.findLineIndex(offset); } + @Override public int getLineStartOffset(int line) { return myChars.length == 0 ? 0 : myLineSet.getLineStart(line); } + @Override public int getLineEndOffset(int line) { return myChars.length == 0? 0 : myLineSet.getLineEnd(line); } + @Override public void insertString(int offset, @NotNull CharSequence s) { } + @Override public void deleteString(int startOffset, int endOffset) { } + @Override public void replaceString(int startOffset, int endOffset, @NotNull CharSequence s) { } + @Override public boolean isWritable() { return false; } + @Override public long getModificationStamp() { return 0; } + @Override public void fireReadOnlyModificationAttempt() { } + @Override public void addDocumentListener(@NotNull DocumentListener listener) { } + @Override public void addDocumentListener(@NotNull DocumentListener listener, @NotNull Disposable parentDisposable) { } + @Override public void removeDocumentListener(@NotNull DocumentListener listener) { } + @NotNull @Override public RangeMarker createRangeMarker(int startOffset, int endOffset) { return null; } + @NotNull @Override public RangeMarker createRangeMarker(int startOffset, int endOffset, boolean surviveOnExternalChange) { return null; } + @Override public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) { } + @Override public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) { } + @Override public void setReadOnly(boolean isReadOnly) { } + @NotNull @Override public RangeMarker createGuardedBlock(int startOffset, int endOffset) { return null; } + @Override public void removeGuardedBlock(@NotNull RangeMarker block) { } + @Nullable @Override public RangeMarker getOffsetGuard(int offset) { return null; } + @Nullable @Override public RangeMarker getRangeGuard(int start, int end) { return null; } + @Override public void startGuardedBlockChecking() { } + @Override public void stopGuardedBlockChecking() { } + @Override public void setCyclicBufferSize(int bufferSize) { } + + @NotNull @Override public RangeMarker createRangeMarker(@NotNull TextRange textRange) { return null; } + @Override public int getLineSeparatorLength(int line) { return 0; } + } + +} diff --git a/platform/platform-impl/src/com/intellij/ui/win/RecentTasks.java b/platform/platform-impl/src/com/intellij/ui/win/RecentTasks.java index 2d620b1a750d..12ad39f4cea2 100644 --- a/platform/platform-impl/src/com/intellij/ui/win/RecentTasks.java +++ b/platform/platform-impl/src/com/intellij/ui/win/RecentTasks.java @@ -15,49 +15,28 @@ */ package com.intellij.ui.win; -import com.intellij.openapi.application.PathManager; +import com.intellij.idea.StartupUtil; -import java.io.File; import java.lang.ref.WeakReference; import java.util.concurrent.atomic.AtomicBoolean; public class RecentTasks { - private static AtomicBoolean initialiazed = + private static AtomicBoolean initialized = new AtomicBoolean(false); private final static WeakReference<Thread> openerThread = new WeakReference<Thread>(Thread.currentThread()); static { - final String libraryName = (System.getProperty("sun.arch.data.model").contains("64"))? - "jumplistbridge64.dll": - "jumplistbridge.dll"; - - final String binPath = PathManager.getBinPath(); - final String communityBinPath = PathManager.getHomePath() + File.separatorChar + "community" + File.separatorChar + "bin"; - - final String [] libraryPaths = { - binPath, - binPath + File.separatorChar + "win", - communityBinPath, - communityBinPath + File.separatorChar + "win", - }; - - for (String path : libraryPaths) { - final File candidate = new File(path + File.separatorChar + libraryName); - if (candidate.exists()) { - System.load(candidate.getAbsolutePath()); - break; - } - } + System.loadLibrary("jumpListBridge"); } private synchronized static void init() { - if (initialiazed.get()) return; + if (initialized.get()) return; - initialize("JetBrains.JetBrainsNativeAppID"); - initialiazed.set(true); + initialize("JetBrains.JetBrainsNativeAppID." + StartupUtil.getAcquiredPort()); + initialized.set(true); } /** @@ -66,7 +45,7 @@ public class RecentTasks { * @param applicationId */ native private static void initialize (String applicationId); - native private static void addTaskNative (String location, String args, String description); + native private static void addTasksNativeForCategory (String category, Task [] tasks); native private static void clearNative(); public synchronized static void clear() { @@ -75,11 +54,10 @@ public class RecentTasks { clearNative(); } - public synchronized static void addTask(File location, String args, String description) { + public synchronized static void addTasks(final Task[] tasks) { init(); checkThread(); - if (!location.exists()) throw new IllegalArgumentException("Task should be a valid path"); - addTaskNative(location.getAbsolutePath(), args, description); + addTasksNativeForCategory("Recent", tasks); } private static void checkThread() { @@ -87,5 +65,15 @@ public class RecentTasks { if (t == null || !t.equals(Thread.currentThread())) throw new RuntimeException("This class has to be used from the same thread"); } -} + public static class Task { + private final String path; + private final String args; + private final String description; + public Task(String path, String args, String description) { + this.path = path; + this.args = args; + this.description = description; + } + } +} diff --git a/platform/platform-impl/src/com/intellij/ui/win/WinDockDelegate.java b/platform/platform-impl/src/com/intellij/ui/win/WinDockDelegate.java index 951154f909ff..cf2250546b01 100644 --- a/platform/platform-impl/src/com/intellij/ui/win/WinDockDelegate.java +++ b/platform/platform-impl/src/com/intellij/ui/win/WinDockDelegate.java @@ -44,10 +44,14 @@ public class WinDockDelegate implements SystemDock.Delegate { public void updateRecentProjectsMenu () { final AnAction[] recentProjectActions = RecentProjectsManagerBase.getInstance().getRecentProjectsActions(false); RecentTasks.clear(); - for (final AnAction action : recentProjectActions) { - ReopenProjectAction rpa = ((ReopenProjectAction)action); - RecentTasks.addTask(new File(javaExe), argsToExecute + rpa.getProjectPath(), rpa.getProjectName()); + RecentTasks.Task[] tasks = new RecentTasks.Task[recentProjectActions.length]; + for (int i = 0; i < recentProjectActions.length; i ++) { + ReopenProjectAction rpa = (ReopenProjectAction)recentProjectActions[i]; + tasks[i] = new RecentTasks.Task(javaExe, + argsToExecute + rpa.getProjectPath(), + rpa.getProjectName()); } + RecentTasks.addTasks(tasks); } synchronized public static SystemDock.Delegate getInstance() { if (!initialized) { diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 6fb8b82651fe..29382244bb60 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -7,7 +7,7 @@ undo.documentUndoLimit=100 actionSystem.fixLostTyping=true # suppress inspection "UnusedProperty" -actionSystem.fixLostTyping.description=Redispatch events, lost between actions and dialog show/close. +actionSystem.fixLostTyping.descrinonRegistry.isption=Redispatch events, lost between actions and dialog show/close. actionSystem.fixStickyFocusedWindows=true actionSystem.fixNullFocusedComponent=true actionSystem.noDefaultComponent=true @@ -232,6 +232,9 @@ ide.goto.middle.matching=true ide.goto.middle.matching.description=Suggest items in goto actions that contain the entered string somewhere in the middle. ide.goto.rebuild.delay=0 +ide.non.english.keyboard.layout.fix=false +ide.non.english.keyboard.layout.fix.description=Enables a fix for key codes with non-English keyboard layouts + ide.enable.toolwindow.stack=false change.signature.awesome.mode=true diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/IdeaWin32PerformanceTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/IdeaWin32PerformanceTest.java index 614ec8ea05b7..29845fad3a65 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/IdeaWin32PerformanceTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/IdeaWin32PerformanceTest.java @@ -51,8 +51,8 @@ public class IdeaWin32PerformanceTest { private void doTest(File file) { final String path = file.getPath(); - assertNotNull(file.listFiles()); - assertNotNull(myDriver.listChildren(path)); + assertNotNull(path, file.listFiles()); + assertNotNull(path, myDriver.listChildren(path)); long t1 = System.nanoTime(); final File[] children1 = file.listFiles(); @@ -64,7 +64,7 @@ public class IdeaWin32PerformanceTest { assertNotNull(path, children1); assertNotNull(path, children2); - assertEquals(children1.length, children2.length); + assertEquals(path, children1.length, children2.length); for (File child : children1) { if (child.isDirectory()) { diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/ModifiableRootModel.java b/platform/projectModel-api/src/com/intellij/openapi/roots/ModifiableRootModel.java index f7eb6e0ee4bc..a974b6783296 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/ModifiableRootModel.java +++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ModifiableRootModel.java @@ -151,40 +151,10 @@ public interface ModifiableRootModel extends ModuleRootModel { */ void inheritSdk(); - /** - * @deprecated moved to J2ME plugin - */ - @Deprecated - void setExplodedDirectory(VirtualFile file); - - /** - * @deprecated moved to J2ME plugin - */ - @Deprecated - void setExplodedDirectory(String url); - boolean isChanged(); - /** - * @deprecated moved to J2ME plugin - */ - @Deprecated - boolean isExcludeExplodedDirectory(); - - /** - * @deprecated moved to J2ME plugin - */ - @Deprecated - void setExcludeExplodedDirectory(boolean excludeExplodedDir); - boolean isWritable(); - /** - * @deprecated use {@code JavaModuleExternalPaths} extension instead - */ - @Deprecated - void setRootUrls(OrderRootType orderRootType, String[] urls); - <T extends OrderEntry> void replaceEntryOfType(Class<T> entryClass, T entry); @Nullable diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleExtension.java b/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleExtension.java index efacdd08e8ba..a486fdb45c45 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleExtension.java +++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleExtension.java @@ -23,9 +23,7 @@ package com.intellij.openapi.roots; import com.intellij.openapi.Disposable; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.util.JDOMExternalizable; -import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; public abstract class ModuleExtension<T extends ModuleExtension> implements JDOMExternalizable, Disposable, Comparable<ModuleExtension> { public static final ExtensionPointName<ModuleExtension> EP_NAME = ExtensionPointName.create("com.intellij.moduleExtension"); @@ -56,18 +54,6 @@ public abstract class ModuleExtension<T extends ModuleExtension> implements JDOM public abstract boolean isChanged(); - @Deprecated - @Nullable - public VirtualFile[] getRootPaths(OrderRootType type) { - return null; - } - - @Deprecated - @Nullable - public String[] getRootUrls(OrderRootType type) { - return null; - } - @Override public int compareTo(@NotNull final ModuleExtension o) { return getClass().getName().compareTo(o.getClass().getName()); diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootModel.java b/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootModel.java index e9ce9adaf5d5..4cc76e664c38 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootModel.java +++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootModel.java @@ -147,20 +147,6 @@ public interface ModuleRootModel { @NotNull String[] getSourceRootUrls(boolean includingTests); /** - * @deprecated moved to J2ME plugin - */ - @Deprecated - @Nullable - VirtualFile getExplodedDirectory(); - - /** - * @deprecated moved to J2ME plugin - */ - @Deprecated - @Nullable - String getExplodedDirectoryUrl(); - - /** * Passes all order entries in the module to the specified visitor. * * @param policy the visitor to accept. @@ -187,18 +173,6 @@ public interface ModuleRootModel { */ @NotNull String[] getDependencyModuleNames(); - /** - * @deprecated use {@code JavaModuleExternalPaths} instead - */ - @Deprecated - @NotNull VirtualFile[] getRootPaths(OrderRootType rootType); - - /** - * @deprecated use {@code JavaModuleExternalPaths} instead - */ - @Deprecated - @NotNull String[] getRootUrls(OrderRootType rootType); - <T> T getModuleExtension(Class<T> klass); @NotNull diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/OrderRootType.java b/platform/projectModel-api/src/com/intellij/openapi/roots/OrderRootType.java index 76a855bd22bd..60fccacb04c0 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/OrderRootType.java +++ b/platform/projectModel-api/src/com/intellij/openapi/roots/OrderRootType.java @@ -95,15 +95,6 @@ public class OrderRootType { return false; } - /** - * Whether {@link ModuleOrderEntry#getFiles(OrderRootType)} collects the list of roots from dependent modules. - * @deprecated looks like this method was introduced by mistake. It won't be called by IDEA anymore - */ - @Deprecated - public boolean collectFromDependentModules() { - return false; - } - public static synchronized OrderRootType[] getAllTypes() { return getAllPersistentTypes(); } diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java b/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java index 8da7c492019a..645b9e011e2d 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java +++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java @@ -106,12 +106,6 @@ public abstract class ProjectRootManager implements ModificationTracker { @Nullable public abstract Sdk getProjectSdk(); - @Deprecated - @Nullable - public Sdk getProjectJdk() { - return getProjectSdk(); - } - /** * Returns the name of the SDK selected for the project. * @@ -119,11 +113,6 @@ public abstract class ProjectRootManager implements ModificationTracker { */ public abstract String getProjectSdkName(); - @Deprecated - public String getProjectJdkName() { - return getProjectSdkName(); - } - /** * Sets the SDK to be used for the project. * @@ -132,20 +121,10 @@ public abstract class ProjectRootManager implements ModificationTracker { public abstract void setProjectSdk(@Nullable Sdk sdk); - @Deprecated - public void setProjectJdk(@Nullable Sdk jdk) { - setProjectSdk(jdk); - } - /** * Sets the name of the JDK to be used for the project. * * @param name the name of the JDK. */ public abstract void setProjectSdkName(String name); - - @Deprecated - public void setProjectJdkName(String name) { - setProjectSdkName(name); - } } diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/impl/FileIndexImplUtil.java b/platform/projectModel-api/src/com/intellij/openapi/roots/impl/FileIndexImplUtil.java deleted file mode 100644 index ac0782588a69..000000000000 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/impl/FileIndexImplUtil.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.openapi.roots.impl; - -import com.intellij.openapi.roots.ContentIterator; -import com.intellij.openapi.vfs.VfsUtilCore; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileFilter; -import org.jetbrains.annotations.NotNull; - -@SuppressWarnings("UnusedDeclaration") -public class FileIndexImplUtil { - private FileIndexImplUtil() { } - - /** - * @deprecated use {@linkplain VfsUtilCore#iterateChildrenRecursively(com.intellij.openapi.vfs.VirtualFile, - * com.intellij.openapi.vfs.VirtualFileFilter, com.intellij.openapi.roots.ContentIterator)} (to remove in IDEA 13) - */ - public static boolean iterateRecursively(@NotNull final VirtualFile root, - @NotNull final VirtualFileFilter filter, - @NotNull final ContentIterator iterator) { - return VfsUtilCore.iterateChildrenRecursively(root, filter, iterator); - } -} diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/libraries/LibraryTablesRegistrar.java b/platform/projectModel-api/src/com/intellij/openapi/roots/libraries/LibraryTablesRegistrar.java index 7410aed002d0..e44ccb1750b2 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/libraries/LibraryTablesRegistrar.java +++ b/platform/projectModel-api/src/com/intellij/openapi/roots/libraries/LibraryTablesRegistrar.java @@ -42,9 +42,5 @@ public abstract class LibraryTablesRegistrar { public abstract void registerLibraryTable(@NotNull LibraryTable libraryTable); - @Deprecated - @NotNull - public abstract LibraryTable registerLibraryTable(@NonNls String customLevel); - public abstract List<LibraryTable> getCustomLibraryTables(); }
\ No newline at end of file diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java index 36e0eb0e57da..fcaf6659a90a 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java @@ -110,17 +110,6 @@ public class ModuleRootManagerImpl extends ModuleRootManager implements ModuleCo } - - @Override - public VirtualFile getExplodedDirectory() { - return null; - } - - @Override - public String getExplodedDirectoryUrl() { - return null; - } - @Override @NotNull public ModifiableRootModel getModifiableModel() { @@ -231,18 +220,6 @@ public class ModuleRootManagerImpl extends ModuleRootManager implements ModuleCo } @Override - @NotNull - public VirtualFile[] getRootPaths(final OrderRootType rootType) { - return myRootModel.getRootPaths(rootType); - } - - @Override - @NotNull - public String[] getRootUrls(final OrderRootType rootType) { - return myRootModel.getRootUrls(rootType); - } - - @Override public <T> T getModuleExtension(final Class<T> klass) { return myRootModel.getModuleExtension(klass); } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java index 5ef797598d23..93ebe7031d1f 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java @@ -517,30 +517,12 @@ public class RootModelImpl extends RootModelBase implements ModifiableRootModel } @Override - public VirtualFile getExplodedDirectory() { - return null; - } - - @Override - public void setExplodedDirectory(@Nullable VirtualFile file) { - } - - @Override - public void setExplodedDirectory(@Nullable String url) { - } - - @Override @NotNull public Module getModule() { return myModuleRootManager.getModule(); } @Override - public String getExplodedDirectoryUrl() { - return null; - } - - @Override public boolean isChanged() { if (!myWritable) return false; @@ -637,15 +619,6 @@ public class RootModelImpl extends RootModelBase implements ModifiableRootModel myDisposed = true; } - @Override - public boolean isExcludeExplodedDirectory() { - return false; - } - - @Override - public void setExcludeExplodedDirectory(boolean excludeExplodedDir) { - } - private class Order extends ArrayList<OrderEntry> { @Override public void clear() { @@ -745,35 +718,11 @@ public class RootModelImpl extends RootModelBase implements ModifiableRootModel } } - @Override - @NotNull - public VirtualFile[] getRootPaths(final OrderRootType rootType) { - for (ModuleExtension extension : myExtensions) { - final VirtualFile[] files = extension.getRootPaths(rootType); - if (files != null) return files; - } - return VirtualFile.EMPTY_ARRAY; - } - - @Override - @NotNull - public String[] getRootUrls(final OrderRootType rootType) { - for (ModuleExtension extension : myExtensions) { - final String[] urls = extension.getRootUrls(rootType); - if (urls != null) return urls; - } - return ArrayUtil.EMPTY_STRING_ARRAY; - } - private RootModelImpl getSourceModel() { assertWritable(); return myModuleRootManager.getRootModel(); } - @Override - public void setRootUrls(final OrderRootType orderRootType, @NotNull final String[] urls) { - } - @Nullable @Override public <T> T getModuleExtension(@NotNull final Class<T> klass) { diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryTablesRegistrarImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryTablesRegistrarImpl.java index 2280294f8686..bf9bb143853a 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryTablesRegistrarImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryTablesRegistrarImpl.java @@ -17,7 +17,6 @@ package com.intellij.openapi.roots.impl.libraries; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.libraries.LibraryTable; -import com.intellij.openapi.roots.libraries.LibraryTablePresentation; import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; import com.intellij.openapi.Disposable; import com.intellij.util.SmartList; @@ -59,45 +58,6 @@ public class LibraryTablesRegistrarImpl extends LibraryTablesRegistrar implement } @Override - @NotNull - public LibraryTable registerLibraryTable(final String customLevel) { - LibraryTable table = new LibraryTableBase() { - @Override - public String getTableLevel() { - return customLevel; - } - - @Override - public LibraryTablePresentation getPresentation() { - return new LibraryTablePresentation() { - @Override - public String getDisplayName(boolean plural) { - return customLevel; - } - - @Override - public String getDescription() { - throw new UnsupportedOperationException("Method getDescription is not yet implemented in " + getClass().getName()); - } - - @Override - public String getLibraryTableEditorTitle() { - throw new UnsupportedOperationException("Method getLibraryTableEditorTitle is not yet implemented in " + getClass().getName()); - } - }; - } - - @Override - public boolean isEditable() { - return false; - } - }; - - registerLibraryTable(table); - return table; - } - - @Override public List<LibraryTable> getCustomLibraryTables() { return new SmartList<LibraryTable>(myLibraryTables.values()); } diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsRootModel.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsRootModel.java index e0bd6909f962..dabe1b351957 100644 --- a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsRootModel.java +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsRootModel.java @@ -19,7 +19,6 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.impl.RootModelBase; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.pointers.VirtualFilePointer; import com.intellij.project.model.impl.module.content.JpsContentEntry; import org.jetbrains.annotations.NotNull; @@ -75,28 +74,6 @@ public class JpsRootModel extends RootModelBase implements ModuleRootModel { } @Override - public VirtualFile getExplodedDirectory() { - throw new UnsupportedOperationException("'getExplodedDirectory' not implemented in " + getClass().getName()); - } - - @Override - public String getExplodedDirectoryUrl() { - throw new UnsupportedOperationException("'getExplodedDirectoryUrl' not implemented in " + getClass().getName()); - } - - @NotNull - @Override - public VirtualFile[] getRootPaths(OrderRootType rootType) { - throw new UnsupportedOperationException("'getRootPaths' not implemented in " + getClass().getName()); - } - - @NotNull - @Override - public String[] getRootUrls(OrderRootType rootType) { - throw new UnsupportedOperationException("'getRootUrls' not implemented in " + getClass().getName()); - } - - @Override public <T> T getModuleExtension(Class<T> klass) { throw new UnsupportedOperationException("'getModuleExtension' not implemented in " + getClass().getName()); } diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/deployment/DeploymentSource.java b/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/deployment/DeploymentSource.java index 7afc1f437f43..1b59239f1841 100644 --- a/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/deployment/DeploymentSource.java +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/deployment/DeploymentSource.java @@ -40,4 +40,7 @@ public interface DeploymentSource { boolean isValid(); boolean isArchive(); + + @NotNull + DeploymentSourceType<?> getType(); } diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/deployment/DeploymentSourceType.java b/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/deployment/DeploymentSourceType.java new file mode 100644 index 000000000000..690b501b6e7f --- /dev/null +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/deployment/DeploymentSourceType.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.remoteServer.configuration.deployment; + +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.project.Project; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +/** + * @author nik + */ +public abstract class DeploymentSourceType<S extends DeploymentSource> { + public static final ExtensionPointName<DeploymentSourceType<?>> EP_NAME = ExtensionPointName.create("com.intellij.remoteServer.deploymentSource.type"); + private final String myId; + + protected DeploymentSourceType(@NotNull String id) { + myId = id; + } + + public final String getId() { + return myId; + } + + @NotNull + public abstract S load(@NotNull Element tag, @NotNull Project project); + + public abstract void save(@NotNull S s, @NotNull Element tag); + + + public void setBuildBeforeRunTask(@NotNull RunConfiguration configuration, @NotNull S source) { + } + + public void updateBuildBeforeRunOption(@NotNull JComponent runConfigurationEditorComponent, @NotNull Project project, @NotNull S source, boolean select) { + } +} diff --git a/platform/remote-servers/impl/remote-servers-impl.iml b/platform/remote-servers/impl/remote-servers-impl.iml index 737907ab5b82..f47ab6cd9062 100644 --- a/platform/remote-servers/impl/remote-servers-impl.iml +++ b/platform/remote-servers/impl/remote-servers-impl.iml @@ -11,9 +11,7 @@ <orderEntry type="module" module-name="remote-servers-api" /> <orderEntry type="module" module-name="core-impl" /> <orderEntry type="module" module-name="lang-api" /> - <orderEntry type="module" module-name="compiler-openapi" /> <orderEntry type="module" module-name="lang-impl" /> - <orderEntry type="module" module-name="compiler-impl" /> <orderEntry type="module" module-name="xdebugger-api" /> </component> </module> diff --git a/platform/platform-resources/src/META-INF/RemoteServers.xml b/platform/remote-servers/impl/src/META-INF/RemoteServers.xml index 1fc87fc0f907..d8b3bdf3a234 100644 --- a/platform/platform-resources/src/META-INF/RemoteServers.xml +++ b/platform/remote-servers/impl/src/META-INF/RemoteServers.xml @@ -1,19 +1,19 @@ <idea-plugin> <extensionPoints> <extensionPoint name="remoteServer.type" interface="com.intellij.remoteServer.ServerType"/> + <extensionPoint name="remoteServer.deploymentSource.type" interface="com.intellij.remoteServer.configuration.deployment.DeploymentSourceType"/> </extensionPoints> <extensions defaultExtensionNs="com.intellij"> <applicationService serviceInterface="com.intellij.remoteServer.configuration.RemoteServersManager" serviceImplementation="com.intellij.remoteServer.impl.configuration.RemoteServersManagerImpl"/> - <applicationService serviceInterface="com.intellij.remoteServer.configuration.deployment.DeploymentSourceUtil" - serviceImplementation="com.intellij.remoteServer.impl.configuration.deployment.DeploymentSourceUtilImpl"/> <applicationService serviceInterface="com.intellij.remoteServer.runtime.ServerConnectionManager" serviceImplementation="com.intellij.remoteServer.impl.runtime.ServerConnectionManagerImpl"/> <applicationConfigurable instance="com.intellij.remoteServer.impl.configuration.RemoteServerListConfigurable"/> <programRunner implementation="com.intellij.remoteServer.impl.runtime.DeployToServerRunner"/> <projectService serviceInterface="com.intellij.remoteServer.runtime.ui.RemoteServersView" serviceImplementation="com.intellij.remoteServer.runtime.ui.RemoteServersView"/> + <remoteServer.deploymentSource.type implementation="com.intellij.remoteServer.impl.configuration.deployment.ModuleDeploymentSourceType"/> </extensions> <application-components> <component> diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerConfigurationType.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerConfigurationType.java index 527c33a37e5c..afee5e563013 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerConfigurationType.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerConfigurationType.java @@ -19,14 +19,12 @@ import com.intellij.execution.configuration.ConfigurationFactoryEx; import com.intellij.execution.configurations.ConfigurationTypeBase; import com.intellij.execution.configurations.RunConfiguration; import com.intellij.openapi.project.Project; -import com.intellij.packaging.artifacts.Artifact; -import com.intellij.packaging.impl.run.BuildArtifactsBeforeRunTaskProvider; import com.intellij.remoteServer.ServerType; import com.intellij.remoteServer.configuration.RemoteServer; import com.intellij.remoteServer.configuration.RemoteServersManager; -import com.intellij.remoteServer.configuration.deployment.ArtifactDeploymentSource; import com.intellij.remoteServer.configuration.deployment.DeploymentConfigurator; import com.intellij.remoteServer.configuration.deployment.DeploymentSource; +import com.intellij.remoteServer.configuration.deployment.DeploymentSourceType; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -65,12 +63,8 @@ public class DeployToServerConfigurationType extends ConfigurationTypeBase { DeploymentSource source = ContainerUtil.getFirstItem(sources); if (source != null) { deployConfiguration.setDeploymentSource(source); - if (source instanceof ArtifactDeploymentSource) { - Artifact artifact = ((ArtifactDeploymentSource)source).getArtifact(); - if (artifact != null) { - BuildArtifactsBeforeRunTaskProvider.setBuildArtifactBeforeRun(configuration.getProject(), configuration, artifact); - } - } + DeploymentSourceType type = source.getType(); + type.setBuildBeforeRunTask(configuration, source); } } } diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java index 1850988c8520..d2ec003b435b 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java @@ -23,12 +23,11 @@ import com.intellij.execution.configurations.RunProfileState; import com.intellij.execution.configurations.RuntimeConfigurationException; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.openapi.components.ComponentSerializationUtil; -import com.intellij.openapi.module.ModulePointerManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; -import com.intellij.packaging.artifacts.ArtifactPointerManager; import com.intellij.remoteServer.ServerType; import com.intellij.remoteServer.configuration.RemoteServer; import com.intellij.remoteServer.configuration.RemoteServersManager; @@ -37,22 +36,19 @@ import com.intellij.remoteServer.configuration.deployment.*; import com.intellij.remoteServer.impl.runtime.DeployToServerState; import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; import com.intellij.util.xmlb.XmlSerializer; -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.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; - /** * @author nik */ public class DeployToServerRunConfiguration<S extends ServerConfiguration, D extends DeploymentConfiguration> extends RunConfigurationBase { + private static final Logger LOG = Logger.getInstance(DeployToServerRunConfiguration.class); + private static final String DEPLOYMENT_SOURCE_TYPE_ATTRIBUTE = "type"; @NonNls public static final String SETTINGS_ELEMENT = "settings"; public static final SkipDefaultValuesSerializationFilters SERIALIZATION_FILTERS = new SkipDefaultValuesSerializationFilters(); private final ServerType<S> myServerType; @@ -139,39 +135,49 @@ public class DeployToServerRunConfiguration<S extends ServerConfiguration, D ext myDeploymentSource = null; if (state != null) { myServerName = state.myServerName; - if (!state.myDeploymentItemState.isEmpty()) { - DeploymentItemState itemState = state.myDeploymentItemState.get(0); - myDeploymentSource = itemState.createSource(getProject()); - myDeploymentConfiguration = myDeploymentConfigurator.createDefaultConfiguration(myDeploymentSource); - if (itemState.mySettings != null) { - ComponentSerializationUtil.loadComponentState(myDeploymentConfiguration.getSerializer(), itemState.mySettings); + Element deploymentTag = state.myDeploymentTag; + if (deploymentTag != null) { + String typeId = deploymentTag.getAttributeValue(DEPLOYMENT_SOURCE_TYPE_ATTRIBUTE); + DeploymentSourceType<?> type = findDeploymentSourceType(typeId); + if (type != null) { + myDeploymentSource = type.load(deploymentTag, getProject()); + myDeploymentConfiguration = myDeploymentConfigurator.createDefaultConfiguration(myDeploymentSource); + ComponentSerializationUtil.loadComponentState(myDeploymentConfiguration.getSerializer(), deploymentTag.getChild(SETTINGS_ELEMENT)); + } + else { + LOG.warn("Cannot load deployment source for '" + getName() + "' run configuration: unknown deployment type '" + typeId + "'"); } } } } + @Nullable + private static DeploymentSourceType<?> findDeploymentSourceType(@Nullable String id) { + for (DeploymentSourceType<?> type : DeploymentSourceType.EP_NAME.getExtensions()) { + if (type.getId().equals(id)) { + return type; + } + } + return null; + } + @Override public void writeExternal(Element element) throws WriteExternalException { ConfigurationState state = new ConfigurationState(); state.myServerName = myServerName; if (myDeploymentSource != null) { - DeploymentItemState itemState; - if (myDeploymentSource instanceof ArtifactDeploymentSource) { - itemState = new ArtifactDeploymentSettingsState(((ArtifactDeploymentSource)myDeploymentSource).getArtifactPointer().getArtifactName()); - } - else if (myDeploymentSource instanceof ModuleDeploymentSource) { - itemState = new ModuleDeploymentSettingsState(((ModuleDeploymentSource)myDeploymentSource).getModulePointer().getModuleName()); - } - else { - throw new WriteExternalException("Unknown source " + myDeploymentSource); - } + DeploymentSourceType type = myDeploymentSource.getType(); + Element deploymentTag = new Element("deployment").setAttribute(DEPLOYMENT_SOURCE_TYPE_ATTRIBUTE, type.getId()); + type.save(myDeploymentSource, deploymentTag); if (myDeploymentConfiguration != null) { Object configurationState = myDeploymentConfiguration.getSerializer().getState(); if (configurationState != null) { - itemState.setSettings(XmlSerializer.serialize(configurationState, SERIALIZATION_FILTERS)); + Element settingsTag = new Element(SETTINGS_ELEMENT); + XmlSerializer.serializeInto(configurationState, settingsTag, SERIALIZATION_FILTERS); + deploymentTag.addContent(settingsTag); } } - state.myDeploymentItemState.add(itemState); + state.myDeploymentTag = deploymentTag; } XmlSerializer.serializeInto(state, element, SERIALIZATION_FILTERS); super.writeExternal(element); @@ -181,83 +187,7 @@ public class DeployToServerRunConfiguration<S extends ServerConfiguration, D ext @Attribute("server-name") public String myServerName; - //in fact this collection has no more than one element - @Property(surroundWithTag = false) - @AbstractCollection(surroundWithTag = false, - elementTypes = {ExternalFileDeploymentSettingsState.class, ArtifactDeploymentSettingsState.class, ModuleDeploymentSettingsState.class}) - public List<DeploymentItemState> myDeploymentItemState = new ArrayList<DeploymentItemState>(); - } - - public static abstract class DeploymentItemState { - private Element mySettings; - - @Tag(SETTINGS_ELEMENT) - public Element getSettings() { - return mySettings; - } - - public void setSettings(Element settings) { - mySettings = settings; - } - - @NotNull - public abstract DeploymentSource createSource(Project project); - } - - @Tag("file") - public static class ExternalFileDeploymentSettingsState extends DeploymentItemState { - @Attribute("path") - public String myFilePath; - - public ExternalFileDeploymentSettingsState() { - } - - public ExternalFileDeploymentSettingsState(String filePath) { - myFilePath = filePath; - } - - @NotNull - @Override - public DeploymentSource createSource(Project project) { - throw new UnsupportedOperationException("'createSource' not implemented in " + getClass().getName()); - } - } - - @Tag("artifact") - public static class ArtifactDeploymentSettingsState extends DeploymentItemState { - @Attribute("name") - public String myArtifactName; - - public ArtifactDeploymentSettingsState() { - } - - public ArtifactDeploymentSettingsState(String artifactName) { - myArtifactName = artifactName; - } - - @NotNull - @Override - public DeploymentSource createSource(Project project) { - return new ArtifactDeploymentSourceImpl(ArtifactPointerManager.getInstance(project).createPointer(myArtifactName)); - } - } - - @Tag("module") - public static class ModuleDeploymentSettingsState extends DeploymentItemState { - @Attribute("name") - public String myModuleName; - - public ModuleDeploymentSettingsState() { - } - - public ModuleDeploymentSettingsState(String artifactName) { - myModuleName = artifactName; - } - - @NotNull - @Override - public DeploymentSource createSource(Project project) { - return new ModuleDeploymentSourceImpl(ModulePointerManager.getInstance(project).create(myModuleName)); - } + @Tag("deployment") + public Element myDeploymentTag; } } diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerSettingsEditor.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerSettingsEditor.java index ee18ac1b85e6..ab99150ecbd0 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerSettingsEditor.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerSettingsEditor.java @@ -22,16 +22,14 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; -import com.intellij.packaging.artifacts.Artifact; -import com.intellij.packaging.impl.run.BuildArtifactsBeforeRunTaskProvider; import com.intellij.remoteServer.ServerType; import com.intellij.remoteServer.configuration.RemoteServer; import com.intellij.remoteServer.configuration.RemoteServersManager; import com.intellij.remoteServer.configuration.ServerConfiguration; -import com.intellij.remoteServer.configuration.deployment.ArtifactDeploymentSource; import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration; import com.intellij.remoteServer.configuration.deployment.DeploymentConfigurator; import com.intellij.remoteServer.configuration.deployment.DeploymentSource; +import com.intellij.remoteServer.configuration.deployment.DeploymentSourceType; import com.intellij.remoteServer.impl.configuration.RemoteServerListConfigurable; import com.intellij.ui.*; import com.intellij.util.ui.FormBuilder; @@ -146,11 +144,9 @@ public class DeployToServerSettingsEditor<S extends ServerConfiguration, D exten } private void updateBeforeRunOptions(@Nullable DeploymentSource source, boolean selected) { - if (source instanceof ArtifactDeploymentSource) { - Artifact artifact = ((ArtifactDeploymentSource)source).getArtifact(); - if (artifact != null) { - BuildArtifactsBeforeRunTaskProvider.setBuildArtifactBeforeRunOption(myServerComboBox, myProject, artifact, selected); - } + if (source != null) { + DeploymentSourceType type = source.getType(); + type.updateBuildBeforeRunOption(myServerComboBox, myProject, source, selected); } } diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/ModuleDeploymentSourceImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/ModuleDeploymentSourceImpl.java index de72f2b3c1bd..a870006172fa 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/ModuleDeploymentSourceImpl.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/ModuleDeploymentSourceImpl.java @@ -21,6 +21,7 @@ import com.intellij.openapi.module.ModulePointer; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.remoteServer.configuration.deployment.DeploymentSourceType; import com.intellij.remoteServer.configuration.deployment.ModuleDeploymentSource; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; @@ -113,4 +114,10 @@ public class ModuleDeploymentSourceImpl implements ModuleDeploymentSource { public int hashCode() { return myPointer.hashCode(); } + + @NotNull + @Override + public DeploymentSourceType<?> getType() { + return DeploymentSourceType.EP_NAME.findExtension(ModuleDeploymentSourceType.class); + } } diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/ModuleDeploymentSourceType.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/ModuleDeploymentSourceType.java new file mode 100644 index 000000000000..fd98eee956d2 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/ModuleDeploymentSourceType.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.remoteServer.impl.configuration.deployment; + +import com.intellij.openapi.module.ModulePointerManager; +import com.intellij.openapi.project.Project; +import com.intellij.remoteServer.configuration.deployment.DeploymentSourceType; +import com.intellij.remoteServer.configuration.deployment.ModuleDeploymentSource; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public class ModuleDeploymentSourceType extends DeploymentSourceType<ModuleDeploymentSource> { + private static final String NAME_ATTRIBUTE = "name"; + + public ModuleDeploymentSourceType() { + super("module"); + } + + @NotNull + @Override + public ModuleDeploymentSource load(@NotNull Element tag, @NotNull Project project) { + return new ModuleDeploymentSourceImpl(ModulePointerManager.getInstance(project).create(tag.getAttributeValue(NAME_ATTRIBUTE))); + } + + @Override + public void save(@NotNull ModuleDeploymentSource source, @NotNull Element tag) { + tag.setAttribute(NAME_ATTRIBUTE, source.getModulePointer().getModuleName()); + } +} diff --git a/platform/testFramework/testFramework.iml b/platform/testFramework/testFramework.iml index 91e082177e7b..7985252e6abc 100644 --- a/platform/testFramework/testFramework.iml +++ b/platform/testFramework/testFramework.iml @@ -26,7 +26,6 @@ <orderEntry type="module" module-name="relaxng" exported="" scope="RUNTIME" /> <orderEntry type="module" module-name="images" exported="" scope="RUNTIME" /> <orderEntry type="module" module-name="RegExpSupport" exported="" scope="RUNTIME" /> - <orderEntry type="module" module-name="remote-servers-impl" scope="RUNTIME" /> </component> </module> diff --git a/platform/util/src/com/intellij/util/ArrayUtil.java b/platform/util/src/com/intellij/util/ArrayUtil.java index b4d7df3ebd1d..ace2636a52a5 100644 --- a/platform/util/src/com/intellij/util/ArrayUtil.java +++ b/platform/util/src/com/intellij/util/ArrayUtil.java @@ -339,7 +339,17 @@ public class ArrayUtil extends ArrayUtilRt { return result; } + @NotNull + public static byte[] prepend(byte element, @NotNull byte[] array) { + int length = array.length; + final byte[] result = new byte[length + 1]; + result[0] = element; + System.arraycopy(array, 0, result, 1, length); + return result; + } + public static <T> T[] append(@NotNull final T[] src, final T element, @NotNull ArrayFactory<T> factory) { + int length = src.length; T[] result = factory.create(length + 1); System.arraycopy(src, 0, result, 0, length); diff --git a/platform/util/src/com/intellij/util/io/PersistentHashMap.java b/platform/util/src/com/intellij/util/io/PersistentHashMap.java index 56689a5de85f..dc9a9082cb0e 100644 --- a/platform/util/src/com/intellij/util/io/PersistentHashMap.java +++ b/platform/util/src/com/intellij/util/io/PersistentHashMap.java @@ -629,7 +629,7 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate< LOG.info("Loaded mappings:"+(System.currentTimeMillis() - started) + "ms, keys:"+infos.size()); started = System.currentTimeMillis(); - int fragments = 0; + long fragments = 0; if (infos.size() > 0) { try { fragments = myValueStorage.compactValues(infos, newStorage); @@ -639,7 +639,7 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate< } } - LOG.info("Compacted values for:"+(System.currentTimeMillis() - started) + "ms fragments:"+fragments); + LOG.info("Compacted values for:"+(System.currentTimeMillis() - started) + "ms fragments:"+((int)fragments) + ", newfragments:"+(fragments >> 32)); started = System.currentTimeMillis(); try { diff --git a/platform/util/src/com/intellij/util/io/PersistentHashMapValueStorage.java b/platform/util/src/com/intellij/util/io/PersistentHashMapValueStorage.java index 8c505291473b..56799647e63e 100644 --- a/platform/util/src/com/intellij/util/io/PersistentHashMapValueStorage.java +++ b/platform/util/src/com/intellij/util/io/PersistentHashMapValueStorage.java @@ -119,7 +119,7 @@ public class PersistentHashMapValueStorage { private final UnsyncByteArrayInputStream myBufferStreamWrapper = new UnsyncByteArrayInputStream(myBuffer); private final DataInputStream myBufferDataStreamWrapper = new DataInputStream(myBufferStreamWrapper); - public int compactValues(List<PersistentHashMap.CompactionRecordInfo> infos, PersistentHashMapValueStorage storage) throws IOException { + public long compactValues(List<PersistentHashMap.CompactionRecordInfo> infos, PersistentHashMapValueStorage storage) throws IOException { PriorityQueue<PersistentHashMap.CompactionRecordInfo> records = new PriorityQueue<PersistentHashMap.CompactionRecordInfo>( infos.size(), new Comparator<PersistentHashMap.CompactionRecordInfo>() { @Override @@ -141,6 +141,7 @@ public class PersistentHashMapValueStorage { long lastConsumedOffset = lastReadOffset; long allRecordsStart = 0; int fragments = 0; + int newFragments = 0; int allRecordsLength = 0; byte[] stuffFromPreviousRecord = null; int bytesRead = (int)(mySize - (mySize / fileBufferLength) * fileBufferLength); @@ -182,7 +183,7 @@ public class PersistentHashMapValueStorage { int available = myBufferStreamWrapper.available(); chunkSize = DataInputOutputUtil.readINT(myBufferDataStreamWrapper); - prevChunkAddress = readPrevChunkAddress(info.valueAddress + (available - myBufferStreamWrapper.available())); + prevChunkAddress = readPrevChunkAddress(info.valueAddress); dataOffset = available - myBufferStreamWrapper.available(); byte[] b; @@ -236,9 +237,11 @@ public class PersistentHashMapValueStorage { if (prevChunkAddress == 0) { info.newValueAddress = storage.appendBytes(b, 0, chunkSize, info.newValueAddress); + ++newFragments; } else { if (retained > softMaxRetainedLimit && b.length > blockSizeToWriteWhenSoftMaxRetainedLimitIsHit || retained > maxRetainedLimit) { + ++newFragments; info.newValueAddress = storage.appendBytes(b, 0, chunkSize, info.newValueAddress); info.value = null; retained -= b.length; @@ -264,7 +267,8 @@ public class PersistentHashMapValueStorage { lastReadOffset -= bytesRead; bytesRead = fileBufferLength; } - return fragments; + + return fragments | ((long)newFragments << 32); } public static class ReadResult { diff --git a/platform/util/src/com/intellij/util/lang/ClassPath.java b/platform/util/src/com/intellij/util/lang/ClassPath.java index b0f13f91c02e..31037cf6ab0e 100644 --- a/platform/util/src/com/intellij/util/lang/ClassPath.java +++ b/platform/util/src/com/intellij/util/lang/ClassPath.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.util.lang; import com.intellij.openapi.application.PathManager; @@ -96,11 +95,17 @@ public class ClassPath { } } + /** @deprecated use {@link #ClassPath(java.util.List, boolean, boolean, boolean, boolean)} (to remove in IDEA 14) */ public ClassPath(URL[] urls, boolean canLockJars, boolean canUseCache) { - this(urls, canLockJars, canUseCache, false, true); + this(Arrays.asList(urls), canLockJars, canUseCache, false, true); } + /** @deprecated use {@link #ClassPath(java.util.List, boolean, boolean, boolean, boolean)} (to remove in IDEA 14) */ public ClassPath(URL[] urls, boolean canLockJars, boolean canUseCache, boolean acceptUnescapedUrls, boolean preloadJarContents) { + this(Arrays.asList(urls), canLockJars, canUseCache, acceptUnescapedUrls, preloadJarContents); + } + + public ClassPath(List<URL> urls, boolean canLockJars, boolean canUseCache, boolean acceptUnescapedUrls, boolean preloadJarContents) { myCanLockJars = canLockJars; myCanUseCache = canUseCache; myAcceptUnescapedUrls = acceptUnescapedUrls; @@ -110,7 +115,17 @@ public class ClassPath { // Accessed by reflection from PluginClassLoader // TODO: do we need it? void addURL(URL url) { - push(new URL[]{url}); + push(Collections.singletonList(url)); + } + + private void push(List<URL> urls) { + if (!urls.isEmpty()) { + synchronized (myUrls) { + for (int i = urls.size() - 1; i >= 0; i--) { + myUrls.push(urls.get(i)); + } + } + } } @Nullable @@ -229,14 +244,6 @@ public class ClassPath { return loader; } - private void push(URL[] urls) { - if (urls.length == 0) return; - synchronized (myUrls) { - for (int i = urls.length - 1; i >= 0; i--) myUrls.push(urls[i]); - - } - } - private class MyEnumeration implements Enumeration<URL> { private int myIndex = 0; private Resource myRes = null; diff --git a/platform/util/src/com/intellij/util/lang/ClasspathCache.java b/platform/util/src/com/intellij/util/lang/ClasspathCache.java index 8d4299e5ec49..9b3201f3c756 100644 --- a/platform/util/src/com/intellij/util/lang/ClasspathCache.java +++ b/platform/util/src/com/intellij/util/lang/ClasspathCache.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,12 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/* - * @author max - */ package com.intellij.util.lang; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringHash; import com.intellij.util.ArrayUtil; import com.intellij.util.BloomFilterBase; @@ -35,8 +32,13 @@ import java.util.List; import java.util.Map; import java.util.Set; +/** + * @author max + */ public class ClasspathCache { - private static final boolean doDebug = false; + static final Logger LOG = Logger.getInstance(ClasspathCache.class); + static final boolean doDebug = LOG.isDebugEnabled(); + private final DebugInfo myDebugInfo; private final TIntObjectHashMap<Object> myResourcePackagesCache = new TIntObjectHashMap<Object>(); @@ -114,9 +116,9 @@ public class ClasspathCache { Set<Loader> loaders = myResources2LoadersTempMap.get(name); if (loaders == null) myResources2LoadersTempMap.put(name, loaders = new THashSet<Loader>()); boolean added = loaders.add(loader); - if (UrlClassLoader.doDebug && added) ++registeredBeforeClose; + if (doDebug && added) ++registeredBeforeClose; } else { - if (UrlClassLoader.doDebug) { + if (doDebug) { if (!myNameFilter.maybeContains(name, loader)) ++registeredAfterClose; } @@ -147,8 +149,8 @@ public class ClasspathCache { } } - if (requests % 1000 == 0 && UrlClassLoader.doDebug) { - UrlClassLoader.debug("Avoided disk hits: "+hits + " from " + requests + (doDebug ? ", false hits:" + falseHits + ", bitmap diffs:"+diffs3:"")); + if (requests % 1000 == 0 && doDebug) { + LOG.debug("Avoided disk hits: " + hits + " from " + requests + ", false hits:" + falseHits + ", bitmap diffs:" + diffs3); } } else { @@ -176,8 +178,8 @@ public class ClasspathCache { } } - if (requests2 % 1000 == 0 && UrlClassLoader.doDebug) { - UrlClassLoader.debug("Avoided disk hits2: "+hits2 + " from " + requests2 + (doDebug ? "," + diffs + ", false hits:" + falseHits2 + ", bitmap diffs:"+diffs2:"")); + if (requests2 % 1000 == 0 && doDebug) { + LOG.debug("Avoided disk hits2: " + hits2 + " from " + requests2 + "," + diffs + ", false hits:" + falseHits2 + ", bitmap diffs:" + diffs2); } } @@ -215,14 +217,14 @@ public class ClasspathCache { void nameSymbolsLoaded() { if (!myTempMapMode) { - if (UrlClassLoader.doDebug && registeredAfterClose > 0) { - UrlClassLoader.debug("Registered number of classes after close "+registeredAfterClose + " "+toString()); + if (doDebug && registeredAfterClose > 0) { + LOG.debug("Registered number of classes after close " + registeredAfterClose + " " + toString()); } return; } - if (UrlClassLoader.doDebug) { - UrlClassLoader.debug("Registered number of classes before classes "+registeredBeforeClose + " "+toString()); + if (doDebug) { + LOG.debug("Registered number of classes before classes " + registeredBeforeClose + " " + toString()); } myTempMapMode = false; diff --git a/platform/util/src/com/intellij/util/lang/FileLoader.java b/platform/util/src/com/intellij/util/lang/FileLoader.java index ba76362e3947..7c15d04ba92a 100644 --- a/platform/util/src/com/intellij/util/lang/FileLoader.java +++ b/platform/util/src/com/intellij/util/lang/FileLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.util.lang; import com.intellij.openapi.util.io.FileUtil; @@ -88,14 +87,14 @@ class FileLoader extends Loader { if (!check || file.exists()) { // check means we load or process resource so we check its existence via old way if (check) { ++misses; - if (misses % 1000 == 0 && UrlClassLoader.doDebug) { - UrlClassLoader.debug("[Sample of] missed resource " + name + " from " + myRootDir); + if (misses % 1000 == 0 && ClasspathCache.doDebug) { + ClasspathCache.LOG.debug("[Sample of] missed resource " + name + " from " + myRootDir); } } ++hits; - if (hits % 1000 == 0 && UrlClassLoader.doDebug) { - UrlClassLoader.debug("Exists file loader: misses:" + misses + ", hits:" + hits); + if (hits % 1000 == 0 && ClasspathCache.doDebug) { + ClasspathCache.LOG.debug("Exists file loader: misses:" + misses + ", hits:" + hits); } return new MyResource(name, url, file, !check); @@ -103,8 +102,8 @@ class FileLoader extends Loader { } catch (Exception exception) { ++misses; - if (misses % 1000 == 0 && UrlClassLoader.doDebug) { - UrlClassLoader.debug("Missed " + name + " from " + myRootDir); + if (misses % 1000 == 0 && ClasspathCache.doDebug) { + ClasspathCache.LOG.debug("Missed " + name + " from " + myRootDir); } if (!check && file != null && file.exists()) { try { // we can not open the file if it is directory, Resource still can be created diff --git a/platform/util/src/com/intellij/util/lang/JarLoader.java b/platform/util/src/com/intellij/util/lang/JarLoader.java index 47920fe5f469..72323c111dbe 100644 --- a/platform/util/src/com/intellij/util/lang/JarLoader.java +++ b/platform/util/src/com/intellij/util/lang/JarLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.util.lang; import com.intellij.openapi.diagnostic.Logger; @@ -162,14 +161,14 @@ class JarLoader extends Loader { ZipEntry entry = file.getEntry(name); if (entry != null) { ++hits; - if (hits % 1000 == 0 && UrlClassLoader.doDebug) { - UrlClassLoader.debug("Exists jar loader: misses:" + misses + ", hits:" + hits); + if (hits % 1000 == 0 && ClasspathCache.doDebug) { + ClasspathCache.LOG.debug("Exists jar loader: misses:" + misses + ", hits:" + hits); } return new MyResource(entry, new URL(getBaseURL(), name)); } - if (misses % 1000 == 0 && UrlClassLoader.doDebug) { - UrlClassLoader.debug("Missed " + name + " from jar:" + myURL); + if (misses % 1000 == 0 && ClasspathCache.doDebug) { + ClasspathCache.LOG.debug("Missed " + name + " from jar:" + myURL); } ++misses; } @@ -184,7 +183,7 @@ class JarLoader extends Loader { } final long doneFor = myDebugTime ? System.nanoTime() - started :0; if (doneFor > NS_THRESHOLD) { - System.out.println(doneFor/1000000 + " ms for jar loader get resource:"+name); + ClasspathCache.LOG.debug(doneFor/1000000 + " ms for jar loader get resource:"+name); } } diff --git a/platform/util/src/com/intellij/util/lang/UrlClassLoader.java b/platform/util/src/com/intellij/util/lang/UrlClassLoader.java index 4b59f91a9e59..70a71f9787f6 100644 --- a/platform/util/src/com/intellij/util/lang/UrlClassLoader.java +++ b/platform/util/src/com/intellij/util/lang/UrlClassLoader.java @@ -13,10 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.util.lang; +import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.SystemInfo; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; @@ -24,53 +25,94 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import sun.misc.Resource; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.util.Arrays; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; +import java.util.*; public class UrlClassLoader extends ClassLoader { - private final ClassPath myClassPath; - private final List<URL> myURLs; @NonNls static final String CLASS_EXTENSION = ".class"; - protected static final boolean myDebugTime = false; - protected static final long NS_THRESHOLD = 10000000; + public static final class Builder { + private List<URL> myURLs = ContainerUtil.emptyList(); + private ClassLoader myParent = null; + private boolean myLockJars = false; + private boolean myUseCache = false; + private boolean myAcceptUnescaped = false; + private boolean myPreload = true; + private String[] myNativeLibs = null; + + private Builder() { } + + public Builder urls(List<URL> urls) { myURLs = urls; return this; } + public Builder urls(URL... urls) { myURLs = Arrays.asList(urls); return this; } + public Builder parent(ClassLoader parent) { myParent = parent; return this; } + public Builder allowLock() { myLockJars = true; return this; } + public Builder allowLock(boolean lockJars) { myLockJars = lockJars; return this; } + public Builder useCache() { myUseCache = true; return this; } + public Builder useCache(boolean useCache) { myUseCache = useCache; return this; } + public Builder allowUnescaped() { myAcceptUnescaped = true; return this; } + public Builder noPreload() { myPreload = false; return this; } + public Builder nativeLibs(String... libNames) { myNativeLibs = libNames; return this; } + public UrlClassLoader get() { return new UrlClassLoader(this); } + } + + public static Builder build() { + return new Builder(); + } + + private final List<URL> myURLs; + private final ClassPath myClassPath; + private final Set<String> myNativeLibs; + + /** @deprecated use {@link #build()} (to remove in IDEA 14) */ public UrlClassLoader(@NotNull ClassLoader parent) { - this(Arrays.asList(((URLClassLoader)parent).getURLs()), parent.getParent(), true, true); + this(build().urls(((URLClassLoader)parent).getURLs()).parent(parent.getParent()).allowLock().useCache()); } + /** @deprecated use {@link #build()} (to remove in IDEA 14) */ public UrlClassLoader(List<URL> urls, @Nullable ClassLoader parent) { - this(urls, parent, false, false); + this(build().urls(urls).parent(parent)); } + /** @deprecated use {@link #build()} (to remove in IDEA 14) */ public UrlClassLoader(URL[] urls, @Nullable ClassLoader parent) { - this(Arrays.asList(urls), parent, false, false); + this(build().urls(urls).parent(parent)); } - public UrlClassLoader(List<URL> urls, @Nullable ClassLoader parent, boolean canLockJars, boolean canUseCache) { - this(urls, parent, canLockJars, canUseCache, false, true); + /** @deprecated use {@link #build()} (to remove in IDEA 14) */ + public UrlClassLoader(List<URL> urls, @Nullable ClassLoader parent, boolean lockJars, boolean useCache) { + this(build().urls(urls).parent(parent).allowLock(lockJars).useCache(useCache)); } - public UrlClassLoader(List<URL> urls, @Nullable ClassLoader parent, boolean canLockJars, boolean canUseCache, boolean acceptUnescapedUrls, final boolean preloadJarContents) { + /** @deprecated use {@link #build()} (to remove in IDEA 14) */ + public UrlClassLoader(List<URL> urls, @Nullable ClassLoader parent, boolean lockJars, boolean useCache, boolean allowUnescaped, boolean preload) { super(parent); + myURLs = ContainerUtil.map(urls, new Function<URL, URL>() { + @Override + public URL fun(URL url) { + return internProtocol(url); + } + }); + myClassPath = new ClassPath(myURLs, lockJars, useCache, allowUnescaped, preload); + myNativeLibs = Collections.emptySet(); + } - List<URL> list = ContainerUtil.map(urls, new Function<URL, URL>() { + protected UrlClassLoader(@NotNull Builder builder) { + super(builder.myParent); + myURLs = ContainerUtil.map(builder.myURLs, new Function<URL, URL>() { @Override public URL fun(URL url) { return internProtocol(url); } }); - myClassPath = new ClassPath(list.toArray(new URL[list.size()]), canLockJars, canUseCache, acceptUnescapedUrls, preloadJarContents); - myURLs = list; + myClassPath = new ClassPath(myURLs, builder.myLockJars, builder.myUseCache, builder.myAcceptUnescaped, builder.myPreload); + myNativeLibs = builder.myNativeLibs != null ? ContainerUtil.newHashSet(builder.myNativeLibs) : Collections.<String>emptySet(); } - @NotNull public static URL internProtocol(@NotNull URL url) { try { final String protocol = url.getProtocol(); @@ -80,7 +122,7 @@ public class UrlClassLoader extends ClassLoader { return url; } catch (MalformedURLException e) { - LOG.error(e); + Logger.getInstance(UrlClassLoader.class).error(e); return null; } } @@ -133,12 +175,12 @@ public class UrlClassLoader extends ClassLoader { private Class defineClass(String name, Resource res) throws IOException { int i = name.lastIndexOf('.'); if (i != -1) { - String pkgname = name.substring(0, i); + String pkgName = name.substring(0, i); // Check if package already loaded. - Package pkg = getPackage(pkgname); + Package pkg = getPackage(pkgName); if (pkg == null) { try { - definePackage(pkgname, null, null, null, null, null, null, null); + definePackage(pkgName, null, null, null, null, null, null, null); } catch (IllegalArgumentException e) { // do nothing, package already defined by some other thread @@ -157,28 +199,17 @@ public class UrlClassLoader extends ClassLoader { @Override @Nullable // Accessed from PluginClassLoader via reflection // TODO do we need it? public URL findResource(final String name) { - final long started = myDebugTime ? System.nanoTime():0; - - try { - return findResourceImpl(name); - } finally { - long doneFor = myDebugTime ? (System.nanoTime() - started):0; - if (doneFor > NS_THRESHOLD) { - System.out.println((doneFor / 1000000) + " ms for UrlClassLoader.getResource, resource:"+name); - } - } + return findResourceImpl(name); } protected URL findResourceImpl(final String name) { Resource res = _getResource(name); - if (res == null) return null; - return res.getURL(); + return res != null ? res.getURL() : null; } @Nullable private Resource _getResource(final String name) { String n = name; - if (n.startsWith("/")) n = n.substring(1); return myClassPath.getResource(n, true); } @@ -201,12 +232,50 @@ public class UrlClassLoader extends ClassLoader { protected Enumeration<URL> findResources(String name) throws IOException { return myClassPath.getResources(name, true); } - - static final boolean doDebug = System.getProperty("idea.classloading.debug") != null; - private static final Logger LOG = Logger.getInstance("idea.UrlClassLoader"); - static void debug(String s) { - System.out.println(s); // TODO: remove - LOG.debug(s); + @Override + protected String findLibrary(String libName) { + if (BinPathHolder.path != null && myNativeLibs.contains(libName)) { + String fileName = mapLibraryName(libName); + return BinPathHolder.path + File.separator + fileName; + } + + return super.findLibrary(libName); + } + + private static class BinPathHolder { + private static final String path; + + static { + String homePath = PathManager.getHomePath(); + if (new File(homePath, ".idea").exists()) { + if (new File(homePath, "community").exists()) { + homePath += File.separator + "community"; + } + + String libDir = null; + String prefix = homePath + File.separator + "bin" + File.separator; + if (SystemInfo.isWindows) libDir = prefix + "win"; + else if (SystemInfo.isMac) libDir = prefix + "mac"; + else if (SystemInfo.isLinux) libDir = prefix + "linux"; + + path = libDir; + } + else { + path = PathManager.getBinPath(); + } + } + } + + private static String mapLibraryName(String libName) { + String baseName = libName; + if (SystemInfo.is64Bit) { + baseName = baseName.replace("32", "") + "64"; + } + String fileName = System.mapLibraryName(baseName); + if (SystemInfo.isMac) { + fileName = fileName.replace(".jnilib", ".dylib"); + } + return fileName; } } diff --git a/platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java b/platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java index b89ef901d045..af9a97b92c79 100644 --- a/platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java +++ b/platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java @@ -28,6 +28,7 @@ public class ConcurrentMapsTest extends TestCase { ConcurrentWeakHashMap<Object, Object> map = new ConcurrentWeakHashMap<Object, Object>(TObjectHashingStrategy.IDENTITY); map.put(new Object(), new Object()); + tryGcSoftlyReachableObjects(); // sometimes weak references are not collected under linux, try to stress gc to force them do { System.gc(); } @@ -62,6 +63,7 @@ public class ConcurrentMapsTest extends TestCase { ConcurrentWeakHashMap<Object, Object> map = new ConcurrentWeakHashMap<Object, Object>(); map.put(new Object(), new Object()); + tryGcSoftlyReachableObjects(); // sometimes weak references are not collected under linux, try to stress gc to force them do { System.gc(); } @@ -97,6 +99,7 @@ public class ConcurrentMapsTest extends TestCase { ConcurrentWeakValueHashMap<Object, Object> map = new ConcurrentWeakValueHashMap<Object, Object>(); map.put(new Object(), new Object()); + tryGcSoftlyReachableObjects(); // sometimes weak references are not collected under linux, try to stress gc to force them do { System.gc(); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewI.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewI.java index f5bbd9f9a338..1f0052fceba2 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewI.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewI.java @@ -26,4 +26,5 @@ public interface ChangesViewI { void refreshChangesViewNodeAsync(VirtualFile file); void updateProgressText(final String text, final boolean isError); void setBusy(boolean b); + void setShowFlattenMode(boolean state); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java index d039897be2cf..d0ad812998ee 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java @@ -438,6 +438,7 @@ public class ChangesViewManager implements ChangesViewI, JDOMExternalizable, Pro element.setAttribute(ATT_SHOW_IGNORED, String.valueOf(SHOW_IGNORED_MODE)); } + @Override public void setShowFlattenMode(boolean state) { SHOW_FLATTEN_MODE = state; myView.setShowFlatten(SHOW_FLATTEN_MODE); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DummyChangesView.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DummyChangesView.java index 7679eeba0a96..5e349da068e3 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DummyChangesView.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DummyChangesView.java @@ -44,4 +44,8 @@ class DummyChangesView implements ChangesViewI { @Override public void setBusy(boolean b) { } + + @Override + public void setShowFlattenMode(boolean state) { + } } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties index 694189a8ad01..f62b033c85c8 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties @@ -2034,4 +2034,6 @@ inner.class.referenced.via.subclass.quickfix=Rationalize inner class access boolean.parameter.display.name='public' method with 'boolean' parameter boolean.parameter.problem.descriptor='public' method <code>#ref</code> with 'boolean' parameter boolean.parameters.problem.descriptor='public' method <code>#ref</code> with 'boolean' parameters +boolean.parameter.constructor.problem.descriptor='public' constructor <code>#ref</code> with 'boolean' parameter +boolean.parameters.constructor.problem.descriptor='public' constructor <code>#ref</code> with 'boolean' parameters boolean.parameter.only.report.multiple.option=Only report methods with multiple boolean parameters
\ No newline at end of file diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/BooleanParameterInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/BooleanParameterInspection.java index 5513f421793b..d328f49b1cbf 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/BooleanParameterInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/BooleanParameterInspection.java @@ -45,11 +45,17 @@ public class BooleanParameterInspection extends BaseInspection { @NotNull @Override protected String buildErrorString(Object... infos) { - if (((Integer)infos[0]).intValue() == 1) { - return InspectionGadgetsBundle.message("boolean.parameter.problem.descriptor"); + final PsiMethod method = (PsiMethod)infos[0]; + final int booleanParameterCount = ((Integer)infos[1]).intValue(); + if (booleanParameterCount == 1) { + return method.isConstructor() + ? InspectionGadgetsBundle.message("boolean.parameter.constructor.problem.descriptor") + : InspectionGadgetsBundle.message("boolean.parameter.problem.descriptor"); } else { - return InspectionGadgetsBundle.message("boolean.parameters.problem.descriptor"); + return method.isConstructor() + ? InspectionGadgetsBundle.message("boolean.parameters.constructor.problem.descriptor") + : InspectionGadgetsBundle.message("boolean.parameters.problem.descriptor"); } } @@ -96,7 +102,7 @@ public class BooleanParameterInspection extends BaseInspection { if (count == 0 || onlyReportMultiple && count == 1) { return; } - registerMethodError(method, Integer.valueOf(count)); + registerMethodError(method, method, Integer.valueOf(count)); } } } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspectionBase.java index 7e197d9a167d..da52a98e6d70 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspectionBase.java @@ -47,17 +47,28 @@ public class IgnoreResultOfCallInspectionBase extends BaseInspection { /** * @noinspection PublicField */ - @NonNls public String callCheckString = "java.io.InputStream,read," + - "java.io.InputStream,skip," + - "java.lang.StringBuffer,toString," + - "java.lang.StringBuilder,toString," + + @NonNls public String callCheckString = "java.io.File,.*," + + "java.io.InputStream,read|skip|available|markSupported," + + "java.io.Writer,read|skip|ready|markSupported," + + "java.lang.Boolean,.*," + + "java.lang.Byte,.*," + + "java.lang.Character,.*," + + "java.lang.Double,.*," + + "java.lang.Float,.*," + + "java.lang.Integer,.*," + + "java.lang.Long,.*," + + "java.lang.Math,.*," + + "java.lang.Object,equals|hashCode|toString," + + "java.lang.Short,.*," + + "java.lang.StrictMath,.*," + "java.lang.String,.*," + "java.math.BigInteger,.*," + "java.math.BigDecimal,.*," + "java.net.InetAddress,.*," + - "java.io.File,.*," + - "java.lang.Object,equals|hashCode," + - "java.util.regex.Matcher,.*"; + "java.net.URI,.*," + + "java.util.UUID,.*," + + "java.util.regex.Matcher,pattern|toMatchResult|start|end|group|groupCount|matches|find|lookingAt|quoteReplacement|replaceAll|replaceFirst|regionStart|regionEnd|hasTransparantBounds|hasAnchoringBounds|hitEnd|requireEnd," + + "java.util.regex.Pattern,.*"; Map<String, Pattern> patternCache = null; public IgnoreResultOfCallInspectionBase() { diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/StaticVariableInitializationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/StaticVariableInitializationInspection.java index 9886f1c01c57..a1497d80c46d 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/StaticVariableInitializationInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/StaticVariableInitializationInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 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. @@ -44,22 +44,18 @@ public class StaticVariableInitializationInspection extends BaseInspection { @Override @NotNull public String getDisplayName() { - return InspectionGadgetsBundle.message( - "static.variable.may.not.be.initialized.display.name"); + return InspectionGadgetsBundle.message("static.variable.may.not.be.initialized.display.name"); } @Override @NotNull public String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "static.variable.may.not.be.initialized.problem.descriptor"); + return InspectionGadgetsBundle.message("static.variable.may.not.be.initialized.problem.descriptor"); } @Override public JComponent createOptionsPanel() { - return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message( - "primitive.fields.ignore.option"), - this, "m_ignorePrimitives"); + return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("primitive.fields.ignore.option"), this, "m_ignorePrimitives"); } @Override @@ -77,17 +73,14 @@ public class StaticVariableInitializationInspection extends BaseInspection { @Override public void visitField(@NotNull PsiField field) { - if (!field.hasModifierProperty(PsiModifier.STATIC)) { + if (!field.hasModifierProperty(PsiModifier.STATIC) || field.hasModifierProperty(PsiModifier.FINAL)) { return; } if (field.getInitializer() != null) { return; } final PsiClass containingClass = field.getContainingClass(); - if (containingClass == null) { - return; - } - if (containingClass.isEnum()) { + if (containingClass == null || containingClass.isEnum()) { return; } if (m_ignorePrimitives) { @@ -96,15 +89,14 @@ public class StaticVariableInitializationInspection extends BaseInspection { return; } } - final PsiClassInitializer[] initializers = - containingClass.getInitializers(); + final PsiClassInitializer[] initializers = containingClass.getInitializers(); for (final PsiClassInitializer initializer : initializers) { - if (initializer.hasModifierProperty(PsiModifier.STATIC)) { - final PsiCodeBlock body = initializer.getBody(); - if (InitializationUtils.blockAssignsVariableOrFails(body, - field)) { - return; - } + if (!initializer.hasModifierProperty(PsiModifier.STATIC)) { + continue; + } + final PsiCodeBlock body = initializer.getBody(); + if (InitializationUtils.blockAssignsVariableOrFails(body, field)) { + return; } } registerFieldError(field); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspection.java index 25f84464e89c..6360ab864427 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspection.java @@ -26,8 +26,8 @@ import java.awt.*; import java.util.Arrays; public class IgnoreResultOfCallInspection extends IgnoreResultOfCallInspectionBase { - public IgnoreResultOfCallInspection() { - } + + public IgnoreResultOfCallInspection() {} @Override public JComponent createOptionsPanel() { @@ -35,7 +35,7 @@ public class IgnoreResultOfCallInspection extends IgnoreResultOfCallInspectionBa final ListTable table = new ListTable(new ListWrappingTableModel( Arrays.asList(classNames, methodNamePatterns), InspectionGadgetsBundle.message("result.of.method.call.ignored.class.column.title"), InspectionGadgetsBundle.message("result.of.method.call.ignored.method.column.title"))); - final JPanel tablePanel = UiUtils.createAddRemovePanel(table); + final JPanel tablePanel = UiUtils.createAddRemoveTreeClassChooserPanel(table, "Choose class"); final CheckBox checkBox = new CheckBox(InspectionGadgetsBundle.message("result.of.method.call.ignored.non.library.option"), this, "m_reportAllNonLibraryCalls"); panel.add(tablePanel, BorderLayout.CENTER); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/InstanceVariableUninitializedUseInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/InstanceVariableUninitializedUseInspection.java index 8ff9de4b03d3..0e3ddd3a8723 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/InstanceVariableUninitializedUseInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/InstanceVariableUninitializedUseInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 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. @@ -129,7 +129,7 @@ public class InstanceVariableUninitializedUseInspection extends BaseInspection { @Override public void visitField(@NotNull PsiField field) { - if (field.hasModifierProperty(PsiModifier.STATIC)) { + if (field.hasModifierProperty(PsiModifier.STATIC) || field.hasModifierProperty(PsiModifier.FINAL)) { return; } if (field.getInitializer() != null) { diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestMethodWithoutAssertionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestMethodWithoutAssertionInspection.java index bdbfa99c99ce..de8c3bd65b78 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestMethodWithoutAssertionInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestMethodWithoutAssertionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 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. @@ -76,17 +76,16 @@ public class TestMethodWithoutAssertionInspection extends BaseInspection { @Override @NotNull protected String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "test.method.without.assertion.problem.descriptor"); + return InspectionGadgetsBundle.message("test.method.without.assertion.problem.descriptor"); } @Override public JComponent createOptionsPanel() { final JPanel panel = new JPanel(new BorderLayout()); final ListTable table = new ListTable( - new ListWrappingTableModel(Arrays.asList(classNames, methodNamePatterns), InspectionGadgetsBundle.message("class.name"), + new ListWrappingTableModel(Arrays.asList(classNames, methodNamePatterns), "Assertion class name", InspectionGadgetsBundle.message("method.name.pattern"))); - final JPanel tablePanel = UiUtils.createAddRemovePanel(table); + final JPanel tablePanel = UiUtils.createAddRemoveTreeClassChooserPanel(table, "Choose assertion class"); final CheckBox checkBox = new CheckBox(InspectionGadgetsBundle.message("assert.keyword.is.considered.an.assertion"), this, "assertKeywordIsAssertion"); panel.add(tablePanel, BorderLayout.CENTER); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/logging/LoggerInitializedWithForeignClassInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/logging/LoggerInitializedWithForeignClassInspection.java index 37619fedf9f3..e279a7a0070d 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/logging/LoggerInitializedWithForeignClassInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/logging/LoggerInitializedWithForeignClassInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2012 Bas Leijdekkers + * Copyright 2008-2013 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,7 +72,7 @@ public class LoggerInitializedWithForeignClassInspection extends BaseInspection new ListWrappingTableModel(Arrays.asList(loggerFactoryClassNames, loggerFactoryMethodNames), InspectionGadgetsBundle.message("logger.factory.class.name"), InspectionGadgetsBundle.message("logger.factory.method.name"))); - return UiUtils.createAddRemovePanel(table); + return UiUtils.createAddRemoveTreeClassChooserPanel(table, "Choose logger factory class"); } @Override @@ -92,9 +92,7 @@ public class LoggerInitializedWithForeignClassInspection extends BaseInspection @Override @NotNull public String getName() { - return InspectionGadgetsBundle.message( - "logger.initialized.with.foreign.class.quickfix", - newClassName); + return InspectionGadgetsBundle.message("logger.initialized.with.foreign.class.quickfix", newClassName); } @NotNull @@ -130,7 +128,7 @@ public class LoggerInitializedWithForeignClassInspection extends BaseInspection if (!expression.equals(referenceExpression.getQualifierExpression())) { return; } - final String name = referenceExpression.getReferenceName(); + @NonNls final String name = referenceExpression.getReferenceName(); if (!"getName".equals(name)) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryFullyQualifiedNameInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryFullyQualifiedNameInspection.java index 7f8c7246a500..a9b44ac06699 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryFullyQualifiedNameInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryFullyQualifiedNameInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 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,6 @@ package com.siyeh.ig.style; import com.intellij.codeInspection.ProblemDescriptor; -import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.wm.StatusBar; @@ -35,19 +34,18 @@ import com.siyeh.ig.psiutils.HighlightUtils; import com.siyeh.ig.psiutils.ImportUtils; import org.jetbrains.annotations.NotNull; -import javax.swing.*; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; /** - * com.siyeh.ipp.fqnames.ReplaceFullyQualifiedNameWithImportIntention + * @see com.siyeh.ipp.fqnames.ReplaceFullyQualifiedNameWithImportIntention */ public class UnnecessaryFullyQualifiedNameInspection extends BaseInspection { @SuppressWarnings("PublicField") - public boolean m_ignoreJavadoc = false; + public boolean m_ignoreJavadoc = false; // left here to prevent changes to project files. @Override @NotNull @@ -56,12 +54,6 @@ public class UnnecessaryFullyQualifiedNameInspection extends BaseInspection { } @Override - public JComponent createOptionsPanel() { - return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("unnecessary.fully.qualified.name.ignore.option"), - this, "m_ignoreJavadoc"); - } - - @Override @NotNull public String buildErrorString(Object... infos) { final boolean inSameFile = ((Boolean)infos[0]).booleanValue(); @@ -183,7 +175,7 @@ public class UnnecessaryFullyQualifiedNameInspection extends BaseInspection { return new UnnecessaryFullyQualifiedNameVisitor(); } - private class UnnecessaryFullyQualifiedNameVisitor extends BaseInspectionVisitor { + private static class UnnecessaryFullyQualifiedNameVisitor extends BaseInspectionVisitor { @Override public void visitReferenceExpression(PsiReferenceExpression expression) { @@ -211,7 +203,8 @@ public class UnnecessaryFullyQualifiedNameInspection extends BaseInspection { if (element != null) { return; } - if (m_ignoreJavadoc) { + final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(reference.getProject()); + if (styleSettings.USE_FQ_CLASS_NAMES_IN_JAVADOC) { final PsiElement containingComment = PsiTreeUtil.getParentOfType(reference, PsiDocComment.class); if (containingComment != null) { return; @@ -232,7 +225,6 @@ public class UnnecessaryFullyQualifiedNameInspection extends BaseInspection { } final List<PsiJavaCodeReferenceElement> references = new ArrayList(2); references.add(reference); - final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(reference.getProject()); if (styleSettings.INSERT_INNER_CLASS_IMPORTS) { collectInnerClassNames(reference, references); } @@ -257,7 +249,7 @@ public class UnnecessaryFullyQualifiedNameInspection extends BaseInspection { } } - private void collectInnerClassNames(PsiJavaCodeReferenceElement reference, List<PsiJavaCodeReferenceElement> references) { + private static void collectInnerClassNames(PsiJavaCodeReferenceElement reference, List<PsiJavaCodeReferenceElement> references) { PsiElement rParent = reference.getParent(); while (rParent instanceof PsiJavaCodeReferenceElement) { final PsiJavaCodeReferenceElement parentReference = (PsiJavaCodeReferenceElement)rParent; diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/ui/UiUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/ui/UiUtils.java index fb7b8dab1738..0adb02b76f42 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/ui/UiUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/ui/UiUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Bas Leijdekkers + * Copyright 2010-2013 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,13 +41,6 @@ public class UiUtils { private UiUtils() { } - public static void setScrollPaneSize(JScrollPane scrollPane, int rows, int columns) { - final Component view = scrollPane.getViewport().getView(); - final FontMetrics fontMetrics = view.getFontMetrics(view.getFont()); - final int width = fontMetrics.charWidth('m') * columns; - scrollPane.setPreferredSize(new Dimension(width, fontMetrics.getHeight() * rows)); - } - public static void setComponentSize(Component component, int rows, int columns) { final FontMetrics fontMetrics = component.getFontMetrics(component.getFont()); final int width = fontMetrics.charWidth('m') * columns; @@ -65,14 +58,7 @@ public class UiUtils { @Override public void run() { final int lastRowIndex = tableModel.getRowCount() - 1; - final Rectangle rectangle = table.getCellRect(lastRowIndex, 0, true); - table.scrollRectToVisible(rectangle); - table.editCellAt(lastRowIndex, 0); - final ListSelectionModel selectionModel = table.getSelectionModel(); - selectionModel.setSelectionInterval(lastRowIndex, lastRowIndex); - final TableCellEditor editor = table.getCellEditor(); - final Component component = editor.getTableCellEditorComponent(table, null, true, lastRowIndex, 0); - component.requestFocus(); + editTableCell(table, lastRowIndex, 0); } }); } @@ -80,8 +66,7 @@ public class UiUtils { .disableUpDownActions().createPanel(); } - public static JPanel createAddRemoveTreeClassChooserPanel(final ListTable table, - final String chooserTitle, + public static JPanel createAddRemoveTreeClassChooserPanel(final ListTable table, final String chooserTitle, @NonNls String... ancestorClasses) { final ClassFilter filter; if (ancestorClasses.length == 0) { @@ -96,43 +81,55 @@ public class UiUtils { public void run(AnActionButton button) { final DataContext dataContext = DataManager.getInstance().getDataContext(table); final Project project = PlatformDataKeys.PROJECT.getData(dataContext); - if (project == null) { - return; - } - final TreeClassChooserFactory chooserFactory = TreeClassChooserFactory.getInstance(project); - final TreeClassChooser classChooser = - chooserFactory.createWithInnerClassesScopeChooser(chooserTitle, GlobalSearchScope.allScope(project), filter, null); - classChooser.showDialog(); - final PsiClass selectedClass = classChooser.getSelected(); - if (selectedClass == null) { - return; - } - final String qualifiedName = selectedClass.getQualifiedName(); - final ListWrappingTableModel tableModel = table.getModel(); - final int index = tableModel.indexOf(qualifiedName, 0); final int rowIndex; - if (index < 0) { - tableModel.addRow(qualifiedName); + final ListWrappingTableModel tableModel = table.getModel(); + if (project == null) { + tableModel.addRow(); rowIndex = tableModel.getRowCount() - 1; } else { - rowIndex = index; - } - final ListSelectionModel selectionModel = - table.getSelectionModel(); - selectionModel.setSelectionInterval(rowIndex, rowIndex); - EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - final Rectangle rectangle = table.getCellRect(rowIndex, 0, true); - table.scrollRectToVisible(rectangle); + final TreeClassChooserFactory chooserFactory = TreeClassChooserFactory.getInstance(project); + final TreeClassChooser classChooser = + chooserFactory.createWithInnerClassesScopeChooser(chooserTitle, GlobalSearchScope.allScope(project), filter, null); + classChooser.showDialog(); + final PsiClass selectedClass = classChooser.getSelected(); + if (selectedClass == null) { + return; } - }); + final String qualifiedName = selectedClass.getQualifiedName(); + final int index = tableModel.indexOf(qualifiedName, 0); + if (index < 0) { + tableModel.addRow(qualifiedName); + rowIndex = tableModel.getRowCount() - 1; + } + else { + rowIndex = index; + } + } + editTableCell(table, rowIndex, table.getColumnCount() > 1 && project != null ? 1 : 0); } }).setRemoveAction(new RemoveAction(table)) .disableUpDownActions().createPanel(); } + private static void editTableCell(final ListTable table, final int row, final int column) { + final ListSelectionModel selectionModel = table.getSelectionModel(); + selectionModel.setSelectionInterval(row, row); + EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + final ListWrappingTableModel tableModel = table.getModel(); + table.requestFocus(); + final Rectangle rectangle = table.getCellRect(row, column, true); + table.scrollRectToVisible(rectangle); + table.editCellAt(row, column); + final TableCellEditor editor = table.getCellEditor(); + final Component component = editor.getTableCellEditorComponent(table, tableModel.getValueAt(row, column), true, row, column); + component.requestFocus(); + } + }); + } + public static JPanel createTreeClassChooserList(final Collection<String> collection, String borderTitle, final String chooserTitle, @@ -179,8 +176,7 @@ public class UiUtils { .setRemoveAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton anActionButton) { - final Object selectedValue = list.getSelectedValue(); - collection.remove(selectedValue); + collection.remove(list.getSelectedValue()); ListUtil.removeSelectedItems(list); } }).createPanel(); diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryFullyQualifiedName.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryFullyQualifiedName.html index 874c4107ba4b..0ee3585affe9 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryFullyQualifiedName.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryFullyQualifiedName.html @@ -4,6 +4,8 @@ Reports on fully qualified class names which can be shortened. The quick fix for inspection will shorten the fully qualified names, adding import statements as necessary. <!-- tooltip end --> <p> - +In <code>Settings | Code Style | Java | Imports</code> two settings can be found which influence this inspection. +Use the settings there to specify if references to inner classes +should be qualified with the outer class and if fully qualified names are allowed in javadoc. </body> </html>
\ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/instance_variable_uninitialized_use/InstanceVariableUninitializedUse.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/instance_variable_uninitialized_use/InstanceVariableUninitializedUse.java index 58d468da93f0..f43884c69be6 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/instance_variable_uninitialized_use/InstanceVariableUninitializedUse.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/instance_variable_uninitialized_use/InstanceVariableUninitializedUse.java @@ -24,5 +24,12 @@ class InstanceFieldVsDoWhile { object = new Object(); } while (object.hashCode() < 1000); // Instance field used before initialization } +} +class FinalField { + private final Object object; -}
\ No newline at end of file + FinalField() { + System.out.println(object); + object = null; + } +} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/static_variable_initialization/StaticVariableInitializationInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/static_variable_initialization/StaticVariableInitializationInspection.java index eb8714e964f1..85385b8dd8b6 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/static_variable_initialization/StaticVariableInitializationInspection.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/static_variable_initialization/StaticVariableInitializationInspection.java @@ -36,3 +36,11 @@ public class StaticVariableInitializationInspection } } } +class FinalField { + public static final Object o; + + static { + System.out.println("o = " + o); + o = null; + } +} diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/BooleanParameterInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/BooleanParameterInspectionTest.java index 486037702326..b0c134fc7ca8 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/BooleanParameterInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/BooleanParameterInspectionTest.java @@ -32,6 +32,12 @@ public class BooleanParameterInspectionTest extends LightInspectionTestCase { "}"); } + public void testConstructor() { + doTest("class X {" + + " public /*'public' constructor 'X' with 'boolean' parameter*/X/**/(boolean x) {}" + + "}"); + } + @Override protected LocalInspectionTool getInspection() { return new BooleanParameterInspection(); diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/JDBCResourceInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/JDBCResourceInspectionTest.java index d834557e401b..cf5f1d7aa1ae 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/JDBCResourceInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/JDBCResourceInspectionTest.java @@ -38,25 +38,23 @@ public class JDBCResourceInspectionTest extends LightInspectionTestCase { } public void testARM() { - // doesn't work with mock jdk - /*doTest("import java.sql.*;" + - "class X {" + - " void m(Driver driver) throws SQLException {" + - " try (Connection connection = driver.connect(\"asdf\", null);" + - " PreparedStatement statement = connection.prepareStatement(\"SELECT *\");" + - " ResultSet resultSet = statement.executeQuery()) {" + - " while (resultSet.next()) {" + - " }" + - " }" + - " }" + - "}");*/ + doTest("import java.sql.*;\n" + + "class X {\n" + + " void m(Driver driver) throws SQLException {\n" + + " try (Connection connection = driver.connect(\"jdbc\", null);\n" + + " PreparedStatement statement = connection.prepareStatement(\"SELECT *\");\n" + + " ResultSet resultSet = statement.executeQuery()) {\n" + + " while (resultSet.next()) { resultSet.getMetaData(); }\n" + + " }\n" + + " }\n" + + "}"); } public void testSimple() { doTest("import java.sql.*;" + "class X {" + " void m(Driver driver) throws SQLException {" + - " /*'Connection' should be opened in front of a 'try' block and closed in the corresponding 'finally' block*/driver.connect(\"asdf\", null)/**/;" + + " /*'Connection' should be opened in front of a 'try' block and closed in the corresponding 'finally' block*/driver.connect(\"jdbc\", null)/**/;" + " }" + "}"); } diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/InferLambdaParameterTypeIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/InferLambdaParameterTypeIntention.java index 9e9658f0f354..ca1dc575fe1b 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/InferLambdaParameterTypeIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/InferLambdaParameterTypeIntention.java @@ -16,7 +16,9 @@ package com.siyeh.ipp.types; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; @@ -46,13 +48,14 @@ public class InferLambdaParameterTypeIntention extends Intention { final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class); LOG.assertTrue(lambdaExpression != null); final PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType(); - final String buf = getInferredTypes(functionalInterfaceType, lambdaExpression); - lambdaExpression.getParameterList().replace(JavaPsiFacade.getElementFactory(element.getProject()).createMethodFromText("void foo" + buf, - element).getParameterList()); + final String buf = getInferredTypes(functionalInterfaceType, lambdaExpression, true); + final Project project = element.getProject(); + final PsiMethod methodFromText = JavaPsiFacade.getElementFactory(project).createMethodFromText("void foo" + buf, element); + JavaCodeStyleManager.getInstance(project).shortenClassReferences(lambdaExpression.getParameterList().replace(methodFromText.getParameterList())); } @Nullable - private static String getInferredTypes(PsiType functionalInterfaceType, final PsiLambdaExpression lambdaExpression) { + private static String getInferredTypes(PsiType functionalInterfaceType, final PsiLambdaExpression lambdaExpression, boolean useFQN) { final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); final StringBuilder buf = new StringBuilder(); buf.append("("); @@ -65,7 +68,7 @@ public class InferLambdaParameterTypeIntention extends Intention { PsiParameter parameter = parameters[i]; final PsiType psiType = GenericsUtil.eliminateWildcards(LambdaUtil.getSubstitutor(interfaceMethod, resolveResult).substitute(parameter.getType())); if (psiType != null) { - buf.append(psiType.getPresentableText()).append(" ").append(lambdaParameters[i].getName()); + buf.append(useFQN ? psiType.getCanonicalText() : psiType.getPresentableText()).append(" ").append(lambdaParameters[i].getName()); } else { buf.append(lambdaParameters[i].getName()); @@ -94,7 +97,7 @@ public class InferLambdaParameterTypeIntention extends Intention { if (PsiTreeUtil.isAncestor(lambdaExpression.getParameterList(), element, false)) { final PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType(); if (functionalInterfaceType != null && LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType) != null && LambdaUtil.isLambdaFullyInferred(lambdaExpression, functionalInterfaceType)) { - myInferredTypesText = getInferredTypes(functionalInterfaceType, lambdaExpression); + myInferredTypesText = getInferredTypes(functionalInterfaceType, lambdaExpression, false); return myInferredTypesText != null; } } diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/inferLambdaParameterType/File.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/inferLambdaParameterType/File.java new file mode 100644 index 000000000000..d6536bdca71c --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/inferLambdaParameterType/File.java @@ -0,0 +1,5 @@ +class X { + { + Comparable<java.io.File> c = <caret>o -> 1; + } +} diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/inferLambdaParameterType/File_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/inferLambdaParameterType/File_after.java new file mode 100644 index 000000000000..d99ddf4dccdc --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/inferLambdaParameterType/File_after.java @@ -0,0 +1,7 @@ +import java.io.File; + +class X { + { + Comparable<java.io.File> c = (File o) -> 1; + } +} diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/InferLambdaParameterTypeIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/InferLambdaParameterTypeIntentionTest.java index 94bf41b59cb7..6253144de70f 100644 --- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/InferLambdaParameterTypeIntentionTest.java +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/InferLambdaParameterTypeIntentionTest.java @@ -23,6 +23,10 @@ public class InferLambdaParameterTypeIntentionTest extends IPPTestCase { doTest("Expand lambda to (String o) -> {...}"); } + public void testFile() { + doTest("Expand lambda to (File o) -> {...}"); + } + public void testTwoParams() { doTest("Expand lambda to (String o1, String o2) -> {...}"); } diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntInstallation.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntInstallation.java index 3b4a28971f13..f07283b52347 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntInstallation.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntInstallation.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; -import java.util.Collections; import java.util.Comparator; import java.util.Properties; @@ -117,11 +116,11 @@ public class AntInstallation { public String getVersion() { return VERSION.get(myProperties); } - + public String getHomeDir() { return HOME_DIR.get(myProperties); } - + public AbstractProperty.AbstractPropertyContainer getProperties() { return myProperties; } @@ -134,7 +133,7 @@ public class AntInstallation { public void updateClasspath() { myClassLoaderHolder.updateClasspath(); } - + public static AntInstallation fromHome(String homePath) throws ConfigurationException { File antHome = new File(homePath); String antPath = "'" + antHome.getAbsolutePath() + "'"; @@ -166,7 +165,7 @@ public class AntInstallation { Properties properties = new Properties(); InputStream stream = null; try { - stream = new UrlClassLoader(Collections.singletonList(antJar.toURL()), null, false, false, true, false).getResourceAsStream(VERSION_RESOURCE); + stream = UrlClassLoader.build().urls(antJar.toURI().toURL()).allowUnescaped().noPreload().get().getResourceAsStream(VERSION_RESOURCE); properties.load(stream); } catch (MalformedURLException e) { diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntResourcesClassLoader.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntResourcesClassLoader.java index feb9356add33..c5ee60111e04 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntResourcesClassLoader.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntResourcesClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ public class AntResourcesClassLoader extends UrlClassLoader { private final Set<String> myMisses = new THashSet<String>(); public AntResourcesClassLoader(final List<URL> urls, final ClassLoader parentLoader, final boolean canLockJars, final boolean canUseCache) { - super(urls, parentLoader, canLockJars, canUseCache, true, false); + super(build().urls(urls).parent(parentLoader).allowLock(canLockJars).useCache(canUseCache).allowUnescaped().noPreload()); } protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException { diff --git a/plugins/devkit/src/actions/ShowSerializedXmlAction.java b/plugins/devkit/src/actions/ShowSerializedXmlAction.java index e6280912535c..9de4276ddefb 100644 --- a/plugins/devkit/src/actions/ShowSerializedXmlAction.java +++ b/plugins/devkit/src/actions/ShowSerializedXmlAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -99,9 +99,9 @@ public class ShowSerializedXmlAction extends DumbAwareAction { LOG.info(e1); } } - + final Project project = module.getProject(); - UrlClassLoader loader = new UrlClassLoader(urls, XmlSerializer.class.getClassLoader()); + UrlClassLoader loader = UrlClassLoader.build().urls(urls).parent(XmlSerializer.class.getClassLoader()).get(); final Class<?> aClass; try { aClass = Class.forName(className, true, loader); diff --git a/plugins/google-app-engine/google-app-engine.iml b/plugins/google-app-engine/google-app-engine.iml index ab104003fd25..956452da42a5 100644 --- a/plugins/google-app-engine/google-app-engine.iml +++ b/plugins/google-app-engine/google-app-engine.iml @@ -24,7 +24,7 @@ <orderEntry type="module" module-name="compiler-impl" /> <orderEntry type="module" module-name="dom-openapi" /> <orderEntry type="module" module-name="java-impl" /> - <orderEntry type="module" module-name="remote-servers-api" /> + <orderEntry type="module" module-name="remote-servers-java-api" /> </component> </module> diff --git a/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java index 5d9207635be7..6ebdc4951ac1 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java @@ -130,7 +130,7 @@ public class AppEngineCloudType extends ServerType<AppEngineServerConfiguration> @Override public List<DeploymentSource> getAvailableDeploymentSources() { List<Artifact> artifacts = AppEngineUtil.collectWebArtifacts(myProject, true); - return DeploymentSourceUtil.getInstance().createArtifactDeploymentSources(myProject, artifacts); + return JavaDeploymentSourceUtil.getInstance().createArtifactDeploymentSources(myProject, artifacts); } @NotNull diff --git a/plugins/google-app-engine/source/com/intellij/appengine/sdk/impl/AppEngineSdkUtil.java b/plugins/google-app-engine/source/com/intellij/appengine/sdk/impl/AppEngineSdkUtil.java index 15400345eae1..645c6f7ba2f8 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/sdk/impl/AppEngineSdkUtil.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/sdk/impl/AppEngineSdkUtil.java @@ -98,7 +98,8 @@ public class AppEngineSdkUtil { public static Map<String, Set<String>> computeWhiteList(final File toolsApiJarFile) { try { final THashMap<String, Set<String>> map = new THashMap<String, Set<String>>(); - ClassLoader loader = new UrlClassLoader(Collections.singletonList(toolsApiJarFile.toURI().toURL()), AppEngineSdkUtil.class.getClassLoader()); + final ClassLoader loader = UrlClassLoader.build().urls(toolsApiJarFile.toURI().toURL()).parent( + AppEngineSdkUtil.class.getClassLoader()).get(); final Class<?> whiteListClass = Class.forName("com.google.apphosting.runtime.security.WhiteList", true, loader); final Set<String> classes = (Set<String>) whiteListClass.getMethod("getWhiteList").invoke(null); for (String qualifiedName : classes) { diff --git a/plugins/gradle/resources/i18n/GradleBundle.properties b/plugins/gradle/resources/i18n/GradleBundle.properties index 8252d8be0262..254c04a80c20 100644 --- a/plugins/gradle/resources/i18n/GradleBundle.properties +++ b/plugins/gradle/resources/i18n/GradleBundle.properties @@ -3,6 +3,7 @@ gradle.name=Gradle gradle.settings.text.use.wrapper=Use gradle wrapper (recommended) gradle.settings.text.use.wrapper.disabled=Use gradle wrapper (not configured for the current project) gradle.settings..text.use.local.distribution=Use local gradle distribution +gradle.settings.text.use.bundled.distribution=Use bundled gradle distribution: ({0}) gradle.settings.text.home.path=Gradle home: gradle.settings.text.service.dir.path=Service directory path: diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java index 732e7025418e..dec89c51ab0e 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java @@ -167,10 +167,10 @@ implements ExternalSystemConfigurableAware, ExternalSystemUiAware, ExternalSyste } GradleProjectSettings projectLevelSettings = settings.getLinkedProjectSettings(pair.second); - boolean useWrapper = projectLevelSettings != null && !projectLevelSettings.isPreferLocalInstallationToWrapper(); + DistributionType distributionType = projectLevelSettings == null ? DistributionType.BUNDLED : projectLevelSettings.getDistributionType(); GradleExecutionSettings result = new GradleExecutionSettings(localGradlePath, settings.getServiceDirectoryPath(), - useWrapper, + distributionType, settings.getGradleVmOptions()); for (GradleProjectResolverExtension extension : RESOLVER_EXTENSIONS.getValue()) { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/DelegatingGradleSettingsListenerAdapter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/DelegatingGradleSettingsListenerAdapter.java index 13dbd1182304..d72eea0c4127 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/DelegatingGradleSettingsListenerAdapter.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/DelegatingGradleSettingsListenerAdapter.java @@ -19,6 +19,7 @@ import com.intellij.openapi.externalSystem.settings.DelegatingExternalSystemSett import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsListener; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.gradle.settings.DistributionType; import org.jetbrains.plugins.gradle.settings.GradleProjectSettings; import org.jetbrains.plugins.gradle.settings.GradleSettingsListener; @@ -39,7 +40,7 @@ public class DelegatingGradleSettingsListenerAdapter extends DelegatingExternalS } @Override - public void onPreferLocalGradleDistributionToWrapperChange(boolean currentValue, @NotNull String linkedProjectPath) { + public void onGradleDistributionTypeChange(DistributionType currentValue, @NotNull String linkedProjectPath) { } @Override diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradlePositionManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradlePositionManager.java index d01a931cb5a2..771260eb84d8 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradlePositionManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradlePositionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -149,7 +149,7 @@ public class GradlePositionManager extends ScriptPositionManagerHelper { } } - return new UrlClassLoader(urls, null); + return UrlClassLoader.build().urls(urls).get(); } private class ScriptSourceMapCalculator implements CachedValueProvider<FactoryMap<File, String>> { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleSettingsListenerAdapter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleSettingsListenerAdapter.java index 2f01fe40a05d..9aae216b0470 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleSettingsListenerAdapter.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleSettingsListenerAdapter.java @@ -3,6 +3,7 @@ package org.jetbrains.plugins.gradle.config; import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsListenerAdapter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.gradle.settings.DistributionType; import org.jetbrains.plugins.gradle.settings.GradleProjectSettings; import org.jetbrains.plugins.gradle.settings.GradleSettingsListener; @@ -19,7 +20,7 @@ public abstract class GradleSettingsListenerAdapter extends ExternalSystemSettin } @Override - public void onPreferLocalGradleDistributionToWrapperChange(boolean currentValue, @NotNull String linkedProjectPath) { + public void onGradleDistributionTypeChange(DistributionType currentValue, @NotNull String linkedProjectPath) { } @Override diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java index 2c3e9ab4581d..544542ffb1d3 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java @@ -16,6 +16,7 @@ import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.gradle.settings.DistributionType; import org.jetbrains.plugins.gradle.settings.GradleProjectSettings; import org.jetbrains.plugins.gradle.settings.GradleSettings; import org.jetbrains.plugins.gradle.util.GradleEnvironment; @@ -112,11 +113,7 @@ public class GradleInstallationManager { */ @Nullable public File getGradleHome(@Nullable Project project, @NotNull String linkedProjectPath) { - File result = getWrapperHome(project, linkedProjectPath); - if (result != null) { - return result; - } - result = getManuallyDefinedGradleHome(project, linkedProjectPath); + File result = getManuallyDefinedGradleHome(project, linkedProjectPath); if (result != null) { return result; } @@ -175,60 +172,6 @@ public class GradleInstallationManager { return home == null ? null : LocalFileSystem.getInstance().refreshAndFindFileByIoFile(home); } - @Nullable - public File getWrapperHome(@Nullable Project project, @NotNull String linkedProjectPath) { - if (project == null) { - return null; - } - - GradleProjectSettings settings = GradleSettings.getInstance(project).getLinkedProjectSettings(linkedProjectPath); - if (settings == null) { - return null; - } - - if (settings.isPreferLocalInstallationToWrapper()) { - return null; - } - - String distribution = GradleUtil.getWrapperDistribution(linkedProjectPath); - if (distribution == null) { - return null; - } - File gradleSystemDir = new File(System.getProperty("user.home"), ".gradle"); - if (!gradleSystemDir.isDirectory()) { - return null; - } - - File gradleWrapperDistributionsHome = new File(gradleSystemDir, "wrapper/dists"); - if (!gradleWrapperDistributionsHome.isDirectory()) { - return null; - } - - File targetDistributionHome = new File(gradleWrapperDistributionsHome, distribution); - if (!targetDistributionHome.isDirectory()) { - return null; - } - - File[] files = targetDistributionHome.listFiles(); - if (files == null || files.length != 1) { - // Gradle keeps wrapper at a directory which name is a hash value like '35oej0jnbfh6of4dd05531edaj' - return null; - } - - File[] distFiles = files[0].listFiles(new FileFilter() { - @Override - public boolean accept(File f) { - return f.isDirectory(); - } - }); - if (distFiles == null || distFiles.length != 1) { - // There should exist only the gradle directory in the distribution directory - return null; - } - - return distFiles[0].isDirectory() ? distFiles[0] : null; - } - /** * Allows to ask for user-defined path to gradle. * @@ -344,6 +287,17 @@ public class GradleInstallationManager { } /** + * Allows to answer if given virtual file points to the gradle installation root. + * + * @param file gradle installation root candidate + * @return <code>true</code> if we consider that given file actually points to the gradle installation root; + * <code>false</code> otherwise + */ + public boolean isGradleSdkHome(String gradleHomePath) { + return isGradleSdkHome(new File(gradleHomePath)); + } + + /** * Allows to answer if given files contain the one from gradle installation. * * @param files files to process @@ -411,7 +365,6 @@ public class GradleInstallationManager { if (StringUtil.isEmpty(path)) { continue; } - assert path != null; final Collection<File> libraries = getAllLibraries(project, path); if (libraries == null) { continue; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/DistributionFactoryExt.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/DistributionFactoryExt.java new file mode 100644 index 000000000000..0af4476ea1f9 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/DistributionFactoryExt.java @@ -0,0 +1,165 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.gradle.service.project; + +import org.gradle.internal.classpath.ClassPath; +import org.gradle.internal.classpath.DefaultClassPath; +import org.gradle.logging.ProgressLogger; +import org.gradle.logging.ProgressLoggerFactory; +import org.gradle.tooling.GradleConnectionException; +import org.gradle.tooling.internal.consumer.Distribution; +import org.gradle.tooling.internal.consumer.DistributionFactory; +import org.gradle.util.DistributionLocator; +import org.gradle.util.GradleVersion; +import org.gradle.wrapper.*; + +import java.io.File; +import java.io.FileNotFoundException; +import java.net.URI; +import java.util.LinkedHashSet; +import java.util.Set; + +/** + * @author Vladislav.Soroka + * @since 8/23/13 + */ +public class DistributionFactoryExt extends DistributionFactory { + private final File userHomeDir; + + public DistributionFactoryExt(File userHomeDir) { + super(userHomeDir); + this.userHomeDir = userHomeDir; + } + + /** + * Returns the default distribution to use for the specified project. + */ + public Distribution getWrappedDistribution(File propertiesFile) { + //noinspection UseOfSystemOutOrSystemErr + WrapperExecutor wrapper = WrapperExecutor.forWrapperPropertiesFile(propertiesFile, System.out); + if (wrapper.getDistribution() != null) { + return new ZippedDistribution(wrapper.getConfiguration()); + } + return getDownloadedDistribution(GradleVersion.current().getVersion()); + } + + private Distribution getDownloadedDistribution(String gradleVersion) { + URI distUri = new DistributionLocator().getDistributionFor(GradleVersion.version(gradleVersion)); + return getDistribution(distUri); + } + + private static class ProgressReportingDownload implements IDownload { + private final ProgressLoggerFactory progressLoggerFactory; + + private ProgressReportingDownload(ProgressLoggerFactory progressLoggerFactory) { + this.progressLoggerFactory = progressLoggerFactory; + } + + public void download(URI address, File destination) throws Exception { + ProgressLogger progressLogger = progressLoggerFactory.newOperation(DistributionFactory.class); + progressLogger.setDescription(String.format("Download %s", address)); + progressLogger.started(); + try { + new Download("Gradle Tooling API", GradleVersion.current().getVersion()).download(address, destination); + } + finally { + progressLogger.completed(); + } + } + } + + private static class InstalledDistribution implements Distribution { + private final File gradleHomeDir; + private final String displayName; + private final String locationDisplayName; + + public InstalledDistribution(File gradleHomeDir, String displayName, String locationDisplayName) { + this.gradleHomeDir = gradleHomeDir; + this.displayName = displayName; + this.locationDisplayName = locationDisplayName; + } + + public String getDisplayName() { + return displayName; + } + + public ClassPath getToolingImplementationClasspath(ProgressLoggerFactory progressLoggerFactory) { + ProgressLogger progressLogger = progressLoggerFactory.newOperation(DistributionFactory.class); + progressLogger.setDescription("Validate distribution"); + progressLogger.started(); + try { + return getToolingImpl(); + } + finally { + progressLogger.completed(); + } + } + + private ClassPath getToolingImpl() { + if (!gradleHomeDir.exists()) { + throw new IllegalArgumentException(String.format("The specified %s does not exist.", locationDisplayName)); + } + if (!gradleHomeDir.isDirectory()) { + throw new IllegalArgumentException(String.format("The specified %s is not a directory.", locationDisplayName)); + } + File libDir = new File(gradleHomeDir, "lib"); + if (!libDir.isDirectory()) { + throw new IllegalArgumentException( + String.format("The specified %s does not appear to contain a Gradle distribution.", locationDisplayName)); + } + Set<File> files = new LinkedHashSet<File>(); + //noinspection ConstantConditions + for (File file : libDir.listFiles()) { + if (file.getName().endsWith(".jar")) { + files.add(file); + } + } + return new DefaultClassPath(files); + } + } + + private class ZippedDistribution implements Distribution { + private final WrapperConfiguration wrapperConfiguration; + private InstalledDistribution installedDistribution; + + private ZippedDistribution(WrapperConfiguration wrapperConfiguration) { + this.wrapperConfiguration = wrapperConfiguration; + } + + public String getDisplayName() { + return String.format("Gradle distribution '%s'", wrapperConfiguration.getDistribution()); + } + + public ClassPath getToolingImplementationClasspath(ProgressLoggerFactory progressLoggerFactory) { + if (installedDistribution == null) { + File installDir; + try { + Install install = new Install(new ProgressReportingDownload(progressLoggerFactory), new PathAssembler(userHomeDir)); + installDir = install.createDist(wrapperConfiguration); + } + catch (FileNotFoundException e) { + throw new IllegalArgumentException(String.format("The specified %s does not exist.", getDisplayName()), e); + } + catch (Exception e) { + throw new GradleConnectionException( + String.format("Could not install Gradle distribution from '%s'.", wrapperConfiguration.getDistribution()), e); + } + installedDistribution = new InstalledDistribution(installDir, getDisplayName(), getDisplayName()); + } + return installedDistribution.getToolingImplementationClasspath(progressLoggerFactory); + } + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java index 6a0b53ffc45d..694b1a599a26 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java @@ -20,12 +20,16 @@ import com.intellij.openapi.externalSystem.model.ExternalSystemException; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationEvent; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ArrayUtilRt; import com.intellij.util.Function; +import com.intellij.util.SystemProperties; import com.intellij.util.containers.ContainerUtilRt; +import org.gradle.StartParameter; import org.gradle.tooling.*; import org.gradle.tooling.internal.consumer.DefaultGradleConnector; +import org.gradle.tooling.internal.consumer.Distribution; import org.gradle.tooling.model.idea.BasicIdeaProject; import org.gradle.tooling.model.idea.IdeaProject; import org.jetbrains.annotations.NotNull; @@ -34,6 +38,7 @@ import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings; import java.io.File; import java.io.IOException; +import java.lang.reflect.Field; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; @@ -127,6 +132,17 @@ public class GradleExecutionHelper { } public <T> T execute(@NotNull String projectPath, @Nullable GradleExecutionSettings settings, @NotNull Function<ProjectConnection, T> f) { + + String userDir = null; + try { + // This is a workaround to get right base dir in case of 'PROJECT' setting used + // see org.gradle.wrapper.PathAssembler#getBaseDir for details + userDir = System.getProperty("user.dir"); + System.setProperty("user.dir", projectPath); + } + catch (Exception e) { + // ignore + } ProjectConnection connection = getConnection(projectPath, settings); try { return f.fun(connection); @@ -137,6 +153,53 @@ public class GradleExecutionHelper { finally { try { connection.close(); + if (userDir != null) { + // restore original user.dir property + System.setProperty("user.dir", userDir); + } + } + catch (Throwable e) { + // ignore + } + } + } + + public void ensureInstalledWrapper(@NotNull ExternalSystemTaskId id, + @NotNull String projectPath, + @NotNull GradleExecutionSettings settings, + @NotNull ExternalSystemTaskNotificationListener listener) { + ProjectConnection connection = getConnection(projectPath, settings); + try { + BuildLauncher launcher = getBuildLauncher(id, connection, settings, listener); + try { + final File tempFile = FileUtil.createTempFile("wrap", ".gradle"); + tempFile.deleteOnExit(); + final File wrapperPropertyFileLocation = FileUtil.createTempFile("wrap", "loc"); + wrapperPropertyFileLocation.deleteOnExit(); + final String[] lines = { + "gradle.taskGraph.afterTask { Task task ->", + " if (task instanceof Wrapper) {", + " def wrapperPropertyFileLocation = task.jarFile.getCanonicalPath() - '.jar' + '.properties'", + " new File('" + StringUtil.escapeBackSlashes(wrapperPropertyFileLocation.getCanonicalPath()) + "').write wrapperPropertyFileLocation", + "}}", + }; + FileUtil.writeToFile(tempFile, StringUtil.join(lines, SystemProperties.getLineSeparator())); + launcher.withArguments("--init-script", tempFile.getAbsolutePath()); + launcher.forTasks("wrapper"); + launcher.run(); + String wrapperPropertyFile = FileUtil.loadFile(wrapperPropertyFileLocation); + settings.setWrapperPropertyFile(wrapperPropertyFile); + } + catch (IOException e) { + throw new ExternalSystemException(e); + } + } + catch (Throwable e) { + throw new ExternalSystemException(e); + } + finally { + try { + connection.close(); } catch (Throwable e) { // ignore @@ -147,31 +210,48 @@ public class GradleExecutionHelper { /** * Allows to retrieve gradle api connection to use for the given project. * - * @param projectPath target project path - * @param settings execution settings to use - * @return connection to use - * @throws IllegalStateException if it's not possible to create the connection + * @param projectPath target project path + * @param settings execution settings to use + * @return connection to use + * @throws IllegalStateException if it's not possible to create the connection */ @NotNull - private static ProjectConnection getConnection(@NotNull String projectPath, @Nullable GradleExecutionSettings settings) + private static ProjectConnection getConnection(@NotNull String projectPath, + @Nullable GradleExecutionSettings settings) throws IllegalStateException { File projectDir = new File(projectPath); GradleConnector connector = GradleConnector.newConnector(); - if (settings != null) { - - // Setup wrapper/local installation usage. - if (!settings.isUseWrapper()) { - String gradleHome = settings.getGradleHome(); - if (gradleHome != null) { - try { - // There were problems with symbolic links processing at the gradle side. - connector.useInstallation(new File(gradleHome).getCanonicalFile()); + int ttl = -1; + + if(settings != null) { + //noinspection EnumSwitchStatementWhichMissesCases + switch (settings.getDistributionType()) { + case LOCAL: + String gradleHome = settings.getGradleHome(); + if (gradleHome != null) { + try { + // There were problems with symbolic links processing at the gradle side. + connector.useInstallation(new File(gradleHome).getCanonicalFile()); + } + catch (IOException e) { + connector.useInstallation(new File(settings.getGradleHome())); + } } - catch (IOException e) { - connector.useInstallation(new File(settings.getGradleHome())); + break; + case WRAPPED: + if(settings.getWrapperPropertyFile() != null) { + File propertiesFile = new File(settings.getWrapperPropertyFile()); + Distribution distribution = + new DistributionFactoryExt(StartParameter.DEFAULT_GRADLE_USER_HOME).getWrappedDistribution(propertiesFile); + try { + setField(connector, "distribution", distribution); + } + catch (Exception e) { + throw new ExternalSystemException(e); + } } - } + break; } // Setup service directory if necessary. @@ -184,12 +264,11 @@ public class GradleExecutionHelper { if (settings.isVerboseProcessing() && connector instanceof DefaultGradleConnector) { ((DefaultGradleConnector)connector).setVerboseLogging(true); } + ttl = (int)settings.getRemoteProcessIdleTtlInMs(); + } - // Setup daemon ttl if necessary. - long ttl = settings.getRemoteProcessIdleTtlInMs(); - if (ttl > 0 && connector instanceof DefaultGradleConnector) { - ((DefaultGradleConnector)connector).daemonMaxIdleTime((int)ttl, TimeUnit.MILLISECONDS); - } + if (ttl > 0 && connector instanceof DefaultGradleConnector) { + ((DefaultGradleConnector)connector).daemonMaxIdleTime(ttl, TimeUnit.MILLISECONDS); } connector.forProjectDirectory(projectDir); ProjectConnection connection = connector.connect(); @@ -200,4 +279,27 @@ public class GradleExecutionHelper { } return connection; } + + /** + * Utility to set field in object if there is no public setter for it. + * It's not recommended to use this method. + * FIXME: remove this workaround after gradle API changed + * + * @param obj Object to be modified + * @param fieldName name of object's field + * @param fieldValue value to be set for field + * @throws SecurityException + * @throws NoSuchFieldException + * @throws IllegalArgumentException + * @throws IllegalAccessException + */ + public static void setField(Object obj, String fieldName, Object fieldValue) + throws SecurityException, NoSuchFieldException, + IllegalArgumentException, IllegalAccessException { + final Field field = obj.getClass().getDeclaredField(fieldName); + final boolean isAccessible = field.isAccessible(); + field.setAccessible(true); + field.set(obj, fieldValue); + field.setAccessible(isAccessible); + } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java index 8dde4a838c78..57f00e566af8 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java @@ -20,8 +20,7 @@ import com.intellij.util.containers.ContainerUtilRt; import com.intellij.util.text.CharArrayUtil; import gnu.trove.TObjectIntHashMap; import gnu.trove.TObjectIntProcedure; -import org.gradle.tooling.ModelBuilder; -import org.gradle.tooling.ProjectConnection; +import org.gradle.tooling.*; import org.gradle.tooling.model.DomainObjectSet; import org.gradle.tooling.model.GradleTask; import org.gradle.tooling.model.idea.*; @@ -30,6 +29,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.remote.impl.GradleLibraryNamesMixer; import org.jetbrains.plugins.gradle.settings.ClassHolder; +import org.jetbrains.plugins.gradle.settings.DistributionType; import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings; import org.jetbrains.plugins.gradle.util.GradleConstants; import org.jetbrains.plugins.gradle.util.GradleUtil; @@ -62,6 +62,9 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad throws ExternalSystemException, IllegalArgumentException, IllegalStateException { if (settings != null) { + if(settings.getDistributionType() == DistributionType.WRAPPED) { + myHelper.ensureInstalledWrapper(id, projectPath, settings, listener); + } List<ClassHolder<? extends GradleProjectResolverExtension>> extensionClasses = settings.getResolverExtensions(); if (myCachedExtensions == null || !myCachedExtensions.first.equals(extensionClasses)) { List<GradleProjectResolverExtension> extensions = ContainerUtilRt.newArrayList(); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java index 37f38ea4c8f3..669bc3a5317b 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java @@ -30,9 +30,11 @@ import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBRadioButton; import com.intellij.util.Alarm; import com.intellij.util.Consumer; +import org.gradle.util.GradleVersion; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.service.GradleInstallationManager; +import org.jetbrains.plugins.gradle.settings.DistributionType; import org.jetbrains.plugins.gradle.settings.GradleProjectSettings; import org.jetbrains.plugins.gradle.util.GradleBundle; import org.jetbrains.plugins.gradle.util.GradleConstants; @@ -68,6 +70,7 @@ public class GradleProjectSettingsControl extends AbstractExternalProjectSetting private TextFieldWithBrowseButton myGradleHomePathField; private JBRadioButton myUseWrapperButton; private JBRadioButton myUseLocalDistributionButton; + private JBRadioButton myUseBundledDistributionButton; private boolean myShowBalloonIfNecessary; private boolean myGradleHomeModifiedByUser; @@ -106,21 +109,32 @@ public class GradleProjectSettingsControl extends AbstractExternalProjectSetting myGradleHomeLabel = new JBLabel(GradleBundle.message("gradle.settings.text.home.path")); initGradleHome(); - initWrapperControls(); + initControls(); content.add(myUseWrapperButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel)); content.add(myUseLocalDistributionButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel)); + content.add(myUseBundledDistributionButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel)); content.add(myGradleHomeLabel, ExternalSystemUiUtil.getLabelConstraints(indentLevel)); content.add(myGradleHomePathField, ExternalSystemUiUtil.getFillLineConstraints(0)); } - private void initWrapperControls() { + private void initControls() { ActionListener listener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - boolean enabled = e.getSource() == myUseLocalDistributionButton; - myGradleHomePathField.setEnabled(enabled); - if (enabled) { + boolean localDistributionEnabled = e.getSource() == myUseLocalDistributionButton; + myGradleHomePathField.setEnabled(localDistributionEnabled); + if (localDistributionEnabled) { + if(myGradleHomePathField.getText().isEmpty()){ + deduceGradleHomeIfPossible(); + } else { + if(myInstallationManager.isGradleSdkHome(myGradleHomePathField.getText())){ + myGradleHomeSettingType = LocationSettingType.EXPLICIT_CORRECT; + } else { + myGradleHomeSettingType = LocationSettingType.EXPLICIT_INCORRECT; + myShowBalloonIfNecessary = true; + } + } showBalloonIfNecessary(); } else { @@ -128,12 +142,18 @@ public class GradleProjectSettingsControl extends AbstractExternalProjectSetting } } }; - myUseWrapperButton = new JBRadioButton(GradleBundle.message("gradle.settings.text.use.wrapper"), true); + myUseWrapperButton = new JBRadioButton(GradleBundle.message("gradle.settings.text.use.wrapper")); myUseWrapperButton.addActionListener(listener); myUseLocalDistributionButton = new JBRadioButton(GradleBundle.message("gradle.settings..text.use.local.distribution")); myUseLocalDistributionButton.addActionListener(listener); + + myUseBundledDistributionButton = new JBRadioButton( + GradleBundle.message("gradle.settings.text.use.bundled.distribution", GradleVersion.current().getVersion())); + myUseBundledDistributionButton.addActionListener(listener); + ButtonGroup buttonGroup = new ButtonGroup(); buttonGroup.add(myUseWrapperButton); + buttonGroup.add(myUseBundledDistributionButton); buttonGroup.add(myUseLocalDistributionButton); } @@ -195,14 +215,30 @@ public class GradleProjectSettingsControl extends AbstractExternalProjectSetting new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType, 0).run(); return GradleBundle.message("gradle.home.setting.type.explicit.incorrect", gradleHomePath); } + settings.setDistributionType(DistributionType.LOCAL); + } else if (myUseWrapperButton.isSelected()) { + settings.setDistributionType(DistributionType.WRAPPED); + } else { + settings.setDistributionType(DistributionType.BUNDLED); } - settings.setPreferLocalInstallationToWrapper(myUseLocalDistributionButton.isSelected()); + return null; } @Override protected boolean isExtraSettingModified() { - if (myUseLocalDistributionButton.isSelected() != getInitialSettings().isPreferLocalInstallationToWrapper()) { + if (myUseBundledDistributionButton.isSelected() && + getInitialSettings().getDistributionType() != DistributionType.BUNDLED) { + return true; + } + + if (myUseWrapperButton.isSelected() && + getInitialSettings().getDistributionType() != DistributionType.WRAPPED) { + return true; + } + + if (myUseLocalDistributionButton.isSelected() && + getInitialSettings().getDistributionType() != DistributionType.LOCAL) { return true; } @@ -233,35 +269,32 @@ public class GradleProjectSettingsControl extends AbstractExternalProjectSetting deduceGradleHomeIfPossible(); } else { - assert gradleHome != null; myGradleHomeSettingType = myInstallationManager.isGradleSdkHome(new File(gradleHome)) ? LocationSettingType.EXPLICIT_CORRECT : LocationSettingType.EXPLICIT_INCORRECT; myAlarm.cancelAllRequests(); - if (myGradleHomeSettingType == LocationSettingType.EXPLICIT_INCORRECT && getInitialSettings().isPreferLocalInstallationToWrapper()) { + if (myGradleHomeSettingType == LocationSettingType.EXPLICIT_INCORRECT && + getInitialSettings().getDistributionType() == DistributionType.LOCAL) { new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType, 0).run(); } } } public void updateWrapperControls(@Nullable String linkedProjectPath) { - if (linkedProjectPath != null && GradleUtil.isGradleWrapperDefined(linkedProjectPath)) { - myUseWrapperButton.setEnabled(true); - myUseWrapperButton.setText(GradleBundle.message("gradle.settings.text.use.wrapper")); - if (getInitialSettings().isPreferLocalInstallationToWrapper()) { + myUseWrapperButton.setText(GradleBundle.message("gradle.settings.text.use.wrapper")); + switch (getInitialSettings().getDistributionType()) { + case LOCAL: myGradleHomePathField.setEnabled(true); myUseLocalDistributionButton.setSelected(true); - } - else { + break; + case WRAPPED: myGradleHomePathField.setEnabled(false); myUseWrapperButton.setSelected(true); - } - } - else { - myUseWrapperButton.setText(GradleBundle.message("gradle.settings.text.use.wrapper.disabled")); - myUseWrapperButton.setEnabled(false); - myGradleHomePathField.setEnabled(true); - myUseLocalDistributionButton.setSelected(true); + break; + case BUNDLED: + myGradleHomePathField.setEnabled(false); + myUseBundledDistributionButton.setSelected(true); + break; } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java index 721140dde838..22c287ca1d36 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java @@ -114,7 +114,6 @@ public class GradleSystemSettingsControl implements ExternalSystemSettingsContro deduceServiceDirectoryIfPossible(); } else { - assert path != null; myServiceDirectoryPathField.setText(path); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java index 5fa7ca40e7af..2ff5ffbed801 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java @@ -29,6 +29,7 @@ import org.gradle.tooling.ProjectConnection; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.service.project.GradleExecutionHelper; +import org.jetbrains.plugins.gradle.settings.DistributionType; import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings; import java.io.File; @@ -50,6 +51,11 @@ public class GradleTaskManager implements ExternalSystemTaskManager<GradleExecut @Nullable final GradleExecutionSettings settings, @Nullable final String vmOptions, @NotNull final ExternalSystemTaskNotificationListener listener) throws ExternalSystemException { + + if(settings != null && settings.getDistributionType() == DistributionType.WRAPPED) { + myHelper.ensureInstalledWrapper(id, projectPath, settings, listener); + } + Function<ProjectConnection, Void> f = new Function<ProjectConnection, Void>() { @Override public Void fun(ProjectConnection connection) { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/DistributionType.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/DistributionType.java new file mode 100644 index 000000000000..3540abe23943 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/DistributionType.java @@ -0,0 +1,24 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.gradle.settings; + +/** + * @author Vladislav.Soroka + * @since 8/23/13 + */ +public enum DistributionType { + BUNDLED, WRAPPED, LOCAL +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExecutionSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExecutionSettings.java index 71f334db5c70..82cd84cdd682 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExecutionSettings.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExecutionSettings.java @@ -41,18 +41,19 @@ public class GradleExecutionSettings extends ExternalSystemExecutionSettings { @Nullable private final String myDaemonVmOptions; - private final boolean myUseWrapper; + @NotNull final DistributionType myDistributionType; + @Nullable private String wrapperPropertyFile; @Nullable private String myJavaHome; public GradleExecutionSettings(@Nullable String gradleHome, @Nullable String serviceDirectory, - boolean wrapper, + @NotNull DistributionType distributionType, @Nullable String daemonVmOptions) { myGradleHome = gradleHome; myServiceDirectory = serviceDirectory; - myUseWrapper = wrapper; + myDistributionType = distributionType; if (daemonVmOptions != null && !daemonVmOptions.contains("-Xmx")) { daemonVmOptions += String.format(" -Xmx%dm", SystemInfo.is32Bit ? 512 : 1024); } @@ -70,10 +71,6 @@ public class GradleExecutionSettings extends ExternalSystemExecutionSettings { return myServiceDirectory; } - public boolean isUseWrapper() { - return myUseWrapper; - } - @Nullable public String getJavaHome() { return myJavaHome; @@ -100,12 +97,26 @@ public class GradleExecutionSettings extends ExternalSystemExecutionSettings { return myDaemonVmOptions; } + @Nullable + public String getWrapperPropertyFile() { + return wrapperPropertyFile; + } + + public void setWrapperPropertyFile(@Nullable String wrapperPropertyFile) { + this.wrapperPropertyFile = wrapperPropertyFile; + } + + @NotNull + public DistributionType getDistributionType() { + return myDistributionType; + } + @Override public int hashCode() { int result = super.hashCode(); result = 31 * result + (myGradleHome != null ? myGradleHome.hashCode() : 0); result = 31 * result + (myServiceDirectory != null ? myServiceDirectory.hashCode() : 0); - result = 31 * result + (myUseWrapper ? 1 : 0); + result = 31 * result + myDistributionType.hashCode(); result = 31 * result + (myJavaHome != null ? myJavaHome.hashCode() : 0); result = 31 * result + (myDaemonVmOptions == null ? 0 : myDaemonVmOptions.hashCode()); return result; @@ -117,7 +128,7 @@ public class GradleExecutionSettings extends ExternalSystemExecutionSettings { GradleExecutionSettings that = (GradleExecutionSettings)o; - if (myUseWrapper != that.myUseWrapper) return false; + if (myDistributionType != that.myDistributionType) return false; if (!Comparing.equal(myDaemonVmOptions, that.myDaemonVmOptions)) return false; if (myGradleHome != null ? !myGradleHome.equals(that.myGradleHome) : that.myGradleHome != null) return false; if (myJavaHome != null ? !myJavaHome.equals(that.myJavaHome) : that.myJavaHome != null) return false; @@ -130,6 +141,6 @@ public class GradleExecutionSettings extends ExternalSystemExecutionSettings { @Override public String toString() { - return "home: " + myGradleHome + ", use wrapper: " + myUseWrapper; + return "home: " + myGradleHome + ", distributionType: " + myDistributionType; } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleProjectSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleProjectSettings.java index a254be804b50..6039e6fadc98 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleProjectSettings.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleProjectSettings.java @@ -26,8 +26,11 @@ import org.jetbrains.annotations.Nullable; public class GradleProjectSettings extends ExternalProjectSettings { @Nullable private String myGradleHome; + @NotNull private DistributionType distributionType; - private boolean myPreferLocalInstallationToWrapper; + public GradleProjectSettings() { + this.distributionType = DistributionType.BUNDLED; + } @Nullable public String getGradleHome() { @@ -38,12 +41,13 @@ public class GradleProjectSettings extends ExternalProjectSettings { myGradleHome = gradleHome; } - public boolean isPreferLocalInstallationToWrapper() { - return myPreferLocalInstallationToWrapper; + @NotNull + public DistributionType getDistributionType() { + return distributionType; } - public void setPreferLocalInstallationToWrapper(boolean preferLocalInstallationToWrapper) { - myPreferLocalInstallationToWrapper = preferLocalInstallationToWrapper; + public void setDistributionType(@NotNull DistributionType distributionType) { + this.distributionType = distributionType; } @NotNull @@ -52,7 +56,7 @@ public class GradleProjectSettings extends ExternalProjectSettings { GradleProjectSettings result = new GradleProjectSettings(); copyTo(result); result.myGradleHome = myGradleHome; - result.myPreferLocalInstallationToWrapper = myPreferLocalInstallationToWrapper; + result.distributionType = distributionType; return result; } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java index a1e530dfb264..655a05f0afbf 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java @@ -121,9 +121,8 @@ public class GradleSettings extends AbstractExternalSystemSettings<GradleSetting if (!Comparing.equal(old.getGradleHome(), current.getGradleHome())) { getPublisher().onGradleHomeChange(old.getGradleHome(), current.getGradleHome(), current.getExternalProjectPath()); } - if (old.isPreferLocalInstallationToWrapper() != current.isPreferLocalInstallationToWrapper()) { - getPublisher().onPreferLocalGradleDistributionToWrapperChange(current.isPreferLocalInstallationToWrapper(), - current.getExternalProjectPath()); + if (old.getDistributionType() != current.getDistributionType()) { + getPublisher().onGradleDistributionTypeChange(current.getDistributionType(), current.getExternalProjectPath()); } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettingsListener.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettingsListener.java index 77b3a333c39b..9b17befca9cd 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettingsListener.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettingsListener.java @@ -29,15 +29,15 @@ public interface GradleSettingsListener extends ExternalSystemSettingsListener<G void onGradleHomeChange(@Nullable String oldPath, @Nullable String newPath, @NotNull String linkedProjectPath); /** - * Is expected to be invoked when 'prefer local gradle distribution to wrapper' setting is changed (generally this + * Is expected to be invoked when 'gradle distribution type' setting is changed (generally this * switches tooling api to different gradle version). * <p/> * <b>Note:</b> this callback is executed <b>after</b> the actual config change. - * + * * @param currentValue current value * @param linkedProjectPath target linked gradle project path */ - void onPreferLocalGradleDistributionToWrapperChange(boolean currentValue, @NotNull String linkedProjectPath); + void onGradleDistributionTypeChange(DistributionType currentValue, @NotNull String linkedProjectPath); /** * Is expected to be invoked when service directory path is changed. diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java index d74aa376831c..d08cd9535062 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -144,7 +144,7 @@ public class AntTasksProvider { private final Future<Map<String, Class>> myFuture; public AntClassLoader(ArrayList<URL> urls) { - super(urls, null, false, false, true, false); + super(build().urls(urls).allowUnescaped().noPreload()); myFuture = ApplicationManager.getApplication().executeOnPooledThread(new Callable<Map<String, Class>>() { @Override public Map<String, Class> call() throws Exception { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonFramework.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonFramework.java index 5e9ccae44555..9808af8a22f6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonFramework.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonFramework.java @@ -202,18 +202,13 @@ public class GriffonFramework extends MvcFramework { @Override public VirtualFile getSdkRoot(@Nullable Module module) { - if (module == null) return null; - final VirtualFile[] classRoots = ModuleRootManager.getInstance(module).orderEntries().librariesOnly().getClassesRoots(); - for (VirtualFile file : classRoots) { - if (GriffonLibraryPresentationProvider.isGriffonCoreJar(file)) { - final VirtualFile localFile = JarFileSystem.getInstance().getVirtualFileForJar(file); - if (localFile != null) { - final VirtualFile parent = localFile.getParent(); - if (parent != null) { - return parent.getParent(); - } - } - return null; + VirtualFile coreJar = findCoreJar(module); + if (coreJar == null) return null; + + if (GriffonLibraryPresentationProvider.isGriffonCoreJar(coreJar)) { + final VirtualFile parent = coreJar.getParent(); + if (parent != null) { + return parent.getParent(); } } return null; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcFramework.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcFramework.java index 75686574f06a..a3ccb230688e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcFramework.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcFramework.java @@ -226,6 +226,20 @@ public abstract class MvcFramework { public abstract String getUserLibraryName(); + @Nullable + protected VirtualFile findCoreJar(@Nullable Module module) { + if (module == null) return null; + + JavaPsiFacade javaFacade = JavaPsiFacade.getInstance(module.getProject()); + PsiClass aClass = javaFacade.findClass(getSomeFrameworkClass(), GlobalSearchScope.moduleWithLibrariesScope(module)); + if (aClass == null) return null; + + VirtualFile virtualFile = aClass.getContainingFile().getVirtualFile(); + if (virtualFile == null || !(virtualFile.getFileSystem() instanceof JarFileSystem)) return null; + + return PathUtil.getLocalFile(virtualFile); + } + protected List<File> getImplicitClasspathRoots(@NotNull Module module) { final List<File> toExclude = new ArrayList<File>(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrInplaceVariableIntroducer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrInplaceVariableIntroducer.java index bbbd9a5c363c..2d706a6d08df 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrInplaceVariableIntroducer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrInplaceVariableIntroducer.java @@ -25,9 +25,11 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.ui.NonFocusableCheckBox; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; -import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SubtypeConstraint; +import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SupertypeConstraint; import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.refactoring.introduce.GrFinalListener; import org.jetbrains.plugins.groovy.refactoring.introduce.GrInplaceIntroducer; import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext; @@ -99,9 +101,10 @@ public class GrInplaceVariableIntroducer extends GrInplaceIntroducer { protected void addAdditionalVariables(TemplateBuilderImpl builder) { GrVariable variable = getVariable(); assert variable != null; - TypeConstraint[] constraints = {SubtypeConstraint.create(variable.getType())}; + TypeConstraint[] constraints = {SupertypeConstraint.create(variable.getType())}; ChooseTypeExpression typeExpression = new ChooseTypeExpression(constraints, variable.getManager(), true, variable.getResolveScope()); - builder.replaceElement(variable.getTypeElementGroovy(), "Variable_type", typeExpression, true, true); + PsiElement element = variable.getTypeElementGroovy() != null ? variable.getTypeElementGroovy() + : PsiUtil.findModifierInList(variable.getModifierList(), GrModifier.DEF); + builder.replaceElement(element, "Variable_type", typeExpression, true, true); } - } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java index 8c8058a309e5..ff941bec3e06 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java @@ -17,21 +17,22 @@ package org.jetbrains.plugins.groovy.refactoring.introduce.variable; import com.intellij.diagnostic.LogMessageEx; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.*; -import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.util.PsiUtilCore; import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.util.ArrayUtilRt; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; +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; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringInjection; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; @@ -72,69 +73,19 @@ public class GrIntroduceLocalVariableProcessor { preprocessOccurrences(); - boolean isExpressionFirstOccurrence = myOccurrences[0] == myExpression; - + int expressionIndex = ArrayUtilRt.find(myOccurrences, myExpression); final PsiElement[] replaced = processOccurrences(); - GrStatement anchor = getAnchor(replaced); - if (isControlStatementBranch(anchor)) { - anchor = insertBraces(replaced, anchor); - } - - GrVariable variable = insertVariableDefinition(declaration, anchor); - - if (isExpressionFirstOccurrence) { - final PsiElement expressionSkipped = PsiUtil.skipParentheses(replaced[0], true); - if (PsiUtil.isExpressionStatement(expressionSkipped) && - expressionSkipped.getParent() == variable.getParent().getParent()) { - expressionSkipped.delete(); - refreshPositionMarker(variable); - } - } RefactoringUtil.highlightAllOccurrences(myContext.getProject(), replaced, myContext.getEditor()); - return variable; - } - - private GrStatement insertBraces(PsiElement[] replaced, GrStatement anchor) { - List<SmartPsiElementPointer<PsiElement>> replacedPointers = ContainerUtil.newArrayList(); - final SmartPointerManager pointerManager = SmartPointerManager.getInstance(myContext.getProject()); - for (PsiElement element : replaced) { - replacedPointers.add(pointerManager.createSmartPsiElementPointer(element)); - } - SmartPsiElementPointer<GrStatement> anchorPointer = pointerManager.createSmartPsiElementPointer(anchor); - - final Document document = myContext.getEditor().getDocument(); - final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myContext.getProject()); - documentManager.doPostponedOperationsAndUnblockDocument(document); - final TextRange range = anchor.getTextRange(); - document.insertString(range.getEndOffset(), "}"); - document.insertString(skipSpacesBackward(document, range.getStartOffset()), "{"); - documentManager.commitDocument(document); - - for (int i = 0; i < replacedPointers.size(); i++) { - SmartPsiElementPointer<PsiElement> pointer = replacedPointers.get(i); - replaced[i] = pointer.getElement(); - } - anchor = anchorPointer.getElement(); - CodeStyleManager.getInstance(myContext.getProject()).reformat(anchor.getParent()); - return anchor; + return insertVariableDefinition(declaration, anchor, replaced[expressionIndex]); } private void refreshPositionMarker(PsiElement e) { myHandler.refreshPositionMarker(myContext.getEditor().getDocument().createRangeMarker(e.getTextRange())); } - private static int skipSpacesBackward(Document document, int offset) { - if (offset == 0) return offset; - final CharSequence sequence = document.getCharsSequence(); - while (Character.isSpaceChar(sequence.charAt(offset - 1))) { - offset--; - } - return offset; - } - private static boolean isControlStatementBranch(GrStatement statement) { return statement.getParent() instanceof GrLoopStatement && statement == ((GrLoopStatement)statement.getParent()).getBody() || statement.getParent() instanceof GrIfStatement && @@ -157,10 +108,6 @@ public class GrIntroduceLocalVariableProcessor { final GrExpression replaced = ((GrExpression)occurrence).replaceWithExpression(templateRef, true); result.add(replaced); - - if (isOriginal) { - refreshPositionMarker(replaced); - } } return PsiUtilCore.toPsiElementArray(result); @@ -198,21 +145,67 @@ public class GrIntroduceLocalVariableProcessor { } @NotNull - private GrVariable insertVariableDefinition(@NotNull GrVariableDeclaration declaration, final GrStatement anchor) throws IncorrectOperationException { + private GrVariable insertVariableDefinition(@NotNull GrVariableDeclaration declaration, @NotNull GrStatement anchor, PsiElement expression) throws IncorrectOperationException { + boolean deleteExpression = expression != null && PsiUtil.isExpressionStatement(expression) && !isSingleGStringInjectionExpr(expression); + boolean anchorEqualsExpression = anchor == expression; + + if (deleteExpression && !anchorEqualsExpression) { + expression.delete(); + } + + boolean isInsideLoop = isControlStatementBranch(anchor); + if (isInsideLoop) { + anchor = insertBraces(anchor); + } + LOG.assertTrue(myOccurrences.length > 0); + declaration = doInsertDefinition(declaration, anchor, deleteExpression, anchorEqualsExpression); + + final GrVariable variable = declaration.getVariables()[0]; + JavaCodeStyleManager.getInstance(declaration.getProject()).shortenClassReferences(declaration); + + + PsiElement markerPlace = deleteExpression ? variable : + isInsideLoop ? declaration.getParent() + : expression; + refreshPositionMarker(markerPlace); + + return variable; + } + + private GrVariableDeclaration doInsertDefinition(GrVariableDeclaration declaration, + GrStatement anchor, + boolean deleteExpression, + boolean anchorEqualsExpression) { PsiElement realContainer = anchor.getParent(); GrStatementOwner block = (GrStatementOwner)realContainer; - declaration = (GrVariableDeclaration)block.addStatementBefore(declaration, anchor); - final GrVariable variable = declaration.getVariables()[0]; - variable.setType(mySettings.getSelectedType()); + if (deleteExpression && anchorEqualsExpression) { + declaration = (GrVariableDeclaration)anchor.replace(declaration); + } + else { + declaration = (GrVariableDeclaration)block.addStatementBefore(declaration, anchor); + } + return declaration; + } - JavaCodeStyleManager.getInstance(declaration.getProject()).shortenClassReferences(declaration); - return variable; + private GrStatement insertBraces(GrStatement anchor) { + GrBlockStatement blockStatement = GroovyPsiElementFactory.getInstance(myContext.getProject()).createBlockStatement(); + + blockStatement.getBlock().addStatementBefore(anchor, null); + GrBlockStatement newBlockStatement = ((GrBlockStatement)anchor.replace(blockStatement)); + anchor = newBlockStatement.getBlock().getStatements()[0]; + return anchor; } + private static boolean isSingleGStringInjectionExpr(PsiElement expression) { + PsiElement parent = expression.getParent(); + return parent instanceof GrClosableBlock && parent.getParent() instanceof GrStringInjection; + } + + @NotNull private GrStatement getAnchor(PsiElement[] replaced) { PsiElement anchor = GrIntroduceHandlerBase.findAnchor(replaced, myContext.getScope()); if (!(anchor instanceof GrStatement)) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java index d5fb69eb7b80..5ce7a0985305 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java @@ -22,6 +22,7 @@ import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiType; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.introduce.inplace.OccurrencesChooser; +import com.intellij.refactoring.util.CanonicalTypes; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; @@ -144,6 +145,24 @@ public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase<GroovyInt @Override protected GroovyIntroduceVariableSettings getSettingsForInplace(final GrIntroduceContext context, final OccurrencesChooser.ReplaceChoice choice) { return new GroovyIntroduceVariableSettings() { + private final CanonicalTypes.Type myType; + private final String myName; + + + { + GrExpression expression = context.getExpression(); + StringPartInfo stringPart = context.getStringPart(); + GrVariable var = context.getVar(); + PsiType type = expression != null ? expression.getType() : + var != null ? var.getType() : + stringPart != null ? stringPart.getLiteral().getType() : + null; + myType = type != null ?CanonicalTypes.createTypeWrapper(type) : null; + + myName = new GrVariableNameSuggester(context, new GroovyVariableValidator(context)).suggestNames().iterator().next(); + } + + @Override public boolean isDeclareFinal() { return false; @@ -152,7 +171,7 @@ public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase<GroovyInt @Nullable @Override public String getName() { - return new GrVariableNameSuggester(context, new GroovyVariableValidator(context)).suggestNames().iterator().next(); + return myName; } @Override @@ -163,13 +182,7 @@ public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase<GroovyInt @Nullable @Override public PsiType getSelectedType() { - GrExpression expression = context.getExpression(); - StringPartInfo stringPart = context.getStringPart(); - GrVariable var = context.getVar(); - return expression != null ? expression.getType() : - var != null ? var.getType() : - stringPart != null ? stringPart.getLiteral().getType() : - null; + return myType != null ? myType.getType(context.getPlace(), context.getPlace().getManager()) : null; } }; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/template/expressions/ChooseTypeExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/template/expressions/ChooseTypeExpression.java index 57d54cc34f90..4db70097ad5c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/template/expressions/ChooseTypeExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/template/expressions/ChooseTypeExpression.java @@ -21,6 +21,7 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInsight.lookup.PsiTypeLookupItem; import com.intellij.codeInsight.template.*; +import com.intellij.codeInsight.template.impl.JavaTemplateUtil; import com.intellij.openapi.editor.Document; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; @@ -117,11 +118,23 @@ public class ChooseTypeExpression extends Expression { type = TypesUtil.unboxPrimitiveTypeWrapper(type); if (type == null) return null; - return new PsiTypeResult(type, context.getProject()) { + final PsiType finalType = type; + return new PsiTypeResult(finalType, context.getProject()) { @Override public void handleRecalc(PsiFile psiFile, Document document, int segmentStart, int segmentEnd) { - if (myItems.length <= 1) super.handleRecalc(psiFile, document, segmentStart, segmentEnd); + if (myItems.length <= 1) { + super.handleRecalc(psiFile, document, segmentStart, segmentEnd); + } + else { + JavaTemplateUtil.updateTypeBindings(getType(), psiFile, document, segmentStart, segmentEnd, true); + } } + + @Override + public String toString() { + return myItems.length == 1 ? super.toString() : finalType.getPresentableText(); + } + }; } diff --git a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/abs.test b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/abs.test index 92581cf81fb7..d19519fde385 100644 --- a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/abs.test +++ b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/abs.test @@ -1,3 +1,3 @@ <begin>0.abs()<end> ----- -def preved = 0.abs()<caret> +def preved = 0.abs()<caret>
\ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/call1.test b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/call1.test index 0886271c68b2..1c1333a80f70 100644 --- a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/call1.test +++ b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/call1.test @@ -1,3 +1,3 @@ <begin>foo 1,2,3<end> ----- -def preved = foo(1, 2, 3)<caret> +def preved = foo(1, 2, 3)<caret>
\ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/call2.test b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/call2.test index c96db207a109..2d2c232172c9 100644 --- a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/call2.test +++ b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/call2.test @@ -4,9 +4,8 @@ foo 1,2,3 foo 1,2,3 foo 1,2,3 ----- -def preved = foo(1, 2, 3) +def preved = foo(1, 2, 3)<caret> preved preved -preved<caret> preved preved
\ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/charArray.test b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/charArray.test index 43789fa9e26c..04861f676d47 100644 --- a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/charArray.test +++ b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/charArray.test @@ -1,3 +1,3 @@ <begin>"abc".toCharArray()<end> ----- -char[] preved = "abc".toCharArray()<caret> +char[] preved = "abc".toCharArray()<caret>
\ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/fqn.test b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/fqn.test index 9dcc4d73f3f9..7bbe8d07b0da 100644 --- a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/fqn.test +++ b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/fqn.test @@ -4,4 +4,4 @@ import p.Foo ----- import p.Foo -def preved = Foo.foo()<caret> +def preved = Foo.foo()<caret>
\ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop5.test b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop5.test index ddf85d24dc33..960a392a2a16 100644 --- a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop5.test +++ b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop5.test @@ -3,5 +3,5 @@ foo <begin>foo<end> ----- while (true) { def preved = foo - foo preved<caret> -}
\ No newline at end of file + foo preved +}<caret>
\ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop6.test b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop6.test index 26deb67c231d..9bef9bf595cd 100644 --- a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop6.test +++ b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop6.test @@ -3,5 +3,5 @@ foo <all>foo<end> ----- while (true) { def preved = foo - preved preved<caret> -}
\ No newline at end of file + preved preved +}<caret>
\ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop8.test b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop8.test index 004246285d53..fb8cb92bdd5e 100644 --- a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop8.test +++ b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop8.test @@ -2,5 +2,5 @@ while (true) return <begin>1<end> ----- while (true) { def preved = 1 - return preved<caret> -}
\ No newline at end of file + return preved +}<caret>
\ No newline at end of file diff --git a/plugins/groovy/testdata/intentions/introduceLocalVariable/Constructor-after.groovy b/plugins/groovy/testdata/intentions/introduceLocalVariable/Constructor-after.groovy index d5925e60d0d6..8bd13e4b07d3 100644 --- a/plugins/groovy/testdata/intentions/introduceLocalVariable/Constructor-after.groovy +++ b/plugins/groovy/testdata/intentions/introduceLocalVariable/Constructor-after.groovy @@ -1 +1 @@ -def varName = new Hoge() +def varName = new Hoge()
\ No newline at end of file diff --git a/plugins/groovy/testdata/intentions/introduceLocalVariable/MethodCall1-after.groovy b/plugins/groovy/testdata/intentions/introduceLocalVariable/MethodCall1-after.groovy index 011acc5fa43d..b72bc1c8158f 100644 --- a/plugins/groovy/testdata/intentions/introduceLocalVariable/MethodCall1-after.groovy +++ b/plugins/groovy/testdata/intentions/introduceLocalVariable/MethodCall1-after.groovy @@ -1 +1 @@ -def varName = Calendar.getInstance() +def varName = Calendar.getInstance()
\ No newline at end of file diff --git a/plugins/groovy/testdata/intentions/introduceLocalVariable/MethodCall2-after.groovy b/plugins/groovy/testdata/intentions/introduceLocalVariable/MethodCall2-after.groovy index 7cded4fd4b7b..bd4e3e290fa7 100644 --- a/plugins/groovy/testdata/intentions/introduceLocalVariable/MethodCall2-after.groovy +++ b/plugins/groovy/testdata/intentions/introduceLocalVariable/MethodCall2-after.groovy @@ -1 +1 @@ -def varName = 'fuga'.length() +def varName = 'fuga'.length()
\ No newline at end of file diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgExecutableValidator.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgExecutableValidator.java index 2850867d5784..5a5da6febf10 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgExecutableValidator.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgExecutableValidator.java @@ -42,6 +42,6 @@ public class HgExecutableValidator extends ExecutableValidator { @Override public boolean isExecutableValid(@NotNull String executable) { - return HgUtil.isValid(executable); + return HgUtil.isExecutableValid(executable); } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.java index e9abbc4d4e78..3e301d972058 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.java @@ -71,7 +71,7 @@ public class HgConfigurationProjectPanel { public void validate() throws ConfigurationException { String hgExecutable; hgExecutable = getCurrentPath(); - if (!HgUtil.isValid(hgExecutable)) { + if (!HgUtil.isExecutableValid(hgExecutable)) { throw new ConfigurationException( HgVcsMessages.message("hg4idea.configuration.executable.error", hgExecutable) ); diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgSetExecutablePathPanel.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgSetExecutablePathPanel.java index a7f7eea6f015..6ed3936dcacd 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgSetExecutablePathPanel.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgSetExecutablePathPanel.java @@ -24,7 +24,7 @@ class HgSetExecutablePathPanel extends TextFieldWithBrowseButton { FileChooserDescriptor descriptor = new FileChooserDescriptor(true, false, false, false, false, false) { public void validateSelectedFiles(VirtualFile[] files) throws Exception { String path = files[0].getPath(); - if (!HgUtil.isValid(path)) { + if (!HgUtil.isExecutableValid(path)) { throw new ConfigurationException(HgVcsMessages.message("hg4idea.configuration.executable.error", path)); } for (ActionListener okListener : myOkListeners) { diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java index 6ac0bc7ad6e0..ac5e5a4e165d 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java @@ -12,9 +12,6 @@ // limitations under the License. package org.zmlx.hg4idea.util; -import com.intellij.execution.configurations.GeneralCommandLine; -import com.intellij.execution.process.CapturingProcessHandler; -import com.intellij.execution.process.ProcessOutput; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; @@ -48,6 +45,9 @@ import org.zmlx.hg4idea.*; import org.zmlx.hg4idea.command.HgRemoveCommand; import org.zmlx.hg4idea.command.HgStatusCommand; import org.zmlx.hg4idea.command.HgWorkingCopyRevisionsCommand; +import org.zmlx.hg4idea.execution.HgCommandResult; +import org.zmlx.hg4idea.execution.ShellCommand; +import org.zmlx.hg4idea.execution.ShellCommandException; import org.zmlx.hg4idea.provider.HgChangeProvider; import org.zmlx.hg4idea.repo.HgRepository; import org.zmlx.hg4idea.repo.HgRepositoryManager; @@ -593,22 +593,29 @@ public abstract class HgUtil { return hgRepository.getRepositoryConfig().getPaths(); } - public static boolean isValid(@Nullable String executable) { + public static boolean isExecutableValid(@Nullable String executable) { try { if (StringUtil.isEmptyOrSpaces(executable)) { return false; } - GeneralCommandLine commandLine = new GeneralCommandLine(); - //noinspection ConstantConditions - commandLine.setExePath(executable); - commandLine.addParameter("--version"); - commandLine.addParameter("-q"); - CapturingProcessHandler handler = new CapturingProcessHandler(commandLine.createProcess(), CharsetToolkit.getDefaultSystemCharset()); - ProcessOutput result = handler.runProcess(30 * 1000); - return !result.isTimeout() && result.getStderr().isEmpty(); + HgCommandResult result = getVersionOutput(executable); + return result.getRawError().isEmpty(); } catch (Throwable e) { + LOG.info("Error during hg executable validation: ", e); return false; } } + + @NotNull + public static HgCommandResult getVersionOutput(@NotNull String executable) throws ShellCommandException, InterruptedException { + String hgExecutable = executable.trim(); + ShellCommand shellCommand = new ShellCommand(false); + List<String> cmdArgs = new ArrayList<String>(); + cmdArgs.add(hgExecutable); + cmdArgs.add("version"); + cmdArgs.add("-q"); + return shellCommand + .execute(cmdArgs, null, CharsetToolkit.getDefaultSystemCharset()); + } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java index 849305a49105..e613ac7cde50 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java @@ -21,13 +21,9 @@ import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.execution.HgCommandResult; -import org.zmlx.hg4idea.execution.ShellCommand; import org.zmlx.hg4idea.execution.ShellCommandException; -import java.nio.charset.Charset; import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -46,10 +42,10 @@ public final class HgVersion implements Comparable<HgVersion> { * The minimal supported version */ public static final HgVersion MIN = new HgVersion(1, 9, 1); - public static final HgVersion AMENDSUPPORTED = new HgVersion(2, 2, 0); + public static final HgVersion AMEND_SUPPORTED = new HgVersion(2, 2, 0); /** - * Special version with a special Type which indicates, that Hg version information is unavailable. + * Special version which indicates, that Hg version information is unavailable. */ public static final HgVersion NULL = new HgVersion(0, 0, 0); @@ -57,13 +53,10 @@ public final class HgVersion implements Comparable<HgVersion> { private final int myMiddle; private final int myMinor; - private final int myHashCode; - public HgVersion(int major, int middle, int minor) { myMajor = major; myMiddle = middle; myMinor = minor; - myHashCode = Objects.hashCode(myMajor, myMiddle, myMinor); } /** @@ -100,14 +93,7 @@ public final class HgVersion implements Comparable<HgVersion> { @NotNull public static HgVersion identifyVersion(@NotNull String executable) throws ShellCommandException, InterruptedException, ParseException { - String hgExecutable = executable.trim(); - ShellCommand shellCommand = new ShellCommand(false); - List<String> cmdArgs = new ArrayList<String>(); - cmdArgs.add(hgExecutable); - cmdArgs.add("version"); - cmdArgs.add("-q"); - HgCommandResult versionResult = shellCommand - .execute(cmdArgs, null, Charset.defaultCharset()); + HgCommandResult versionResult = HgUtil.getVersionOutput(executable); return parseVersion(versionResult.getRawOutput()); } @@ -119,33 +105,24 @@ public final class HgVersion implements Comparable<HgVersion> { } public boolean isAmendSupported() { - return !isNull() && compareTo(AMENDSUPPORTED) >= 0; + return !isNull() && compareTo(AMEND_SUPPORTED) >= 0; } /** * Note: this class has a natural ordering that is inconsistent with equals. - * Two HgVersions are equal if their number versions are equal and if their types are equal. - * Types are considered equal also if one of them is undefined. Otherwise they are compared. + * Two HgVersions are equal if their number versions are equal. */ @Override public boolean equals(final Object obj) { if (!(obj instanceof HgVersion)) { return false; } - HgVersion other = (HgVersion)obj; - if (compareTo(other) != 0) { - return false; - } - return true; + return compareTo((HgVersion)obj) == 0; } - /** - * Hashcode is computed from numbered components of the version. Thus HgVersions with the same numbered components will be compared - * by equals, and there the type will be taken into consideration). - */ @Override public int hashCode() { - return myHashCode; + return Objects.hashCode(myMajor, myMiddle, myMinor); } /** @@ -156,9 +133,6 @@ public final class HgVersion implements Comparable<HgVersion> { * {@link HgVersion#NULL} is less than any other not-NULL version. */ public int compareTo(@NotNull HgVersion o) { - if (o.isNull()) { - return isNull() ? 0 : 1; - } int d = myMajor - o.myMajor; if (d != 0) { return d; diff --git a/plugins/hg4idea/testSrc/hg4idea/test/version/HgVersionTest.java b/plugins/hg4idea/testSrc/hg4idea/test/version/HgVersionTest.java index a28f3b3cfa49..86bc7a88fc7c 100644 --- a/plugins/hg4idea/testSrc/hg4idea/test/version/HgVersionTest.java +++ b/plugins/hg4idea/testSrc/hg4idea/test/version/HgVersionTest.java @@ -70,7 +70,7 @@ public class HgVersionTest extends HgPlatformTest { assertEquals(middle, expected.middle); assertEquals(minor, expected.minor); HgVersion versionFromTest = new HgVersion(expected.major, expected.middle, expected.minor); - assertEquals(versionFromTest, actual); //test equals meth + assertEquals(versionFromTest, actual); //test equals method } private static class TestHgVersion { diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java index 0b82c99e9241..9c3fe6914a73 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java @@ -80,7 +80,7 @@ public class JavaFxInjectPageLanguageIntention extends PsiElementBaseIntentionAc } } - return new UrlClassLoader(urls, null); + return UrlClassLoader.build().urls(urls).get(); } @Override diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java index 41d10e4a9c75..60d7a433d421 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java @@ -101,13 +101,13 @@ public class JavaFxPropertyAttributeDescriptor extends BasicXmlAttributeDescript } @Override - protected PsiElement getEnumeratedValueDeclaration(XmlAttributeValue attributeValue, String value) { + public PsiElement getEnumeratedValueDeclaration(XmlElement xmlElement, String value) { final PsiClass aClass = getEnum(); if (aClass != null) { final PsiField fieldByName = aClass.findFieldByName(value, false); return fieldByName != null ? fieldByName : aClass.findFieldByName(value.toUpperCase(), false); } - return attributeValue; + return xmlElement; } @Nullable diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExternalParameters.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExternalParameters.java index ad92707e8f01..2aa35156a91d 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExternalParameters.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExternalParameters.java @@ -144,7 +144,7 @@ public class MavenExternalParameters { params.getClassPath().add(path); } - params.setEnv(Collections.unmodifiableMap(runnerSettings.getEnvironmentProperties())); + params.setEnv(new HashMap<String, String>(runnerSettings.getEnvironmentProperties())); params.setPassParentEnvs(runnerSettings.isPassParentEnv()); params.setMainClass(MAVEN_LAUNCHER_CLASS); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java index 71243eb945ad..defe2bf99d6c 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java @@ -28,12 +28,13 @@ public class MavenModelPropertiesPatcher { Map<String, Map<String, List<MavenPluginDescriptor>>> groupMap = map.get(plugin.getArtifactId()); if (groupMap != null) { Map<String, List<MavenPluginDescriptor>> goalsMap = groupMap.get(plugin.getGroupId()); + if (goalsMap != null) { + patch(modelProperties, goalsMap.get(null), null, plugin.getConfigurationElement(), plugin); - patch(modelProperties, goalsMap.get(null), null, plugin.getConfigurationElement(), plugin); - - for (MavenPlugin.Execution execution : plugin.getExecutions()) { - for (String goal : execution.getGoals()) { - patch(modelProperties, goalsMap.get(goal), goal, execution.getConfigurationElement(), plugin); + for (MavenPlugin.Execution execution : plugin.getExecutions()) { + for (String goal : execution.getGoals()) { + patch(modelProperties, goalsMap.get(goal), goal, execution.getConfigurationElement(), plugin); + } } } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java index 7177d4425179..f3ed0f92b411 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java @@ -71,6 +71,7 @@ public class GenericRepository extends BaseRepositoryImpl { private List<TemplateVariable> myTemplateVariables = new ArrayList<TemplateVariable>(); private String mySubtypeName; + private boolean myDownloadTasksInSeparateRequests; /** * Serialization constructor @@ -100,8 +101,9 @@ public class GenericRepository extends BaseRepositoryImpl { myResponseType = other.getResponseType(); myTemplateVariables = other.getTemplateVariables(); + mySubtypeName = other.getSubtypeName(); + myDownloadTasksInSeparateRequests = other.getDownloadTasksInSeparateRequests(); myResponseHandlersMap = new EnumMap<ResponseType, ResponseHandler>(ResponseType.class); - mySubtypeName = other.mySubtypeName; for (Map.Entry<ResponseType, ResponseHandler> e : other.myResponseHandlersMap.entrySet()) { ResponseHandler handler = e.getValue().clone(); handler.setRepository(this); @@ -113,6 +115,7 @@ public class GenericRepository extends BaseRepositoryImpl { myLoginURL = ""; myTasksListUrl = ""; mySingleTaskUrl = ""; + myDownloadTasksInSeparateRequests = false; myLoginMethodType = HTTPMethod.GET; myTasksListMethodType = HTTPMethod.GET; mySingleTaskMethodType = HTTPMethod.GET; @@ -144,6 +147,7 @@ public class GenericRepository extends BaseRepositoryImpl { if (!Comparing.equal(getResponseType(), that.getResponseType())) return false; if (!Comparing.equal(getTemplateVariables(), that.getTemplateVariables())) return false; if (!Comparing.equal(getResponseHandlers(), that.getResponseHandlers())) return false; + if (!Comparing.equal(getDownloadTasksInSeparateRequests(), that.getDownloadTasksInSeparateRequests())) return false; return true; } @@ -160,6 +164,9 @@ public class GenericRepository extends BaseRepositoryImpl { @Override public Task[] getIssues(@Nullable final String query, final int max, final long since) throws Exception { + if (StringUtil.isEmpty(myTasksListUrl)) { + throw new Exception("'Task list URL' configuration parameter is mandatory"); + } if (!isLoginAnonymously() && !isUseHttpAuthentication()) { executeMethod(getLoginMethod()); } @@ -168,8 +175,11 @@ public class GenericRepository extends BaseRepositoryImpl { new TemplateVariable("since", since)); String requestUrl = GenericRepositoryUtil.substituteTemplateVariables(getTasksListUrl(), variables); String responseBody = executeMethod(getHttpMethod(requestUrl, myTasksListMethodType)); - Task[] tasks = getActiveResponseHandler().parseIssues(responseBody); - if (!StringUtil.isEmpty(mySingleTaskUrl) && !(myResponseType == ResponseType.TEXT)) { + Task[] tasks = getActiveResponseHandler().parseIssues(responseBody, max); + if (myResponseType == ResponseType.TEXT) { + return tasks; + } + if (StringUtil.isNotEmpty(mySingleTaskUrl) && myDownloadTasksInSeparateRequests) { for (int i = 0; i < tasks.length; i++) { tasks[i] = findTask(tasks[i].getId()); } @@ -380,4 +390,12 @@ public class GenericRepository extends BaseRepositoryImpl { public void setSubtypeName(String subtypeName) { mySubtypeName = subtypeName; } + + public boolean getDownloadTasksInSeparateRequests() { + return myDownloadTasksInSeparateRequests; + } + + public void setDownloadTasksInSeparateRequests(boolean downloadTasksInSeparateRequests) { + myDownloadTasksInSeparateRequests = downloadTasksInSeparateRequests; + } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.form b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.form index 0e8695752594..6922f2aa280e 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.form +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.form @@ -3,7 +3,7 @@ <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="6" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="8"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <xy x="20" y="20" width="500" height="438"/> + <xy x="20" y="20" width="514" height="438"/> </constraints> <properties/> <border type="none"/> @@ -16,7 +16,7 @@ <text value="Response Type:"/> </properties> </component> - <grid id="d68b9" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <grid id="d68b9" layout-manager="GridLayoutManager" row-count="1" column-count="6" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> <grid row="3" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> @@ -44,13 +44,6 @@ <text value="&Text"/> </properties> </component> - <hspacer id="cebcb"> - <constraints> - <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"> - <preferred-size width="14" height="44"/> - </grid> - </constraints> - </hspacer> <component id="71bfc" class="javax.swing.JRadioButton" binding="myJsonRadioButton"> <constraints> <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"> @@ -61,6 +54,26 @@ <text value="JS&ON"/> </properties> </component> + <component id="b8210" class="javax.swing.JLabel"> + <constraints> + <grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <horizontalTextPosition value="4"/> + <text value="Each task in separate request:"/> + </properties> + </component> + <component id="69199" class="com.intellij.ui.components.JBCheckBox" binding="myDownloadTasksInSeparateRequests"> + <constraints> + <grid row="0" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties/> + </component> + <hspacer id="b7318"> + <constraints> + <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/> + </constraints> + </hspacer> </children> </grid> <grid id="2e934" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java index 0a6b9a1d1d98..6ddb8da103b5 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java @@ -1,5 +1,6 @@ package com.intellij.tasks.generic; +import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.util.Condition; @@ -7,12 +8,14 @@ import com.intellij.tasks.TaskManager; import com.intellij.tasks.config.BaseRepositoryEditor; import com.intellij.ui.EditorTextField; import com.intellij.ui.TextFieldWithAutoCompletion; +import com.intellij.ui.components.JBCheckBox; import com.intellij.ui.components.JBLabel; import com.intellij.util.Consumer; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.net.HTTPMethod; import com.intellij.util.ui.FormBuilder; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -26,6 +29,7 @@ import java.util.Map; import static com.intellij.tasks.generic.GenericRepositoryUtil.concat; import static com.intellij.tasks.generic.GenericRepositoryUtil.createPlaceholdersList; import static com.intellij.tasks.generic.GenericRepositoryUtil.prettifyVariableName; +import static com.intellij.ui.TextFieldWithAutoCompletion.StringsCompletionProvider; /** * @author Evgeny.Zakrevsky @@ -49,6 +53,7 @@ public class GenericRepositoryEditor<T extends GenericRepository> extends BaseRe private JButton myResetToDefaultsButton; private JPanel myCardPanel; private JBLabel mySingleTaskURLLabel; + private JBCheckBox myDownloadTasksInSeparateRequests; private Map<JTextField, TemplateVariable> myField2Variable; private Map<JRadioButton, ResponseType> myRadio2ResponseType; @@ -100,6 +105,7 @@ public class GenericRepositoryEditor<T extends GenericRepository> extends BaseRe installListener(myLoginURLText); installListener(myTasksListURLText); installListener(mySingleTaskURLText); + installListener(myDownloadTasksInSeparateRequests); myTabbedPane.addTab("Server configuration", myPanel); // Put appropriate configuration components on the card panel @@ -147,7 +153,7 @@ public class GenericRepositoryEditor<T extends GenericRepository> extends BaseRe @Override public void actionPerformed(final ActionEvent e) { myRepository.resetToDefaults(); - // XXX: Why clone() here? + // TODO: look closely reset(myRepository.clone()); } }); @@ -156,6 +162,7 @@ public class GenericRepositoryEditor<T extends GenericRepository> extends BaseRe selectCardByResponseType(); loginUrlEnablingChanged(); singleTaskUrlEnablingChanged(); + myDownloadTasksInSeparateRequests.setSelected(myRepository.getDownloadTasksInSeparateRequests()); } private void singleTaskUrlEnablingChanged() { @@ -202,6 +209,7 @@ public class GenericRepositoryEditor<T extends GenericRepository> extends BaseRe selectRadioButtonByResponseType(); selectCardByResponseType(); loginUrlEnablingChanged(); + myDownloadTasksInSeparateRequests.setSelected(myRepository.getDownloadTasksInSeparateRequests()); } private void selectRadioButtonByResponseType() { @@ -227,6 +235,7 @@ public class GenericRepositoryEditor<T extends GenericRepository> extends BaseRe myRepository.setTasksListMethodType(HTTPMethod.valueOf((String)myTasksListMethodTypeComboBox.getSelectedItem())); myRepository.setSingleTaskMethodType(HTTPMethod.valueOf((String)mySingleTaskMethodComboBox.getSelectedItem())); + myRepository.setDownloadTasksInSeparateRequests(myDownloadTasksInSeparateRequests.isSelected()); for (Map.Entry<JTextField, TemplateVariable> entry : myField2Variable.entrySet()) { TemplateVariable variable = entry.getValue(); JTextField field = entry.getKey(); @@ -243,14 +252,24 @@ public class GenericRepositoryEditor<T extends GenericRepository> extends BaseRe private void createUIComponents() { List<String> placeholders = createPlaceholdersList(myRepository); myLoginURLText = createTextFieldWithCompletion(myRepository.getLoginUrl(), placeholders); - myTasksListURLText = createTextFieldWithCompletion(myRepository.getTasksListUrl(), - concat(placeholders, "{max}", "{since}")); - mySingleTaskURLText = createTextFieldWithCompletion(myRepository.getSingleTaskUrl(), - concat(placeholders, "{id}")); + myTasksListURLText = createTextFieldWithCompletion(myRepository.getTasksListUrl(), concat(placeholders, "{max}", "{since}")); + mySingleTaskURLText = createTextFieldWithCompletion(myRepository.getSingleTaskUrl(), concat(placeholders, "{id}")); } - private TextFieldWithAutoCompletion<String> createTextFieldWithCompletion(String text, List<String> variants) { - return TextFieldWithAutoCompletion.create(myProject, variants, true, text); + private TextFieldWithAutoCompletion<String> createTextFieldWithCompletion(String text, final List<String> variants) { + final StringsCompletionProvider provider = new StringsCompletionProvider(variants, null) { + @Nullable + @Override + public String getPrefix(@NotNull CompletionParameters parameters) { + final String text = parameters.getOriginalFile().getText(); + final int i = text.lastIndexOf('{', parameters.getOffset() - 1); + if (i < 0) { + return ""; + } + return text.substring(i, parameters.getOffset()); + } + }; + return new TextFieldWithAutoCompletion<String>(myProject, provider, true, text); } @Override diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryUtil.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryUtil.java index b90bfb839fcf..ce1fa3ec69dc 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryUtil.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryUtil.java @@ -7,12 +7,10 @@ import com.intellij.util.containers.HashMap; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.methods.PostMethod; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.*; +import java.util.Collection; +import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -21,9 +19,6 @@ import java.util.regex.Pattern; */ public class GenericRepositoryUtil { private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("\\{(\\w[-\\w]*)\\}"); - private static SimpleDateFormat ISO8601_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - private static Pattern ISO8601_DATE_PATTERN = Pattern.compile( - "(\\d{4}-\\d{2}-\\d{2})[ T](\\d{2}:\\d{2}:\\d{2})(.\\d{3,})?([+-]\\d{2}:\\d{2}|[+-]\\d{4}|[+-]\\d{2}|Z)"); public static HttpMethod getPostMethodFromURL(final String requestUrl) { int n = requestUrl.indexOf('?'); @@ -72,38 +67,6 @@ public class GenericRepositoryUtil { }); } - @Nullable - public static Date parseISO8601Date(@NotNull String s) { - // SimpleDateFormat prior JDK7 doesn't support 'X' specifier for ISO 8601 timezone format. - // Because some bug trackers and task servers e.g. send dates ending with 'Z' (that stands for UTC), - // dates should be preprocessed before parsing. - Matcher m = ISO8601_DATE_PATTERN.matcher(s); - if (!m.matches()) { - return null; - } - String datePart = m.group(1); - String timePart = m.group(2); - String milliseconds = m.group(3); - milliseconds = milliseconds == null? "000" : milliseconds.substring(1, 4); - String timezone = m.group(4); - if (timezone.equals("Z")) { - timezone = "+0000"; - } else if (timezone.length() == 3) { - // [+-]HH - timezone += "00"; - } else if (timezone.length() == 6) { - // [+-]HH:MM - timezone = timezone.substring(0, 3) + timezone.substring(4, 6); - } - String canonicalForm = String.format("%sT%s.%s%s", datePart, timePart, milliseconds, timezone); - try { - return ISO8601_DATE_FORMAT.parse(canonicalForm); - } - catch (ParseException e) { - return null; - } - } - public static String prettifyVariableName(String variableName) { String prettyName = variableName.replace('_', ' '); return StringUtil.capitalizeWords(prettyName, true); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/HighlightedSelectorsTable.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/HighlightedSelectorsTable.java index 48d7b1bba651..ab65c32fa823 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/HighlightedSelectorsTable.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/HighlightedSelectorsTable.java @@ -15,19 +15,18 @@ */ package com.intellij.tasks.generic; -import com.intellij.lang.Language; import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.project.Project; -import com.intellij.ui.LanguageTextField; +import com.intellij.ui.EditorTextField; import com.intellij.ui.table.TableView; -import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.AbstractTableCellEditor; import com.intellij.util.ui.ColumnInfo; import com.intellij.util.ui.ListTableModel; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import java.awt.*; import java.util.List; @@ -35,14 +34,9 @@ import java.util.List; class HighlightedSelectorsTable extends TableView<Selector> { - private final FileType myValueFileType; - private final Project myProject; - - public HighlightedSelectorsTable(@NotNull FileType valueFileType, @NotNull Project project) { - this(valueFileType, project, ContainerUtil.<Selector>emptyList()); - } - - public HighlightedSelectorsTable(@NotNull final FileType valueFileType, @NotNull final Project project, @NotNull final List<Selector> selectors) { + public HighlightedSelectorsTable(@NotNull final FileType valueFileType, + @NotNull final Project project, + @NotNull final List<Selector> selectors) { super(new ListTableModel<Selector>(new ColumnInfo[]{ new ColumnInfo<Selector, String>("Name") { @Nullable @@ -52,6 +46,7 @@ class HighlightedSelectorsTable extends TableView<Selector> { } }, new ColumnInfo<Selector, String>("Path") { + @Nullable @Override public String valueOf(Selector selector) { @@ -71,29 +66,40 @@ class HighlightedSelectorsTable extends TableView<Selector> { @Nullable @Override public TableCellRenderer getRenderer(Selector selector) { - return new LanguageTextFieldRenderer(((LanguageFileType)valueFileType).getLanguage(), project); + return new EditorTableCellViewer(valueFileType, project); + } + + @Nullable + @Override + public TableCellEditor getEditor(Selector o) { + return new EditorTableCellViewer(valueFileType, project); } } }, selectors, 0)); - myValueFileType = valueFileType; - myProject = project; - } - public List<Selector> getSelectors() { - return getItems(); } - private static class LanguageTextFieldRenderer implements TableCellRenderer { - private final Project myProject; - private final Language myLanguage; + private static class EditorTableCellViewer extends AbstractTableCellEditor implements TableCellRenderer { + private final EditorTextField myEditorField; + + private EditorTableCellViewer(FileType fileType, Project project) { + myEditorField = new EditorTextField("", project, fileType); + } - private LanguageTextFieldRenderer(Language language, Project project) { - myProject = project; - myLanguage = language; + @Override + public Object getCellEditorValue() { + return myEditorField.getText(); + } + + @Override + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + myEditorField.setText((String)value); + return myEditorField; } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - return new LanguageTextField(myLanguage, myProject, (String)value); + myEditorField.setText((String)value); + return myEditorField; } } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java index e2f1ea8ce00f..cc80ed29e5ba 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java @@ -4,16 +4,15 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.PlainTextFileType; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.tasks.Task; +import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.HashMap; import com.intellij.util.xmlb.annotations.Tag; import com.jayway.jsonpath.InvalidPathException; import com.jayway.jsonpath.JsonPath; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.Map; @@ -32,6 +31,8 @@ public final class JsonPathResponseHandler extends SelectorBasedResponseHandler new Pair<Class<?>, String>(Boolean.class, "JSON boolean") ); + private final Map<String, JsonPath> myCompiledCache = new HashMap<String, JsonPath>(); + /** * Serialization constructor */ @@ -48,111 +49,95 @@ public final class JsonPathResponseHandler extends SelectorBasedResponseHandler return PlainTextFileType.INSTANCE; } - @SuppressWarnings("unchecked") - @NotNull - @Override - public Task[] doParseIssues(String response) throws Exception { - Object tasksMatch = JsonPath.read(response, getSelectorPath("tasks")); - if (!(tasksMatch instanceof List)) { - throw new Exception("Selector 'task' should match array of tasks. Got " + tasksMatch.toString() + " instead"); - } - List<Object> tasks = (List<Object>)tasksMatch; - List<GenericTask> result = new ArrayList<GenericTask>(tasks.size()); - for (Object rawTask : tasks) { - String taskText = rawTask.toString(); - String id = extractId(taskText, getSelector("id")); - String summary = extractString(taskText, getSelector("summary")); - assert summary != null; - GenericTask task = new GenericTask(id, summary, myRepository); - task.setDescription(extractString(response, getSelector("description"))); - task.setIssueUrl(extractString(response, getSelector("issueUrl"))); - Boolean closed = extractBoolean(response, getSelector("closed")); - if (closed != null) { - task.setClosed(closed); - } - task.setUpdated(extractDate(response, getSelector("updated"))); - task.setCreated(extractDate(response, getSelector("created"))); - result.add(task); - } - return result.toArray(new Task[result.size()]); - } - @Nullable - @Override - public Task doParseIssue(String response) throws Exception { - String id = extractId(response, getSelector("singleTask-id")); - String summary = extractString(response, getSelector("singleTask-summary")); - GenericTask task = new GenericTask(id, summary, myRepository); - task.setDescription(extractString(response, getSelector("singleTask-description"))); - task.setIssueUrl(extractString(response, getSelector("singleTask-issueUrl"))); - Boolean closed = extractBoolean(response, getSelector("singleTask-closed")); - if (closed != null) { - task.setClosed(closed); - } - task.setUpdated(extractDate(response, getSelector("singleTask-updated"))); - task.setCreated(extractDate(response, getSelector("singleTask-created"))); - return task; - } - - @SuppressWarnings({"unchecked", "MethodMayBeStatic"}) - @Nullable - private <T> T extractValueAndCheckType(String source, Selector selector, Class<T> cls) throws Exception { - if (selector == null || StringUtil.isEmpty(selector.getPath())) { + private Object extractRawValue(@NotNull Selector selector, @NotNull String source) throws Exception { + if (StringUtil.isEmpty(selector.getPath())) { return null; } + JsonPath jsonPath = lazyCompile(selector.getPath()); Object value; try { - value = JsonPath.read(source, selector.getPath()); + value = jsonPath.read(source); } catch (InvalidPathException e) { - // NOTE: could be thrown when selector is actually invalid or just not matched - throw new Exception(String.format("JsonPath expression '%s' is malformed or didn't match", selector.getPath()), e); + throw new Exception(String.format("JsonPath expression '%s' doesn't match", selector.getPath()), e); } if (value == null) { return null; } - if (!(cls.isInstance(value))) { - throw new Exception( - String.format("Selector '%s' should match %s. Got '%s' instead", selector.getName(), JSON_TYPES.get(cls), value.toString())); - } - return (T)value; + return value; } - @SuppressWarnings("MethodMayBeStatic") @Nullable - private String extractId(String task, Selector idSelector) throws Exception { - Object rawId; - try { - rawId = JsonPath.read(task, idSelector.getPath()); - } - catch (InvalidPathException e) { - throw new Exception(String.format("JsonPath expression '%s' is malformed or didn't match", idSelector.getPath()), e); + private <T> T extractValueAndCheckType(@NotNull Selector selector, @NotNull String source, Class<T> cls) throws Exception { + final Object value = extractRawValue(selector, source); + if (value == null) { + return null; } - if (!(rawId instanceof String) && !(rawId instanceof Long)) { + if (!(cls.isInstance(value))) { throw new Exception( - String.format("Selector 'id' should match either JSON string or JSON number value. Got '%s' instead", rawId.toString())); + String.format("JsonPath expression '%s' should match %s. Got '%s' instead", + selector.getPath(), JSON_TYPES.get(cls), value)); + } + @SuppressWarnings("unchecked") + T casted = (T)value; + return casted; + } + + @NotNull + @Override + protected List<Object> selectTasksList(@NotNull String response, int max) throws Exception { + @SuppressWarnings("unchecked") + List<Object> list = (List<Object>)extractValueAndCheckType(getSelector(TASKS), response, List.class); + if (list == null) { + return ContainerUtil.emptyList(); } - return String.valueOf(rawId); + return ContainerUtil.map2List(list, new Function<Object, Object>() { + @Override + public Object fun(Object o) { + return o.toString(); + } + }).subList(0, Math.min(list.size(), max)); } - private String extractString(String source, Selector selector) throws Exception { - return extractValueAndCheckType(source, selector, String.class); + @Nullable + @Override + protected String selectString(@NotNull Selector selector, @NotNull Object context) throws Exception { + //return extractValueAndCheckType((String)context, selector, String.class); + final Object value = extractRawValue(selector, (String)context); + if (value == null) { + return null; + } + if (value instanceof String || value instanceof Long || value instanceof Boolean) { + return value.toString(); + } + throw new Exception(String.format("JsonPath expression '%s' should match string value. Got '%s' instead", + selector.getPath(), value)); } - private Boolean extractBoolean(String source, Selector selector) throws Exception { - return extractValueAndCheckType(source, selector, Boolean.class); + @Nullable + @Override + protected Boolean selectBoolean(@NotNull Selector selector, @NotNull Object context) throws Exception { + return extractValueAndCheckType(selector, (String)context, Boolean.class); } - private Long extractLong(String source, Selector selector) throws Exception { - return extractValueAndCheckType(source, selector, Long.class); + @Nullable + private Long selectLong(@NotNull Selector selector, @NotNull String source) throws Exception { + return extractValueAndCheckType(selector, source, Long.class); } - private Date extractDate(String response, Selector selector) throws Exception { - String dateString = extractString(response, selector); - if (dateString == null) { - return null; + @NotNull + private JsonPath lazyCompile(@NotNull String path) throws Exception { + if (!myCompiledCache.containsKey(path)) { + try { + final JsonPath jsonPath = JsonPath.compile(path); + myCompiledCache.put(path, jsonPath); + } + catch (InvalidPathException e) { + throw new Exception(String.format("Malformed JsonPath expression '%s'", path)); + } } - return GenericRepositoryUtil.parseISO8601Date(dateString); + return myCompiledCache.get(path); } @Override diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java index fca6b21eeb41..e9e6d5e8460f 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java @@ -2,12 +2,14 @@ package com.intellij.tasks.generic; import com.intellij.execution.util.ListTableWithButtons; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.util.ui.AbstractTableCellEditor; import com.intellij.util.ui.ColumnInfo; import com.intellij.util.ui.ListTableModel; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import java.awt.*; import java.util.List; @@ -109,6 +111,27 @@ public class ManageTemplateVariablesDialog extends DialogWrapper { @Nullable @Override + public TableCellEditor getEditor(final TemplateVariable variable) { + if (variable.getIsHidden()) { + return new AbstractTableCellEditor() { + private JPasswordField myPasswordField; + @Override + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + myPasswordField = new JPasswordField(variable.getValue()); + return myPasswordField; + } + + @Override + public Object getCellEditorValue() { + return myPasswordField.getText(); + } + }; + } + return super.getEditor(variable); + } + + @Nullable + @Override protected String getDescription(TemplateVariable templateVariable) { return templateVariable.getDescription(); } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java index 45332b5de037..c08085194712 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java @@ -86,7 +86,7 @@ public final class RegExResponseHandler extends ResponseHandler { @NotNull @Override - public Task[] parseIssues(String response) throws Exception { + public Task[] parseIssues(String response, int max) throws Exception { final List<String> placeholders = getPlaceholders(myTaskRegex); if (!placeholders.contains(ID_PLACEHOLDER) || !placeholders.contains(SUMMARY_PLACEHOLDER)) { throw new Exception("Incorrect Task Pattern"); @@ -99,7 +99,7 @@ public final class RegExResponseHandler extends ResponseHandler { .matcher(response); List<Task> tasks = new ArrayList<Task>(); - while (matcher.find()) { + for (int i = 0; i < max && matcher.find(); i++) { String id = matcher.group(placeholders.indexOf(ID_PLACEHOLDER) + 1); String summary = matcher.group(placeholders.indexOf(SUMMARY_PLACEHOLDER) + 1); // temporary workaround to make AssemblaIntegrationTestPass diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java index 94bdd979cfcd..d51c38ac1bf7 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java @@ -45,7 +45,7 @@ public abstract class ResponseHandler implements Cloneable { public abstract ResponseType getResponseType(); @NotNull - public abstract Task[] parseIssues(String response) throws Exception; + public abstract Task[] parseIssues(String response, int max) throws Exception; @Nullable public abstract Task parseIssue(String response) throws Exception; diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java index 5ef8809a39c5..865e43db81a2 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java @@ -4,16 +4,19 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.tasks.Task; +import com.intellij.tasks.impl.TaskUtil; import com.intellij.ui.components.JBScrollPane; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xmlb.annotations.AbstractCollection; import com.intellij.util.xmlb.annotations.Property; import com.intellij.util.xmlb.annotations.Tag; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.ArrayList; +import java.util.Date; import java.util.LinkedHashMap; import java.util.List; @@ -22,6 +25,25 @@ import java.util.List; */ public abstract class SelectorBasedResponseHandler extends ResponseHandler { + // Supported selector names + @NonNls protected static final String TASKS = "tasks"; + + @NonNls protected static final String SUMMARY = "summary"; + @NonNls protected static final String DESCRIPTION = "description"; + @NonNls protected static final String ISSUE_URL = "issueUrl"; + @NonNls protected static final String CLOSED = "closed"; + @NonNls protected static final String UPDATED = "updated"; + @NonNls protected static final String CREATED = "created"; + + @NonNls protected static final String SINGLE_TASK_ID = "singleTask-id"; + @NonNls protected static final String SINGLE_TASK_SUMMARY = "singleTask-summary"; + @NonNls protected static final String SINGLE_TASK_DESCRIPTION = "singleTask-description"; + @NonNls protected static final String SINGLE_TASK_ISSUE_URL = "singleTask-issueUrl"; + @NonNls protected static final String SINGLE_TASK_CLOSED = "singleTask-closed"; + @NonNls protected static final String SINGLE_TASK_UPDATED = "singleTask-updated"; + @NonNls protected static final String SINGLE_TASK_CREATED = "singleTask-created"; + @NonNls protected static final String ID = "id"; + protected LinkedHashMap<String, Selector> mySelectors = new LinkedHashMap<String, Selector>(); /** @@ -37,25 +59,25 @@ public abstract class SelectorBasedResponseHandler extends ResponseHandler { // standard selectors setSelectors(ContainerUtil.newArrayList( // matched against list of tasks at whole downloaded from "taskListUrl" - new Selector("tasks", ""), + new Selector(TASKS), // matched against single tasks extracted from the list downloaded from "taskListUrl" - new Selector("id"), - new Selector("summary"), - new Selector("description"), - new Selector("updated"), - new Selector("created"), - new Selector("closed"), - new Selector("issueUrl"), + new Selector(ID), + new Selector(SUMMARY), + new Selector(DESCRIPTION), + new Selector(UPDATED), + new Selector(CREATED), + new Selector(CLOSED), + new Selector(ISSUE_URL), // matched against single task downloaded from "singleTaskUrl" - new Selector("singleTask-id"), - new Selector("singleTask-summary"), - new Selector("singleTask-description"), - new Selector("singleTask-updated"), - new Selector("singleTask-created"), - new Selector("singleTask-closed"), - new Selector("singleTask-issueUrl") + new Selector(SINGLE_TASK_ID), + new Selector(SINGLE_TASK_SUMMARY), + new Selector(SINGLE_TASK_DESCRIPTION), + new Selector(SINGLE_TASK_UPDATED), + new Selector(SINGLE_TASK_CREATED), + new Selector(SINGLE_TASK_CLOSED), + new Selector(SINGLE_TASK_ISSUE_URL) )); } @@ -76,15 +98,18 @@ public abstract class SelectorBasedResponseHandler extends ResponseHandler { } } - @Nullable - public Selector getSelector(@NotNull String name) { + /** + * Only predefined selectors should be accessed. + */ + @NotNull + protected Selector getSelector(@NotNull String name) { return mySelectors.get(name); } - @Nullable - public String getSelectorPath(@NotNull String name) { + @NotNull + protected String getSelectorPath(@NotNull String name) { Selector s = getSelector(name); - return s == null ? null : s.getPath(); + return s.getPath(); } @Override @@ -107,10 +132,10 @@ public abstract class SelectorBasedResponseHandler extends ResponseHandler { @Override public boolean isConfigured() { - Selector idSelector = getSelector("id"); - if (idSelector == null || StringUtil.isEmpty(idSelector.getPath())) return false; - Selector summarySelector = getSelector("summary"); - if (summarySelector == null || StringUtil.isEmpty(summarySelector.getPath())) return false; + Selector idSelector = getSelector(ID); + if (StringUtil.isEmpty(idSelector.getPath())) return false; + Selector summarySelector = getSelector(SUMMARY); + if (StringUtil.isEmpty(summarySelector.getPath())) return false; return true; } @@ -133,26 +158,109 @@ public abstract class SelectorBasedResponseHandler extends ResponseHandler { @NotNull @Override - public final Task[] parseIssues(String response) throws Exception { - if (StringUtil.isEmpty(getSelectorPath("tasks")) || - StringUtil.isEmpty(getSelectorPath("id")) || - StringUtil.isEmpty(getSelectorPath("summary"))) { + public final Task[] parseIssues(String response, int max) throws Exception { + if (StringUtil.isEmpty(getSelectorPath(TASKS)) || + StringUtil.isEmpty(getSelectorPath(ID)) || + StringUtil.isEmpty(getSelectorPath(SUMMARY))) { throw new Exception("Selectors 'tasks', 'id' and 'summary' are mandatory"); } - return doParseIssues(response); + List<Object> tasks = selectTasksList(response, max); + List<Task> result = new ArrayList<Task>(tasks.size()); + for (Object context : tasks) { + String id = selectString(getSelector(ID), context); + String summary = selectString(getSelector(SUMMARY), context); + assert id != null && summary != null; + GenericTask task = new GenericTask(id, summary, myRepository); + if (!myRepository.getDownloadTasksInSeparateRequests()) { + String description = selectString(getSelector(DESCRIPTION), context); + if (description != null) { + task.setDescription(description); + } + String issueUrl = selectString(getSelector(ISSUE_URL), context); + if (issueUrl != null) { + task.setIssueUrl(issueUrl); + } + Boolean closed = selectBoolean(getSelector(CLOSED), context); + if (closed != null) { + task.setClosed(closed); + } + Date updated = selectDate(getSelector(UPDATED), context); + if (updated != null) { + task.setUpdated(updated); + } + Date created = selectDate(getSelector(CREATED), context); + if (created != null) { + task.setCreated(created); + } + } + result.add(task); + } + return result.toArray(new Task[result.size()]); } - protected abstract Task[] doParseIssues(String response) throws Exception; + @Nullable + private Date selectDate(@NotNull Selector selector, @NotNull Object context) throws Exception { + String s = selectString(selector, context); + if (s == null) { + return null; + } + return TaskUtil.parseDate(s); + } + + @Nullable + protected Boolean selectBoolean(@NotNull Selector selector, @NotNull Object context) throws Exception { + String s = selectString(selector, context); + if (s == null) { + return null; + } + s = s.trim().toLowerCase(); + if (s.equals("true")) { + return true; + } + else if (s.equals("false")) { + return false; + } + throw new Exception( + String.format("Expression '%s' should match boolean value. Got '%s' instead", selector.getName(), s)); + } + + @NotNull + protected abstract List<Object> selectTasksList(@NotNull String response, int max) throws Exception; + + @Nullable + protected abstract String selectString(@NotNull Selector selector, @NotNull Object context) throws Exception; @Nullable @Override public final Task parseIssue(String response) throws Exception { - if (StringUtil.isEmpty(getSelectorPath("singleTask-id")) || - StringUtil.isEmpty(getSelectorPath("singleTask-summary"))) { + if (StringUtil.isEmpty(getSelectorPath(SINGLE_TASK_ID)) || + StringUtil.isEmpty(getSelectorPath(SINGLE_TASK_SUMMARY))) { throw new Exception("Selectors 'singleTask-id' and 'singleTask-summary' are mandatory"); } - return doParseIssue(response); + String id = selectString(getSelector(SINGLE_TASK_ID), response); + String summary = selectString(getSelector(SINGLE_TASK_SUMMARY), response); + assert id != null && summary != null; + GenericTask task = new GenericTask(id, summary, myRepository); + String description = selectString(getSelector(SINGLE_TASK_DESCRIPTION), response); + if (description != null) { + task.setDescription(description); + } + String issueUrl = selectString(getSelector(SINGLE_TASK_ISSUE_URL), response); + if (issueUrl != null) { + task.setIssueUrl(issueUrl); + } + Boolean closed = selectBoolean(getSelector(SINGLE_TASK_CLOSED), response); + if (closed != null) { + task.setClosed(closed); + } + Date updated = selectDate(getSelector(SINGLE_TASK_UPDATED), response); + if (updated != null) { + task.setUpdated(updated); + } + Date created = selectDate(getSelector(SINGLE_TASK_CREATED), response); + if (created != null) { + task.setCreated(created); + } + return task; } - - protected abstract Task doParseIssue(String response) throws Exception; } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java index 97dfc0731fc4..f768258d817d 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java @@ -1,42 +1,28 @@ package com.intellij.tasks.generic; import com.intellij.openapi.fileTypes.FileType; -import com.intellij.tasks.Task; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.containers.HashMap; import com.intellij.util.xmlb.annotations.Tag; import org.intellij.lang.xpath.XPathFileType; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.JDOMException; +import org.jdom.input.SAXBuilder; +import org.jdom.xpath.XPath; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.w3c.dom.Document; -import org.w3c.dom.NodeList; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathFactory; -import java.io.ByteArrayInputStream; -import java.util.ArrayList; +import java.io.StringReader; +import java.util.List; +import java.util.Map; /** * @author Mikhail Golubev */ @Tag("XPathResponseHandler") public final class XPathResponseHandler extends SelectorBasedResponseHandler { - private final static DocumentBuilder ourDocumentBuilder = createDocumentBuilder(); - private static DocumentBuilder createDocumentBuilder() { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - try { - return factory.newDocumentBuilder(); - } catch (ParserConfigurationException e) { - throw new AssertionError("Can't create DocumentBuilder"); - } - } - - private final static XPathFactory ourXPathFactory = createXPathFactory(); - private static XPathFactory createXPathFactory() { - return XPathFactory.newInstance(); - } + private final Map<String, XPath> myCompiledCache = new HashMap<String, XPath>(); /** * Serialization constructor @@ -50,44 +36,52 @@ public final class XPathResponseHandler extends SelectorBasedResponseHandler { super(repository); } + @NotNull @Override - public FileType getSelectorFileType() { - return XPathFileType.XPATH2; + protected List<Object> selectTasksList(@NotNull String response, int max) throws Exception { + Document document = new SAXBuilder(false).build(new StringReader(response)); + Element root = document.getRootElement(); + XPath xPath = lazyCompile(getSelector(TASKS).getPath()); + @SuppressWarnings("unchecked") + List<Object> rawTaskElements = xPath.selectNodes(root); + if (!rawTaskElements.isEmpty() && !(rawTaskElements.get(0) instanceof Element)) { + throw new Exception(String.format("Expression '%s' should match list of XML elements. Got '%s' instead.", + xPath.getXPath(), rawTaskElements.toString())); + } + return rawTaskElements.subList(0, Math.min(rawTaskElements.size(), max)); } + @Nullable @Override - public Task[] doParseIssues(String response) throws Exception { - String idSelector = getSelectorPath("id"), summarySelector = getSelectorPath("summary"); - if (idSelector == null || summarySelector == null) { - throw new IllegalArgumentException("Selectors 'task', 'id' and 'summary' are mandatory"); + protected String selectString(@NotNull Selector selector, @NotNull Object context) throws Exception { + if (StringUtil.isEmpty(selector.getPath())) { + return null; } - - Document document = ourDocumentBuilder.parse(new ByteArrayInputStream(response.getBytes())); - - XPathExpression idPath = ourXPathFactory.newXPath().compile(idSelector); - NodeList idNodes = (NodeList)idPath.evaluate(document, XPathConstants.NODESET); - - XPathExpression summaryPath = ourXPathFactory.newXPath().compile(summarySelector); - NodeList summaryNodes = (NodeList)summaryPath.evaluate(document, XPathConstants.NODESET); - - if (summaryNodes.getLength() != idNodes.getLength()) { - // popup will be shown to the user - throw new IllegalArgumentException("Number of tasks selected by 'id' and 'summary' XPath expressions is not the same."); + XPath xPath = lazyCompile(selector.getPath()); + String s = xPath.valueOf(context); + if (s == null) { + throw new Exception(String.format("XPath expression '%s' doesn't match", xPath.getXPath())); } + return s; + } - ArrayList<Task> tasks = new ArrayList<Task>(idNodes.getLength()); - for (int i = 0; i < idNodes.getLength(); i++) { - String id = idNodes.item(i).getNodeValue(); - String summary = summaryNodes.item(i).getNodeValue(); - tasks.add(new GenericTask(id, summary, myRepository)); + @NotNull + private XPath lazyCompile(@NotNull String path) throws Exception { + if (!myCompiledCache.containsKey(path)) { + try { + final XPath compiled = XPath.newInstance(path); + myCompiledCache.put(path, compiled); + } + catch (JDOMException e) { + throw new Exception(String.format("Malformed XPath expression '%s'", path)); + } } - return tasks.toArray(new Task[tasks.size()]); + return myCompiledCache.get(path); } - @Nullable @Override - public Task doParseIssue(String response) throws Exception { - return null; + public FileType getSelectorFileType() { + return XPathFileType.XPATH; } @Override diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml index b374b7f8e51f..942ca6f7f68a 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml @@ -1,13 +1,14 @@ <Generic shared="false" url="https://app.asana.com/api/1.0"> <commitMessageFormat>{id} {summary}</commitMessageFormat> <password/> + <option name="downloadTasksInSeparateRequests" value="true" /> <option name="loginAnonymously" value="false"/> <option name="loginMethodType" value="GET"/> <option name="loginUrl" value=""/> <option name="responseHandlers"> <XPathResponseHandler> <selectors> - <selector name="tasks" path="foo"/> + <selector name="tasks" path=""/> <selector name="id" path=""/> <selector name="summary" path=""/> <selector name="description" path=""/> @@ -30,7 +31,7 @@ <selector name="description" path=""/> <selector name="updated" path=""/> <selector name="created" path=""/> - <selector name="completed" path=""/> + <selector name="closed" path=""/> <selector name="issueUrl" path=""/> <selector name="singleTask-id" path="data.id"/> <selector name="singleTask-summary" path="data.name"/> diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java index fb2c776406ec..4c939830e4f4 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java @@ -771,7 +771,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe Task[] tasks = repository.getIssues(request, max, since, cancelled); myBadRepositories.remove(repository); if (issues == null) issues = new ArrayList<Task>(tasks.length); - if (!repository.isSupported(TaskRepository.NATIVE_SEARCH)) { + if (!repository.isSupported(TaskRepository.NATIVE_SEARCH) && request != null) { List<Task> filteredTasks = TaskSearchSupport.filterTasks(request, ContainerUtil.list(tasks)); ContainerUtil.addAll(issues, filteredTasks); } else { diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskUtil.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskUtil.java index 6a386f9760c0..b37a07a1628f 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskUtil.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskUtil.java @@ -22,7 +22,6 @@ import com.intellij.tasks.TaskRepository; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -33,9 +32,10 @@ import java.util.regex.Pattern; * @author Dmitry Avdeev */ public class TaskUtil { - - private static final Pattern DATE_PATTERN = Pattern.compile("(\\d\\d\\d\\d[/-]\\d\\d[/-]\\d\\d).*(\\d\\d:\\d\\d:\\d\\d).*"); - private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + private static SimpleDateFormat ISO8601_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + // Almost ISO-8601 strict except date parts may be separated by '/' as well + private static Pattern ISO8601_DATE_PATTERN = Pattern.compile( + "(\\d{4}[/-]\\d{2}[/-]\\d{2})[ T](\\d{2}:\\d{2}:\\d{2})(.\\d{3,})?([+-]\\d{2}:\\d{2}|[+-]\\d{4}|[+-]\\d{2}|Z)?"); public static String formatTask(@NotNull Task task, String format) { return format.replace("{id}", task.getId()).replace("{number}", task.getNumber()) @@ -62,11 +62,34 @@ public class TaskUtil { } @Nullable - public static Date parseDate(String date) throws ParseException { - final Matcher m = DATE_PATTERN.matcher(date); - if (m.find()) { - return DATE_FORMAT.parse(m.group(1).replace('-', '/') + " " + m.group(2)); + public static Date parseDate(@NotNull String s) { + // SimpleDateFormat prior JDK7 doesn't support 'X' specifier for ISO 8601 timezone format. + // Because some bug trackers and task servers e.g. send dates ending with 'Z' (that stands for UTC), + // dates should be preprocessed before parsing. + Matcher m = ISO8601_DATE_PATTERN.matcher(s); + if (!m.matches()) { + return null; + } + String datePart = m.group(1).replace('/', '-'); + String timePart = m.group(2); + String milliseconds = m.group(3); + milliseconds = milliseconds == null? "000" : milliseconds.substring(1, 4); + String timezone = m.group(4); + if (timezone == null || timezone.equals("Z")) { + timezone = "+0000"; + } else if (timezone.length() == 3) { + // [+-]HH + timezone += "00"; + } else if (timezone.length() == 6) { + // [+-]HH:MM + timezone = timezone.substring(0, 3) + timezone.substring(4, 6); + } + String canonicalForm = String.format("%sT%s.%s%s", datePart, timePart, milliseconds, timezone); + try { + return ISO8601_DATE_FORMAT.parse(canonicalForm); + } + catch (ParseException e) { + return null; } - return null; } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java index 847d7b17d4cb..f1571fb61447 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java @@ -9,6 +9,7 @@ import com.intellij.tasks.TaskRepository; import com.intellij.tasks.TaskType; import com.intellij.tasks.impl.BaseRepository; import com.intellij.tasks.impl.BaseRepositoryImpl; +import com.intellij.tasks.impl.TaskUtil; import com.intellij.util.NullableFunction; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xmlb.annotations.Tag; @@ -172,6 +173,7 @@ public class RedmineRepository extends BaseRepositoryImpl { }; } + @Nullable private static Date parseDate(Element element, String name) throws ParseException { final String date = element.getChildText(name); if (date.matches(".*\\+\\d\\d:\\d\\d")) { @@ -180,7 +182,16 @@ public class RedmineRepository extends BaseRepositoryImpl { format.setTimeZone(TimeZone.getTimeZone("GMT" + date.substring(timeZoneIndex))); return format.parse(date.substring(0, timeZoneIndex)); } - return (new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.US)).parse(date); + // Ad-hoc fix for IDEA-110012 + Date parsed; + try { + parsed = (new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.US)).parse(date); + } + catch (ParseException e) { + LOG.warn("Unparseable date: " + date, e); + parsed = TaskUtil.parseDate(date); + } + return parsed; } @Override diff --git a/plugins/tasks/tasks-tests/tasks-tests.iml b/plugins/tasks/tasks-tests/tasks-tests.iml index a1d500107e02..deeddccdb91f 100644 --- a/plugins/tasks/tasks-tests/tasks-tests.iml +++ b/plugins/tasks/tasks-tests/tasks-tests.iml @@ -18,8 +18,6 @@ <orderEntry type="module" module-name="xslt-debugger" /> <orderEntry type="module" module-name="xdebugger-impl" scope="TEST" /> <orderEntry type="module" module-name="git4idea" scope="TEST" /> - <orderEntry type="module" module-name="remote-servers-impl" scope="TEST" /> - <orderEntry type="module" module-name="manifest" scope="TEST" /> </component> </module> diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/AsanaGenericIntegrationTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/AsanaGenericIntegrationTest.java index 1a6d3bf41035..8bb2fec45f40 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/AsanaGenericIntegrationTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/AsanaGenericIntegrationTest.java @@ -53,7 +53,7 @@ public class AsanaGenericIntegrationTest extends TaskManagerTestCase { } public void testParsing() throws Exception { - Task[] tasks = myRepository.getActiveResponseHandler().parseIssues(RESPONSE); + Task[] tasks = myRepository.getActiveResponseHandler().parseIssues(RESPONSE, 50); List<Task> expected = ContainerUtil.<Task>newArrayList( new GenericTask("5479650606120", "Task #1", myRepository), new GenericTask("5202014833559", "Task #2", myRepository) diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/AssemblaIntegrationTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/AssemblaIntegrationTest.java index 43a8af6043ff..28723a65d587 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/AssemblaIntegrationTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/AssemblaIntegrationTest.java @@ -63,7 +63,7 @@ public class AssemblaIntegrationTest extends TaskManagerTestCase { public void testParseCyrillic() throws Exception { AssemblaRepository repository = new AssemblaRepository(new AssemblaRepositoryType()); - Task[] tasks = repository.getActiveResponseHandler().parseIssues(RESPONSE); + Task[] tasks = repository.getActiveResponseHandler().parseIssues(RESPONSE, 50); assertEquals(1, tasks.length); assertEquals("\u041F\u0440\u0438\u0432\u0435\u0442", tasks[0].getSummary()); } diff --git a/plugins/terminal/lib/jediterm-pty-0.08.jar b/plugins/terminal/lib/jediterm-pty-0.08.jar Binary files differindex e9bf3366fd6e..0e3c22395e8e 100644 --- a/plugins/terminal/lib/jediterm-pty-0.08.jar +++ b/plugins/terminal/lib/jediterm-pty-0.08.jar diff --git a/plugins/terminal/lib/pty4j-0.3.jar b/plugins/terminal/lib/pty4j-0.3.jar Binary files differindex a4d2cb998c44..67200e1203af 100644 --- a/plugins/terminal/lib/pty4j-0.3.jar +++ b/plugins/terminal/lib/pty4j-0.3.jar diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java index 0ddfd9f18b6f..c1ceb923a569 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java @@ -19,6 +19,7 @@ import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.util.ui.UIUtil; +import com.jediterm.pty.PtyProcessTtyConnector; import com.jediterm.terminal.TtyConnector; import com.jediterm.terminal.emulator.ColorPalette; import com.jediterm.terminal.ui.AbstractSystemSettingsProvider; @@ -30,6 +31,7 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.util.ArrayList; +import java.util.List; import java.util.concurrent.ExecutionException; /** @@ -191,7 +193,7 @@ public abstract class AbstractTerminalRunner<T extends Process> { } private KeyStroke[] getKeyStrokesByActionId(String actionId) { - java.util.List<KeyStroke> keyStrokes = new ArrayList<KeyStroke>(); + List<KeyStroke> keyStrokes = new ArrayList<KeyStroke>(); Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionId); for (Shortcut sc : shortcuts) { if (sc instanceof KeyboardShortcut) { @@ -202,6 +204,11 @@ public abstract class AbstractTerminalRunner<T extends Process> { return keyStrokes.toArray(new KeyStroke[keyStrokes.size()]); } + + @Override + public boolean shouldCloseTabOnLogout(TtyConnector ttyConnector) { + return ttyConnector instanceof PtyProcessTtyConnector; //close tab only on logout of local pty, not remote + } } public void openSession(TerminalWidget terminalWidget) { diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java index 53d52f89e5da..051a5a54359d 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java @@ -1,16 +1,43 @@ package org.jetbrains.plugins.terminal; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.DumbAwareAction; import com.jediterm.terminal.ui.JediTermWidget; import com.jediterm.terminal.ui.SystemSettingsProvider; import com.jediterm.terminal.ui.TabbedTerminalWidget; +import com.jediterm.terminal.ui.TerminalAction; import org.jetbrains.annotations.NotNull; +import javax.swing.*; +import java.awt.event.KeyEvent; +import java.util.List; + /** * @author traff */ public class JBTabbedTerminalWidget extends TabbedTerminalWidget { public JBTabbedTerminalWidget(@NotNull SystemSettingsProvider settingsProvider) { super(settingsProvider); + + convertActions(this, getActions()); + } + + public static void convertActions(JComponent component, List<TerminalAction> actions) { + for (final TerminalAction action : actions) { + AnAction a = new DumbAwareAction() { + @Override + public void actionPerformed(AnActionEvent e) { + if (e.getInputEvent() instanceof KeyEvent) { + action.perform((KeyEvent)e.getInputEvent()); + } + else { + action.perform(null); + } + } + }; + a.registerCustomShortcutSet(action.getKeyCode(), action.getModifiers(), component); + } } @Override diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java index 7a83c324fba1..e5b6e533e705 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java @@ -62,6 +62,8 @@ public class JBTerminalPanel extends TerminalPanel { TerminalColor.awt(myColorScheme.getColor(EditorColors.SELECTION_BACKGROUND_COLOR)))); setLineSpace(myColorScheme.getConsoleLineSpacing()); + + JBTabbedTerminalWidget.convertActions(this, getActions()); } protected Font createFont() { @@ -116,6 +118,11 @@ public class JBTerminalPanel extends TerminalPanel { protected BufferedImage createBufferedImage(int width, int height) { return UIUtil.createImage(width, height, BufferedImage.TYPE_INT_ARGB); } + + @Override + protected void drawImage(Graphics2D g, BufferedImage image) { + UIUtil.drawImage(g, image, null, 0, 0); + } public String getFontName() { List<String> fonts = myColorScheme.getConsoleFontPreferences().getEffectiveFontFamilies(); @@ -125,7 +132,7 @@ public class JBTerminalPanel extends TerminalPanel { return font; } } - return "Monospaced-14"; + return super.getFontName(); } private static boolean isApplicable(String font) { diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java index 1701a18926a7..6f2e49da3f27 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java @@ -28,6 +28,8 @@ public class JBTerminalWidget extends JediTermWidget { public JBTerminalWidget(SystemSettingsProvider settingsProvider) { super(settingsProvider); + + JBTabbedTerminalWidget.convertActions(this, getActions()); } @Override diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java index 73c8d69ea2e6..bd7cfd23675e 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java @@ -4,12 +4,15 @@ import com.intellij.icons.AllIcons; import com.intellij.notification.EventLog; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.SimpleToolWindowPanel; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentFactory; +import com.jediterm.terminal.ui.JediTermWidget; +import com.jediterm.terminal.ui.TabbedTerminalWidget; import com.jediterm.terminal.ui.TerminalWidget; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -26,7 +29,7 @@ public class TerminalView { private JBTabbedTerminalWidget myTerminalWidget; private Project myProject; - public void initTerminal(Project project, ToolWindow toolWindow) { + public void initTerminal(Project project, final ToolWindow toolWindow) { myProject = project; LocalTerminalDirectRunner terminalRunner = OpenLocalTerminalAction.createTerminalRunner(project); @@ -34,6 +37,12 @@ public class TerminalView { if (terminalRunner != null) { myTerminalWidget = terminalRunner.createTerminalWidget(); + myTerminalWidget.addTabListener(new TabbedTerminalWidget.TabListener() { + @Override + public void tabClosed(JediTermWidget terminal) { + hideIfNoActiveSessions(toolWindow, myTerminalWidget); + } + }); } Content content = createToolWindowContentPanel(terminalRunner, myTerminalWidget, toolWindow); @@ -142,7 +151,20 @@ public class TerminalView { }, true); } - private static class NewSession extends AnAction { + private void hideIfNoActiveSessions(final ToolWindow toolWindow, JBTabbedTerminalWidget terminal) { + if (terminal.isNoActiveSessions()) { + toolWindow.getContentManager().removeAllContents(true); + + toolWindow.getActivation().doWhenDone(new Runnable() { + @Override + public void run() { + initTerminal(myProject, toolWindow); + } + }); + } + } + + private static class NewSession extends DumbAwareAction { private final LocalTerminalDirectRunner myTerminalRunner; private final TerminalWidget myTerminal; @@ -158,7 +180,7 @@ public class TerminalView { } } - private class CloseSession extends AnAction { + private class CloseSession extends DumbAwareAction { private final JBTabbedTerminalWidget myTerminal; private ToolWindow myToolWindow; @@ -170,20 +192,9 @@ public class TerminalView { @Override public void actionPerformed(AnActionEvent e) { - boolean singleSession = myTerminal.isSingleSession(); - myTerminal.closeCurrentSession(); - - if (singleSession) { - myToolWindow.getContentManager().removeAllContents(true); - - myToolWindow.getActivation().doWhenDone(new Runnable() { - @Override - public void run() { - initTerminal(myProject, myToolWindow); - } - }); - } + + hideIfNoActiveSessions(myToolWindow, myTerminal); } } } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/LoaderFactory.java b/plugins/ui-designer/src/com/intellij/uiDesigner/LoaderFactory.java index 66d349a79bd4..4b95eefa8976 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/LoaderFactory.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/LoaderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,7 +55,7 @@ public final class LoaderFactory { public static LoaderFactory getInstance(final Project project) { return ServiceManager.getService(project, LoaderFactory.class); } - + public LoaderFactory(final Project project) { myProject = project; myModule2ClassLoader = new ConcurrentWeakHashMap<Module, ClassLoader>(); @@ -155,7 +155,7 @@ public final class LoaderFactory { private final String myModuleName; public DesignTimeClassLoader(final List<URL> urls, final ClassLoader parent, final String moduleName) { - super(urls, parent); + super(build().urls(urls).parent(parent)); myModuleName = moduleName; } diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 5f6c484bed22..602a51eca96d 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -10,6 +10,9 @@ <xi:include href="/componentSets/Debugger.xml" xpointer="xpointer(/components/*)"/> <xi:include href="/META-INF/IntentionPowerPack.xml" xpointer="xpointer(/idea-plugin/*)"/> <xi:include href="/META-INF/InspectionGadgets.xml" xpointer="xpointer(/idea-plugin/*)"/> + <xi:include href="/META-INF/ManifestSupport.xml" xpointer="xpointer(/idea-plugin/*)"> + <xi:fallback/> + </xi:include> <application-components> <component> @@ -222,8 +225,6 @@ <extensionPoint name="java.compilerOutputIndex" area="IDEA_PROJECT" interface="com.intellij.compilerOutputIndex.api.indexer.CompilerOutputBaseIndex"/> <extensionPoint name="vetoSPICondition" interface="com.intellij.openapi.util.Condition"/> - - <extensionPoint name="manifest.parser.provider" interface="org.jetbrains.lang.manifest.header.HeaderParserProvider"/> </extensionPoints> <extensions defaultExtensionNs="com.intellij"> @@ -1438,22 +1439,6 @@ <lang.commenter language="SPI" implementationClass="com.intellij.spi.SPICommenter"/> <annotator language="SPI" implementationClass="com.intellij.spi.SPIAnnotator"/> - <fileTypeFactory implementation="org.jetbrains.lang.manifest.ManifestFileTypeFactory"/> - <lang.parserDefinition language="Manifest" implementationClass="org.jetbrains.lang.manifest.parser.ManifestParserDefinition"/> - <lang.syntaxHighlighterFactory key="Manifest" implementationClass="org.jetbrains.lang.manifest.highlighting.ManifestSyntaxHighlighterFactory"/> - <annotator language="Manifest" implementationClass="org.jetbrains.lang.manifest.highlighting.HeaderAnnotator"/> - <lang.elementManipulator forClass="org.jetbrains.lang.manifest.psi.HeaderValuePart" - implementationClass="org.jetbrains.lang.manifest.psi.impl.HeaderValuePartManipulator"/> - <completion.contributor language="Manifest" implementationClass="org.jetbrains.lang.manifest.completion.ManifestCompletionContributor"/> - <manifest.parser.provider implementation="org.jetbrains.lang.manifest.header.impl.StandardManifestHeaderParsers"/> - - <applicationService serviceImplementation="org.jetbrains.lang.manifest.header.HeaderParserRepository"/> - - <localInspection language="Manifest" displayName="Missing Final New Line" groupName="Manifest" - enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.lang.manifest.highlighting.MissingFinalNewlineInspection"/> - <localInspection language="Manifest" displayName="Unknown or Misspelled Header Name" groupName="Manifest" - enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.lang.manifest.highlighting.MisspelledHeaderInspection"/> - <gotoDeclarationHandler implementation="com.intellij.codeInsight.navigation.actions.GotoLambdaParameterHandler"/> <java.compilerOutputIndex implementation="com.intellij.compilerOutputIndex.impl.MethodsUsageIndex"/> diff --git a/resources/src/idea/RichPlatformPlugin.xml b/resources/src/idea/RichPlatformPlugin.xml index c539ddb15bde..9e841a297e95 100644 --- a/resources/src/idea/RichPlatformPlugin.xml +++ b/resources/src/idea/RichPlatformPlugin.xml @@ -385,7 +385,12 @@ </extensions> <xi:include href="/META-INF/xdebugger.xml" xpointer="xpointer(/idea-plugin/*)"/> - <xi:include href="/META-INF/RemoteServers.xml" xpointer="xpointer(/idea-plugin/*)"/> + <xi:include href="/META-INF/RemoteServers.xml" xpointer="xpointer(/idea-plugin/*)"> + <xi:fallback/> + </xi:include> + <xi:include href="/META-INF/RemoteServersJava.xml" xpointer="xpointer(/idea-plugin/*)"> + <xi:fallback/> + </xi:include> <xi:include href="/META-INF/XmlPlugin.xml" xpointer="xpointer(/idea-plugin/*)"/> <xi:include href="/META-INF/RegExpPlugin.xml" xpointer="xpointer(/idea-plugin/*)"/> diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/GenericValueReferenceProvider.java b/xml/dom-impl/src/com/intellij/util/xml/impl/GenericValueReferenceProvider.java index c36c2bfa2454..d817a7ee0ce0 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/GenericValueReferenceProvider.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/GenericValueReferenceProvider.java @@ -24,7 +24,7 @@ import com.intellij.psi.xml.*; import com.intellij.util.ProcessingContext; import com.intellij.util.ReflectionCache; import com.intellij.util.xml.*; -import com.intellij.xml.util.XmlAttributeValueReferenceProvider; +import com.intellij.xml.util.XmlEnumeratedValueReferenceProvider; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -92,7 +92,7 @@ public class GenericValueReferenceProvider extends PsiReferenceProvider { // will be handled by core XML return PsiReference.EMPTY_ARRAY; } - context.put(XmlAttributeValueReferenceProvider.SUPPRESS, Boolean.TRUE); + context.put(XmlEnumeratedValueReferenceProvider.SUPPRESS, Boolean.TRUE); } return references; } diff --git a/xml/impl/src/com/intellij/xml/util/XmlAttributeValueReferenceProvider.java b/xml/impl/src/com/intellij/xml/util/XmlEnumeratedValueReferenceProvider.java index 33d72010189d..590ae534eaa6 100644 --- a/xml/impl/src/com/intellij/xml/util/XmlAttributeValueReferenceProvider.java +++ b/xml/impl/src/com/intellij/xml/util/XmlEnumeratedValueReferenceProvider.java @@ -18,13 +18,15 @@ package com.intellij.xml.util; import com.intellij.codeInsight.daemon.impl.analysis.XmlHighlightVisitor; import com.intellij.openapi.util.Key; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.psi.PsiReference; import com.intellij.psi.PsiReferenceProvider; +import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.util.ProcessingContext; import com.intellij.xml.XmlAttributeDescriptor; -import com.intellij.xml.impl.BasicXmlAttributeDescriptor; +import com.intellij.xml.impl.XmlEnumerationDescriptor; import com.intellij.xml.impl.schema.XmlSchemaTagsProcessor; import org.jetbrains.annotations.NotNull; @@ -32,7 +34,7 @@ import org.jetbrains.annotations.NotNull; * @author Dmitry Avdeev * Date: 15.08.13 */ -public class XmlAttributeValueReferenceProvider extends PsiReferenceProvider { +public class XmlEnumeratedValueReferenceProvider extends PsiReferenceProvider { public final static Key<Boolean> SUPPRESS = Key.create("suppress attribute value references"); @@ -44,6 +46,9 @@ public class XmlAttributeValueReferenceProvider extends PsiReferenceProvider { return PsiReference.EMPTY_ARRAY; } XmlAttributeValue value = (XmlAttributeValue)element; + if (value instanceof PsiLanguageInjectionHost && InjectedLanguageUtil.hasInjections((PsiLanguageInjectionHost)value)) { + return PsiReference.EMPTY_ARRAY; + } String unquotedValue = value.getValue(); if (unquotedValue == null || XmlHighlightVisitor.skipValidation(value) || !XmlUtil.isSimpleXmlAttributeValue(unquotedValue, value)) { return PsiReference.EMPTY_ARRAY; @@ -51,9 +56,9 @@ public class XmlAttributeValueReferenceProvider extends PsiReferenceProvider { PsiElement parent = value.getParent(); if (parent instanceof XmlAttribute) { final XmlAttributeDescriptor descriptor = ((XmlAttribute)parent).getDescriptor(); - if (descriptor instanceof BasicXmlAttributeDescriptor && + if (descriptor instanceof XmlEnumerationDescriptor && (descriptor.isFixed() || descriptor.isEnumerated() || unquotedValue.equals(descriptor.getDefaultValue()))) { // todo case insensitive - return ((BasicXmlAttributeDescriptor)descriptor).getValueReferences(value); + return ((XmlEnumerationDescriptor)descriptor).getValueReferences(value); } } return PsiReference.EMPTY_ARRAY; diff --git a/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java b/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java index 6fcd606e18fa..ae588622794a 100644 --- a/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java +++ b/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java @@ -89,6 +89,6 @@ public class XmlReferenceContributor extends PsiReferenceContributor { new XmlEncodingReferenceProvider()); registrar.registerReferenceProvider(xmlAttributeValue(), new XmlPrefixReferenceProvider()); - registrar.registerReferenceProvider(xmlAttributeValue(), new XmlAttributeValueReferenceProvider(), PsiReferenceRegistrar.LOWER_PRIORITY); + registrar.registerReferenceProvider(xmlAttributeValue(), new XmlEnumeratedValueReferenceProvider(), PsiReferenceRegistrar.LOWER_PRIORITY); } } diff --git a/xml/impl/src/com/intellij/xml/util/documentation/XmlDocumentationProvider.java b/xml/impl/src/com/intellij/xml/util/documentation/XmlDocumentationProvider.java index ff05952cf910..b464d56de0c4 100644 --- a/xml/impl/src/com/intellij/xml/util/documentation/XmlDocumentationProvider.java +++ b/xml/impl/src/com/intellij/xml/util/documentation/XmlDocumentationProvider.java @@ -91,7 +91,8 @@ public class XmlDocumentationProvider implements DocumentationProvider { if (curElement!=null) { return formatDocFromComment(curElement, ((XmlElementDecl)element).getNameElement().getText()); } - } else if (element instanceof XmlTag) { + } + else if (element instanceof XmlTag) { XmlTag tag = (XmlTag)element; MyPsiElementProcessor processor = new MyPsiElementProcessor(); String name = tag.getAttributeValue(NAME_ATTR_NAME); @@ -271,7 +272,7 @@ public class XmlDocumentationProvider implements DocumentationProvider { return generateDoc(text, name,null, null); } - private XmlTag getComplexOrSimpleTypeDefinition(PsiElement element, PsiElement originalElement) { + private static XmlTag getComplexOrSimpleTypeDefinition(PsiElement element, PsiElement originalElement) { XmlElementDescriptor descriptor = element.getUserData(DESCRIPTOR_KEY); XmlTag contextTag = null; @@ -421,14 +422,13 @@ public class XmlDocumentationProvider implements DocumentationProvider { if (object instanceof String && originalElement != null) { PsiElement result = findDeclWithName((String)object, originalElement); - PsiElement originalElementParent; - if (result == null && element instanceof XmlTag && (originalElementParent = originalElement.getParent()) instanceof XmlAttributeValue) { - PsiElement originalElementGrandParent = originalElementParent.getParent(); - XmlAttributeDescriptor descriptor = originalElementGrandParent instanceof XmlAttribute ? - ((XmlAttribute)originalElementGrandParent).getDescriptor():null; - - if (descriptor != null && descriptor.getDeclaration() instanceof XmlTag) { - result = findEnumerationValue((String)object, (XmlTag)descriptor.getDeclaration()); + if (result == null && element instanceof XmlTag) { + XmlAttribute attribute = PsiTreeUtil.getParentOfType(originalElement, XmlAttribute.class, false); + if (attribute != null) { + XmlAttributeDescriptor descriptor = attribute.getDescriptor(); + if (descriptor != null && descriptor.getDeclaration() instanceof XmlTag) { + result = findEnumerationValue((String)object, (XmlTag)descriptor.getDeclaration()); + } } } return result; diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngXmlAttributeDescriptor.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngXmlAttributeDescriptor.java index db3d85e44600..f9d9f7cbe23e 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngXmlAttributeDescriptor.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngXmlAttributeDescriptor.java @@ -17,9 +17,6 @@ package org.intellij.plugins.relaxNG.model.descriptors; import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.text.DelimitedListProcessor; -import com.intellij.psi.ElementManipulators; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; @@ -30,8 +27,8 @@ import com.intellij.psi.xml.XmlTag; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; -import com.intellij.xml.util.XmlAttributeValueReference; import com.intellij.xml.impl.BasicXmlAttributeDescriptor; +import com.intellij.xml.util.XmlEnumeratedValueReference; import gnu.trove.THashSet; import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NonNls; @@ -212,19 +209,15 @@ public class RngXmlAttributeDescriptor extends BasicXmlAttributeDescriptor { public PsiReference[] getValueReferences(final XmlAttributeValue value) { String text = value.getValue(); if (text == null) return PsiReference.EMPTY_ARRAY; - final int offset = ElementManipulators.getValueTextRange(value).getStartOffset(); - final List<PsiReference> list = new ArrayList<PsiReference>(); - new DelimitedListProcessor("") { + return new PsiReference[] { new XmlEnumeratedValueReference(value, this) { + @Nullable @Override - protected boolean isDelimiter(char ch) { - return Character.isWhitespace(ch); - } - - @Override - protected void processToken(int start, int end, boolean delimitersOnly) { - list.add(new XmlAttributeValueReference(value, TextRange.create(offset + start, offset + end), RngXmlAttributeDescriptor.this)); + public PsiElement resolve() { + if (isTokenDatatype(getValue())) { + return getElement(); + } + return super.resolve(); } - }.processText(text); - return list.toArray(new PsiReference[list.size()]); + }}; } }
\ No newline at end of file diff --git a/xml/relaxng/test/org/intellij/plugins/relaxNG/RngXmlHighlightingTest.java b/xml/relaxng/test/org/intellij/plugins/relaxNG/RngXmlHighlightingTest.java index d813d2bcbf48..261ca4e2e98e 100644 --- a/xml/relaxng/test/org/intellij/plugins/relaxNG/RngXmlHighlightingTest.java +++ b/xml/relaxng/test/org/intellij/plugins/relaxNG/RngXmlHighlightingTest.java @@ -17,7 +17,7 @@ package org.intellij.plugins.relaxNG; import com.intellij.javaee.ExternalResourceManagerEx; -import com.intellij.javaee.ExternalResourceManagerImpl; +import com.intellij.javaee.ExternalResourceManagerExImpl; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.fileTypes.StdFileTypes; @@ -41,13 +41,19 @@ public class RngXmlHighlightingTest extends HighlightingTestBase { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { final ExternalResourceManagerEx m = ExternalResourceManagerEx.getInstanceEx(); - ExternalResourceManagerImpl.addTestResource("urn:test:simple.rng", toAbsolutePath("highlighting/simple.rng"), myTestRootDisposable); - ExternalResourceManagerImpl.addTestResource("urn:test:addressBook", toAbsolutePath("highlighting/rnc/addressbook.rnc"), myTestRootDisposable); + ExternalResourceManagerExImpl + .addTestResource("urn:test:simple.rng", toAbsolutePath("highlighting/simple.rng"), myTestRootDisposable); + ExternalResourceManagerExImpl.addTestResource("urn:test:addressBook", toAbsolutePath("highlighting/rnc/addressbook.rnc"), + myTestRootDisposable); //m.addResource("http://www.w3.org/1999/XSL/Transform", toAbsolutePath("highlighting/relaxng.rng")); - ExternalResourceManagerImpl.addTestResource("http://www.w3.org/1999/XSL/Format", toAbsolutePath("highlighting/rnc/fo/main.rnc"), myTestRootDisposable); - ExternalResourceManagerImpl.addTestResource("http://docbook.org/ns/docbook", toAbsolutePath("highlighting/docbook.rng"), myTestRootDisposable); - ExternalResourceManagerImpl.addTestResource("urn:intelliForm:AttachmentFilter", toAbsolutePath("highlighting/attachment-filter.rng"), myTestRootDisposable); - ExternalResourceManagerImpl.addTestResource("http://www.w3.org/1999/xhtml", toAbsolutePath("highlighting/html5/xhtml5.rnc"), myTestRootDisposable); + ExternalResourceManagerExImpl.addTestResource("http://www.w3.org/1999/XSL/Format", toAbsolutePath("highlighting/rnc/fo/main.rnc"), + myTestRootDisposable); + ExternalResourceManagerExImpl.addTestResource("http://docbook.org/ns/docbook", toAbsolutePath("highlighting/docbook.rng"), + myTestRootDisposable); + ExternalResourceManagerExImpl.addTestResource("urn:intelliForm:AttachmentFilter", + toAbsolutePath("highlighting/attachment-filter.rng"), myTestRootDisposable); + ExternalResourceManagerExImpl + .addTestResource("http://www.w3.org/1999/xhtml", toAbsolutePath("highlighting/html5/xhtml5.rnc"), myTestRootDisposable); m.addIgnoredResource("urn:intelliForm:Spaces"); m.addIgnoredResource("http://www.w3.org/1999/xlink"); diff --git a/xml/relaxng/testData/highlighting/token-datatype.xml b/xml/relaxng/testData/highlighting/token-datatype.xml index d6e508e77ec6..edd9b0063062 100644 --- a/xml/relaxng/testData/highlighting/token-datatype.xml +++ b/xml/relaxng/testData/highlighting/token-datatype.xml @@ -1,4 +1,4 @@ <token-datatype xmlns="urn:test:simple.rng" a=" v " b="v" c=" x y " s1="v" s2=" v " - s3=<error>" v "</error> />
\ No newline at end of file + s3="<error descr="Attribute should have fixed value v"> v </error>" />
\ No newline at end of file diff --git a/xml/tests/src/com/intellij/codeInsight/XmlDocumentationTest.java b/xml/tests/src/com/intellij/codeInsight/XmlDocumentationTest.java index 319d3941e267..1df551bc875c 100644 --- a/xml/tests/src/com/intellij/codeInsight/XmlDocumentationTest.java +++ b/xml/tests/src/com/intellij/codeInsight/XmlDocumentationTest.java @@ -79,7 +79,9 @@ public class XmlDocumentationTest extends DaemonAnalyzerTestCase { VirtualFile vfile = LocalFileSystem.getInstance().findFileByIoFile(new File(pathname)); assertNotNull(pathname + " not found", vfile); String expectedText = StringUtil.convertLineSeparators(VfsUtilCore.loadText(vfile)); - assertEquals(expectedText, StringUtil.convertLineSeparators(context.generateDoc())); + String text = context.generateDoc(); + assertNotNull(text); + assertEquals(expectedText, StringUtil.convertLineSeparators(text)); if (completionVariant != null) { vfile = LocalFileSystem.getInstance().findFileByIoFile(new File(getTestDataPath() +baseFileNames[0] + ".expected.completion.html")); diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java index d6bbd3ba3722..674ad163c0b2 100644 --- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java +++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java @@ -16,7 +16,6 @@ package com.intellij.psi.impl.source.html.dtd; import com.intellij.psi.PsiElement; -import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.psi.xml.XmlElement; import com.intellij.util.ArrayUtil; import com.intellij.xml.XmlAttributeDescriptor; @@ -94,7 +93,10 @@ public class HtmlAttributeDescriptorImpl extends BasicXmlAttributeDescriptor { } @Override - protected PsiElement getEnumeratedValueDeclaration(XmlAttributeValue attributeValue, String value) { - return super.getEnumeratedValueDeclaration(attributeValue, myCaseSensitive ? value : value.toLowerCase()); + public PsiElement getValueDeclaration(XmlElement attributeValue, String value) { + String s = myCaseSensitive ? value : value.toLowerCase(); + return delegate instanceof BasicXmlAttributeDescriptor ? + ((BasicXmlAttributeDescriptor)delegate).getValueDeclaration(attributeValue, s) : + super.getValueDeclaration(attributeValue, value); } } diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java index 83cf70f5ff37..fba46a2cec3d 100644 --- a/xml/xml-psi-impl/src/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java +++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java @@ -24,17 +24,13 @@ */ package com.intellij.xml.impl; -import com.intellij.openapi.util.Comparing; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiReference; -import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.psi.xml.XmlElement; import com.intellij.util.ArrayUtilRt; -import com.intellij.xml.util.XmlAttributeValueReference; import com.intellij.xml.XmlAttributeDescriptor; import org.jetbrains.annotations.Nullable; -public abstract class BasicXmlAttributeDescriptor implements XmlAttributeDescriptor { +public abstract class BasicXmlAttributeDescriptor extends XmlEnumerationDescriptor implements XmlAttributeDescriptor { public String validateValue(XmlElement context, String value) { return null; } @@ -48,24 +44,12 @@ public abstract class BasicXmlAttributeDescriptor implements XmlAttributeDescrip return getEnumeratedValues(); } - public boolean isEnumerated(@Nullable XmlElement context) { - return isEnumerated(); - } - @Override public String toString() { return getName(); } - public PsiElement getValueDeclaration(XmlAttributeValue attributeValue, String value) { - String defaultValue = getDefaultValue(); - if (Comparing.equal(defaultValue, value)) { - return getDefaultValueDeclaration(); - } - return isFixed() ? null : getEnumeratedValueDeclaration(attributeValue, value); - } - - protected PsiElement getEnumeratedValueDeclaration(XmlAttributeValue attributeValue, String value) { + protected PsiElement getEnumeratedValueDeclaration(XmlElement xmlElement, String value) { String[] values = getEnumeratedValues(); if (values == null || values.length == 0) return getDeclaration(); return ArrayUtilRt.find(values, value) != -1 ? getDeclaration() : null; @@ -74,8 +58,4 @@ public abstract class BasicXmlAttributeDescriptor implements XmlAttributeDescrip protected PsiElement getDefaultValueDeclaration() { return getDeclaration(); } - - public PsiReference[] getValueReferences(XmlAttributeValue value) { - return new PsiReference[] { new XmlAttributeValueReference(value, this)}; - } } diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/XmlEnumerationDescriptor.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/XmlEnumerationDescriptor.java new file mode 100644 index 000000000000..bf7b988e899d --- /dev/null +++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/XmlEnumerationDescriptor.java @@ -0,0 +1,38 @@ +package com.intellij.xml.impl; + +import com.intellij.openapi.util.Comparing; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlElement; +import com.intellij.xml.util.XmlEnumeratedValueReference; + +/** + * @author Dmitry Avdeev + * Date: 22.08.13 + */ +public abstract class XmlEnumerationDescriptor { + + public abstract boolean isFixed(); + + public abstract String getDefaultValue(); + + public abstract String[] getEnumeratedValues(); + + public PsiElement getValueDeclaration(XmlElement attributeValue, String value) { + String defaultValue = getDefaultValue(); + if (Comparing.equal(defaultValue, value)) { + return getDefaultValueDeclaration(); + } + return isFixed() ? null : getEnumeratedValueDeclaration(attributeValue, value); + } + + protected abstract PsiElement getEnumeratedValueDeclaration(XmlElement value, String s); + + protected abstract PsiElement getDefaultValueDeclaration(); + + public PsiReference[] getValueReferences(XmlAttributeValue value) { + return new PsiReference[] { new XmlEnumeratedValueReference(value, this)}; + } + +} diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java index 2248f003ab98..84fba9a1f6fc 100644 --- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java +++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java @@ -15,27 +15,24 @@ */ package com.intellij.xml.impl.schema; -import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; import com.intellij.psi.meta.PsiWritableMetaData; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.xml.*; -import com.intellij.util.*; +import com.intellij.psi.xml.XmlElement; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.ArrayUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.xml.XmlAttributeDescriptor; import com.intellij.xml.XmlElementDescriptor; -import com.intellij.xml.impl.BasicXmlAttributeDescriptor; -import com.intellij.xml.util.XmlUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; -import java.util.List; - /** * @author Mike */ -public class XmlAttributeDescriptorImpl extends BasicXmlAttributeDescriptor implements PsiWritableMetaData { +public class XmlAttributeDescriptorImpl extends XsdEnumerationDescriptor implements PsiWritableMetaData, XmlAttributeDescriptor { private XmlTag myTag; String myUse; - private boolean myExhaustiveEnum; @NonNls public static final String REQUIRED_ATTR_VALUE = "required"; @@ -49,7 +46,7 @@ public class XmlAttributeDescriptorImpl extends BasicXmlAttributeDescriptor impl public XmlAttributeDescriptorImpl() {} - public PsiElement getDeclaration(){ + public XmlTag getDeclaration(){ return myTag; } @@ -70,10 +67,6 @@ public class XmlAttributeDescriptorImpl extends BasicXmlAttributeDescriptor impl return REQUIRED_ATTR_VALUE.equals(myUse); } - public boolean isFixed() { - return myTag.getAttributeValue("fixed") != null; - } - private boolean hasSimpleSchemaType(@NonNls String type) { final String attributeValue = getType(); @@ -105,92 +98,14 @@ public class XmlAttributeDescriptorImpl extends BasicXmlAttributeDescriptor impl return hasSimpleSchemaType("IDREF"); } - public String getDefaultValue() { - if (isFixed()) { - return myTag.getAttributeValue("fixed"); - } - - return myTag.getAttributeValue("default"); - } - - public boolean isEnumerated(@Nullable XmlElement context) { - return processEnumeration(context, PairProcessor.TRUE); - } - public boolean isEnumerated() { return isEnumerated(null); } - public String[] getEnumeratedValues() { - return getEnumeratedValues(null); - } - - public String[] getEnumeratedValues(XmlElement context) { - final List<String> list = new SmartList<String>(); - processEnumeration(context, new PairProcessor<PsiElement, String>() { - @Override - public boolean process(PsiElement element, String s) { - list.add(s); - return true; - } - }); - String defaultValue = getDefaultValue(); - if (defaultValue != null) { - list.add(defaultValue); - } - return ArrayUtil.toStringArray(list); - } - - private boolean processEnumeration(XmlElement context, PairProcessor<PsiElement, String> processor) { - XmlTag contextTag = context != null ? PsiTreeUtil.getContextOfType(context, XmlTag.class, true) : null; - final XmlElementDescriptorImpl elementDescriptor = (XmlElementDescriptorImpl)XmlUtil.findXmlDescriptorByType(myTag, contextTag); - - if (elementDescriptor!=null && elementDescriptor.getType() instanceof ComplexTypeDescriptor) { - return processEnumerationImpl(((ComplexTypeDescriptor)elementDescriptor.getType()).getDeclaration(), processor); - } - - final String namespacePrefix = myTag.getNamespacePrefix(); - XmlTag type = myTag.findFirstSubTag( - ((namespacePrefix.length() > 0)?namespacePrefix+":":"")+"simpleType" - ); - - if (type != null) { - return processEnumerationImpl(type, processor); - } - - return false; - } - - private boolean processEnumerationImpl(final XmlTag declaration, final PairProcessor<PsiElement, String> pairProcessor) { - if ("boolean".equals(declaration.getAttributeValue("name"))) { - XmlAttributeValue valueElement = declaration.getAttribute("name").getValueElement(); - pairProcessor.process(valueElement, "true"); - pairProcessor.process(valueElement, "false"); - myExhaustiveEnum = true; - return true; - } - - else { - final Ref<Boolean> found = new Ref<Boolean>(Boolean.FALSE); - myExhaustiveEnum = XmlUtil.processEnumerationValues(declaration, new Processor<XmlTag>() { - @Override - public boolean process(XmlTag tag) { - found.set(Boolean.TRUE); - XmlAttribute name = tag.getAttribute("value"); - return name == null || pairProcessor.process(name.getValueElement(), name.getValue()); - } - }); - return found.get(); - } - } - + @Nullable @Override - public PsiElement getValueDeclaration(XmlAttributeValue attributeValue, String value) { - PsiElement declaration = super.getValueDeclaration(attributeValue, value); - if (declaration == null && !myExhaustiveEnum) { - return getDeclaration(); - } - return declaration; + public String validateValue(XmlElement context, String value) { + return null; } public String getName(PsiElement context) { @@ -246,20 +161,4 @@ public class XmlAttributeDescriptorImpl extends BasicXmlAttributeDescriptor impl public void setName(String name) throws IncorrectOperationException { NamedObjectDescriptor.setName(myTag, name); } - - @Override - protected PsiElement getEnumeratedValueDeclaration(XmlAttributeValue attributeValue, final String value) { - final Ref<PsiElement> result = new Ref<PsiElement>(); - processEnumeration(myTag, new PairProcessor<PsiElement, String>() { - @Override - public boolean process(PsiElement element, String s) { - if (value.equals(s)) { - result.set(element); - return false; - } - return true; - } - }); - return result.get(); - } } diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorByType.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorByType.java index 1289008ae75c..5e1bbd182e68 100644 --- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorByType.java +++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorByType.java @@ -39,7 +39,7 @@ public class XmlElementDescriptorByType extends XmlElementDescriptorImpl { public XmlElementDescriptorByType() {} - public PsiElement getDeclaration(){ + public XmlTag getDeclaration(){ return myDescriptorTag; } diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java index 22f37c594056..61c33c09cafc 100644 --- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java +++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java @@ -16,12 +16,9 @@ package com.intellij.xml.impl.schema; import com.intellij.codeInsight.daemon.Validator; -import com.intellij.openapi.util.Key; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.meta.PsiWritableMetaData; -import com.intellij.psi.util.ParameterizedCachedValue; -import com.intellij.psi.util.ParameterizedCachedValueProvider; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.xml.*; import com.intellij.util.ArrayUtil; @@ -39,7 +36,8 @@ import java.util.List; /** * @author Mike */ -public class XmlElementDescriptorImpl implements XmlElementDescriptor, PsiWritableMetaData, Validator<XmlTag>, +public class XmlElementDescriptorImpl extends XsdEnumerationDescriptor + implements XmlElementDescriptor, PsiWritableMetaData, Validator<XmlTag>, XmlElementDescriptorAwareAboutChildren { protected XmlTag myDescriptorTag; protected volatile XmlNSDescriptor NSDescriptor; @@ -51,8 +49,6 @@ public class XmlElementDescriptorImpl implements XmlElementDescriptor, PsiWritab public static final String NONQUALIFIED_ATTR_VALUE = "unqualified"; @NonNls private static final String ELEMENT_FORM_DEFAULT = "elementFormDefault"; - private static final Key<ParameterizedCachedValue<XmlAttributeDescriptor[], XmlTag>> ATTRS_KEY = Key.create("attributes"); - private ParameterizedCachedValueProvider<XmlAttributeDescriptor[],XmlTag> myCachedValueProvider; public XmlElementDescriptorImpl(@Nullable XmlTag descriptorTag) { myDescriptorTag = descriptorTag; @@ -60,7 +56,7 @@ public class XmlElementDescriptorImpl implements XmlElementDescriptor, PsiWritab public XmlElementDescriptorImpl() {} - public PsiElement getDeclaration(){ + public XmlTag getDeclaration(){ return myDescriptorTag; } @@ -395,11 +391,6 @@ public class XmlElementDescriptorImpl implements XmlElementDescriptor, PsiWritab return CONTENT_TYPE_MIXED; } - @Override - public String getDefaultValue() { - return myDescriptorTag.getAttributeValue("default"); - } - @Nullable public XmlElementDescriptor getElementDescriptor(final String name) { final String localName = XmlUtil.findLocalNameByQualifiedName(name); diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XsdEnumerationDescriptor.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XsdEnumerationDescriptor.java new file mode 100644 index 000000000000..0a1c341f6825 --- /dev/null +++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XsdEnumerationDescriptor.java @@ -0,0 +1,139 @@ +package com.intellij.xml.impl.schema; + +import com.intellij.openapi.util.Ref; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlElement; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.ArrayUtil; +import com.intellij.util.PairProcessor; +import com.intellij.util.Processor; +import com.intellij.util.SmartList; +import com.intellij.xml.impl.XmlEnumerationDescriptor; +import com.intellij.xml.util.XmlUtil; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * @author Dmitry Avdeev + * Date: 22.08.13 + */ +public abstract class XsdEnumerationDescriptor extends XmlEnumerationDescriptor { + + private boolean myExhaustiveEnum; + + public abstract XmlTag getDeclaration(); + + public String getDefaultValue() { + if (isFixed()) { + return getDeclaration().getAttributeValue("fixed"); + } + + return getDeclaration().getAttributeValue("default"); + } + + public boolean isFixed() { + return getDeclaration().getAttributeValue("fixed") != null; + } + + public String[] getEnumeratedValues() { + return getEnumeratedValues(null); + } + + public String[] getEnumeratedValues(XmlElement context) { + final List<String> list = new SmartList<String>(); + processEnumeration(context, new PairProcessor<PsiElement, String>() { + @Override + public boolean process(PsiElement element, String s) { + list.add(s); + return true; + } + }); + String defaultValue = getDefaultValue(); + if (defaultValue != null) { + list.add(defaultValue); + } + return ArrayUtil.toStringArray(list); + } + + private boolean processEnumeration(XmlElement context, PairProcessor<PsiElement, String> processor) { + XmlTag contextTag = context != null ? PsiTreeUtil.getContextOfType(context, XmlTag.class, true) : null; + final XmlElementDescriptorImpl elementDescriptor = (XmlElementDescriptorImpl)XmlUtil.findXmlDescriptorByType(getDeclaration(), contextTag); + + if (elementDescriptor!=null && elementDescriptor.getType() instanceof ComplexTypeDescriptor) { + return processEnumerationImpl(((ComplexTypeDescriptor)elementDescriptor.getType()).getDeclaration(), processor); + } + + final String namespacePrefix = getDeclaration().getNamespacePrefix(); + XmlTag type = getDeclaration().findFirstSubTag( + ((namespacePrefix.length() > 0) ? namespacePrefix + ":" : "") + "simpleType" + ); + + if (type != null) { + return processEnumerationImpl(type, processor); + } + + return false; + } + + private boolean processEnumerationImpl(final XmlTag declaration, final PairProcessor<PsiElement, String> pairProcessor) { + if ("boolean".equals(declaration.getAttributeValue("name"))) { + XmlAttributeValue valueElement = declaration.getAttribute("name").getValueElement(); + pairProcessor.process(valueElement, "true"); + pairProcessor.process(valueElement, "false"); + myExhaustiveEnum = true; + return true; + } + + else { + final Ref<Boolean> found = new Ref<Boolean>(Boolean.FALSE); + myExhaustiveEnum = XmlUtil.processEnumerationValues(declaration, new Processor<XmlTag>() { + @Override + public boolean process(XmlTag tag) { + found.set(Boolean.TRUE); + XmlAttribute name = tag.getAttribute("value"); + return name == null || pairProcessor.process(tag, name.getValue()); + } + }); + return found.get(); + } + } + + @Override + public PsiElement getValueDeclaration(XmlElement attributeValue, String value) { + PsiElement declaration = super.getValueDeclaration(attributeValue, value); + if (declaration == null && !myExhaustiveEnum) { + return getDeclaration(); + } + return declaration; + } + + + public boolean isEnumerated(@Nullable XmlElement context) { + return processEnumeration(context, PairProcessor.TRUE); + } + + @Override + public PsiElement getEnumeratedValueDeclaration(XmlElement xmlElement, final String value) { + final Ref<PsiElement> result = new Ref<PsiElement>(); + processEnumeration(getDeclaration(), new PairProcessor<PsiElement, String>() { + @Override + public boolean process(PsiElement element, String s) { + if (value.equals(s)) { + result.set(element); + return false; + } + return true; + } + }); + return result.get(); + } + + @Override + protected PsiElement getDefaultValueDeclaration() { + return getDeclaration(); + } +} diff --git a/xml/xml-psi-impl/src/com/intellij/xml/util/XmlAttributeValueReference.java b/xml/xml-psi-impl/src/com/intellij/xml/util/XmlEnumeratedValueReference.java index 75a604b520c8..5cf994a2deac 100644 --- a/xml/xml-psi-impl/src/com/intellij/xml/util/XmlAttributeValueReference.java +++ b/xml/xml-psi-impl/src/com/intellij/xml/util/XmlEnumeratedValueReference.java @@ -17,13 +17,11 @@ package com.intellij.xml.util; import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider; import com.intellij.codeInsight.daemon.XmlErrorMessages; -import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReferenceBase; import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.util.ArrayUtil; -import com.intellij.xml.XmlAttributeDescriptor; -import com.intellij.xml.impl.BasicXmlAttributeDescriptor; +import com.intellij.xml.impl.XmlEnumerationDescriptor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,25 +29,18 @@ import org.jetbrains.annotations.Nullable; * @author Dmitry Avdeev * Date: 16.08.13 */ -public class XmlAttributeValueReference extends PsiReferenceBase<XmlAttributeValue> implements EmptyResolveMessageProvider { - private final XmlAttributeDescriptor myDescriptor; +public class XmlEnumeratedValueReference extends PsiReferenceBase<XmlAttributeValue> implements EmptyResolveMessageProvider { + private final XmlEnumerationDescriptor myDescriptor; - public XmlAttributeValueReference(XmlAttributeValue value, XmlAttributeDescriptor descriptor) { + public XmlEnumeratedValueReference(XmlAttributeValue value, XmlEnumerationDescriptor descriptor) { super(value); myDescriptor = descriptor; } - public XmlAttributeValueReference(XmlAttributeValue element, - TextRange range, - XmlAttributeDescriptor descriptor) { - super(element, range); - myDescriptor = descriptor; - } - @Nullable @Override public PsiElement resolve() { - return ((BasicXmlAttributeDescriptor)myDescriptor).getValueDeclaration(getElement(), getValue()); + return myDescriptor.getValueDeclaration(getElement(), getValue()); } @NotNull |