summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2014-01-27 09:36:41 -0800
committerTor Norbye <tnorbye@google.com>2014-01-27 09:36:49 -0800
commit809cb3e73653399e59e45e0b10749a8e37b85a75 (patch)
tree8aa7262925cc4eed902baa00f2193e98f6bb64e0 /plugins
parente2d6089d43d7ac1f62bafe06638d5ac2c21f5283 (diff)
downloadidea-809cb3e73653399e59e45e0b10749a8e37b85a75.tar.gz
Snapshot 9e6329d622cc9649c9c035f28faddc29564a5b7a from idea/133.696 of git://git.jetbrains.org/idea/community.git
9e6329d: IDEA-119035 Select All shortcut for any table on mac with Darcula 7642139: [log] IDEA-116322 Fix structure filter for multiple roots 5fe2227: [log] refactor: group filters before passing them to providers a9bda1e: Problem with several users in log filter fixed. bb353f3: [log] IDEA-119316 Fix "go to commit" if there are log filters 2825dd1: IDEA-119467 Gradle: auto discovery of buildSrc project (cherry picked from commit 3cb5420) ca05350: Gradle: respect the order of dependencies (cherry picked from commit dca7107) 8a1d099: IDEA-115351 Idea UI hangs after performing Move Module to group (cherry picked from commit 673ed61) [r=Maxim.Mossienko] 9f006a4: NPE fix (cherry picked from commit 1eb3644) 2089b40: Gradle: test data fix (cherry picked from commit c864c4b) 6208324: IDEA-119336 Gradle build files: build.gradle scripts are checkout from Perforce even if the file is not changed (cherry picked from commit 3234c0b) d1d776c: IDEA-119467 Gradle: auto discovery of buildSrc project IDEA-98930 IDEA does not resolve dependencies in Gradle buildSrc/ project (cherry picked from commit 0982afc) 6f6c403: Gradle: dependencies scope merge and sourceSets type handling updated related issues: IDEA-119365 Gradle import does not respect model customisations IDEA-118280 Gradle import: IDEA detect java folder as a resource folder IDEA-117668 IDEA v13 spontaneously changes additional test source root to source root (cherry picked from commit 68bfa5e) a7f9d6f: Gradle: respect module build classpath for build scripts resolving review: http://crucible.labs.intellij.net/cru/CR-IC-4038 742c670: isEAP = false, time to release 13.0.2 3a5cfc7: add profiling parameters to the right part of the classpath (has been broken after Launcher was introduced) ca42a66: fixed empty headers and import (dependant in language level) for qt, gtk... skeletons. ba68876: update copyright in artworks 7c12cb3: IDEA-119619 Settings / Language Injections: project level XML tag injection loses Sub-Tags value on IDE restart f7bd727: don't call robot on alt on Windows and when window is inactive (cherry picked from commit 0fe2cac) 8b62b1e: add WinXP definition (cherry picked from commit dde1494) 62c528a: consume Alt events on WinXP in default handler to avoid WindowsRootPaneUI.AltProcessor (cherry picked from commit f14aab9) 20c7faa: support table decoration on IntelliJ laf (cherry picked from commit 04425c9) 7dc2f34: IDEA-118211 (cherry picked from commit 55ee980) [r=Peter.Gromov] b15f65d: fixed PY-11823 Test Runner detection in settings doesn't pick up just installed test runner 7a2bec9: Fixed dedent in case of tabs ( PY-10120). 56b5f81: Python keywords extracted. Cleanup. f195253: Fixed test data to satisfy PEP8. 6b6bbc1: Make right par indent=none in import statement (PY-9075). 6a39911: Make continuation indent after continuation in indenting statement (PY-9573). cf19307: Test for PY-9573 fb5186fa: Handle 'mode' as a keyword argument to open() as well 27a4d26: Detect text or binary I/O in pathlib.Path.open() a5600e3: Return instance types for instance types of superclasses f56e9b1: fixed PY-11837 nose test runner errors while formatting a test error 7420dd6: Nullity annotations 97ffd71: fixed test data d0eb725: fixed test data 326185d: generator: do not drop the whole module in case there are broken __repr__ defined 982687a: performance for generator: Split big generated modules (like _Gtk, PyQt) into smaller ones af679a5: Simplified always true condition 3174b9c: Extracted PyClassTypeImpl.findProperty() 777280e: Added 'inherited' parameter to PyClass.findProperty() d5d8b23: Python skeletons class members provider now can provide new overridden members 6775ed3: Fixed code insight for returning 'self' in base class methods (PY-10977, PY-11413) d4c641f: Fix formatter to add two blank lines between declarations with comment (PY-9923). 9c8134a: add field after super call 37813c6: Revert "Detect SQL fragments only in the beginning of string literals" (PY-11828) 9d5973f: Use default charset as python console encoding. 7fed382: Added Python 3.4 modules to the stdlib modules list c772246: Don't ignore unused attributes of empty constructors (PY-7527) 91ae6bf: Fixed NPE in PyUnusedLocalInspectionVisitor.visitPyCallExpression() 464ae1c: fixed PY-11800 Parameter unfilled false positive for decorators with '*' arguments. e3ec532: fixed test data 31bb1dd: fixed add field declaration to the beginning of __init__ 2910f7d: fixed EA-52897 - CCE: ImportToggleAliasIntention$.execute cca9133: fixed EA-53046 - NPE: PyExtractMethodUtil.a 2fcf769: fixed quickdoc test fcf329f: fixed editing test 859c599: fixed testdata ab7782a: fixed PY-11765 @ivar and @type in class documentation cause PyUnresolvedReferences inspection to file 8303e4f: IDEA-112303 Tool Windows Quick Access button: impossible to select item in list by mouse (cherry picked from commit 8e2ce03) b206d2d: fix NPE d923a83: Trying to fix EA-51665 - assert: FTManager.createAndStoreBundledTemplate (cherry picked from commit 47dee08) +review CR-IC 72fa58b: Add additional diagnostic to investigate EA-51665 (assert: FTManager.createAndStoreBundledTemplate). (cherry picked from commit a5e4cf4) +review CR-IC 6548f1a: java: incorrect parsing of bounds in class files fixed 8f5b22c: EA-42899 - CCE: XmlLanguageInjectionSupport.doEditInjection & cleanup 2a882e0: EA-53406 - IAE: ServiceManager.getService ed41c77: WI-13685 PhpStorm doesn't save project name CR-PS-181 2c3ccec: IDEA-119445 Remove first slash in "copy reference" (cherry picked from commit 298bb04) 50bf901: IDEA-119153 file search too wide for users folder (cherry picked from commit 37521f0) 8ab790b: IDEA-119470 File and code templates: changes gone when switching tabs (cherry picked from commit 21cdea3) 7402508: EA-53393 - IOOBE: DomAnchorImpl.createAnchor (missing cherry pick) f6ab2da: Bug fix: IDEA incorrect handle escaping. c78400d: IDEA-105253 Missing icon for Thread dumps view 21b6f91: IDEA-104735 Dracula: INVALID string have not dracula style red color (cherry picked from commit 4a5e793) 53885c2: Don't show active editor in recent files 6cf74eb: IDEA-104706 Remove currently active file from "Recent Files" popup (cherry pick from master) ffef358: IDEA-119406 IDEA make corrupts files when performing Maven resource filtering (default value of escapeString is null) b8e9ab1: IDEA-119406 IDEA make corrupts files when performing Maven resource filtering (cherry picked from commit 5b6b3f6) +review CR-IC d3dd646: EA-53308 - CCE: DfaVariableValue.<init> (cherry picked from commit 32a579d) 10f83e0: external build for artifacts: added API to filter contents of directory extracted from jar file [rev by Michael Golubev] b7f4af0: make nonDefaultProject="true" really work 0bebc13: cosmetics 94e0a24: Merge remote-tracking branch 'origin/133' into 133 85cae29: IDEA-119347 ../jre64 JDK not being picked up by idea64.exe 2dd77af: IDEA-117127 Editor: Throwable on Select word at caret inside plain text (cherry picked from commit 2e3a0d8) 0a5e3ad: IDEA-117555 Search everywhere dialog is being closed immediately (cherry picked from commit ba8037d) 520da57: fix getDisplayName nullability assertion 0663734: IDEA-111122 remove attached jar artifact coming from "apklib" dependency from the dependencies of app module: users add it to deploy jar to Maven repository in addition to "apklib" file, but we don't need to add it to the classpath, because it leads to class duplication [rev=sergey.evdokimov] c1fb468: IDEA-79522 need ability to set display names for xml attribute and xml tag language injections 3ae70b9: IDEA-119163 "Language Injections" settings should use toolbar decorator in the same way as other 50c78e9: IDEA-117327 Add a setting to switch off autopopup completion item selection by Enter (cherry picked from commit 84ddafc) ae5ce9b: groovy debugging agent that produces less garbage (cherry picked from commit c7af9fe) f6682f7: Roll-back FileChooserDescriptor API change. 1c64249: Merge remote-tracking branch 'origin/133' into 133 b293f8c: SearchEverywhere doesn't work on Linux 07b98c1: IDEA-74428 Ability to turn on log debug categories from the GUI 4257f6f: CR-IU-511 make abstract class abstract & leave getPresentableText mandatory 7cac7b7: allow to turn off suggestion to create a file when creating a directory with file-like name (IDEA-118250) (cherry picked from commit 5d81e8d) acb9db2: don't show parameter info for invisible editors (EA-53161 - NPE: ParameterInfoComponent.<init>) (cherry picked from commit fb24d98) e6bfbbf: the users don't care if we're preparing editors to open (IDEA-115130) (cherry picked from commit 9a116de) 3f1ebf3: rethrow PCE from KeyedExtensionFactory reflection (cherry picked from commit df8967b) Change-Id: I8083d21f3faff4f899c53a5dea2710713dc1a2a9
Diffstat (limited to 'plugins')
-rw-r--r--plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.form27
-rw-r--r--plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.java26
-rw-r--r--plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/MethodParameterInjectionConfigurable.java34
-rw-r--r--plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java29
-rw-r--r--plugins/IntelliLang/src/META-INF/plugin.xml2
-rw-r--r--plugins/IntelliLang/src/org/intellij/plugins/intelliLang/InjectionsSettingsUI.java181
-rw-r--r--plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java7
-rw-r--r--plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java4
-rw-r--r--plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/BaseInjection.java5
-rw-r--r--plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AbstractInjectionPanel.java24
-rw-r--r--plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedPanel.form4
-rw-r--r--plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/BaseInjectionPanel.form4
-rw-r--r--plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/LanguagePanel.form11
-rw-r--r--plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/configurables/InjectionConfigurable.java85
-rw-r--r--plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java38
-rw-r--r--plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlAttributeInjection.java23
-rw-r--r--plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlTagInjection.java4
-rw-r--r--plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedXmlPanel.form15
-rw-r--r--plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.form35
-rw-r--r--plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.java20
-rw-r--r--plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.form43
-rw-r--r--plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.java22
-rw-r--r--plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.form39
-rw-r--r--plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.java14
-rw-r--r--plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/XmlAttributeInjectionConfigurable.java34
-rw-r--r--plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/XmlTagInjectionConfigurable.java34
-rw-r--r--plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java53
-rw-r--r--plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java6
-rw-r--r--plugins/git4idea/src/git4idea/log/GitLogProvider.java22
-rw-r--r--plugins/gradle/src/META-INF/plugin.xml2
-rw-r--r--plugins/gradle/src/META-INF/services/org.jetbrains.plugins.gradle.model.ModelBuilderService1
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleClassFinder.java34
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java52
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/maven/ImportMavenRepositoriesTask.java7
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/model/BuildScriptClasspathModel.java28
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/model/ClasspathEntryModel.java36
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleDependencyScope.java13
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelBuildScriptClasspathBuilderImpl.java93
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java46
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImpl.java102
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/BuildScriptClasspathData.java49
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/ClasspathEntry.java84
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/BuildScriptClasspathModelImpl.java47
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/ClasspathEntryModelImpl.java60
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/buildSrcInit.gradle25
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle4
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleBuildClasspathManager.java111
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java108
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java29
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java28
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java113
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleStartupActivity.java6
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/BuildClasspathModuleGradleDataService.java161
-rw-r--r--plugins/gradle/testData/testAddMavenDependencyInEmptyFile.gradle1
-rw-r--r--plugins/gradle/testData/testAddMavenDependencyInEmptyFile_after.gradle1
-rw-r--r--plugins/gradle/testData/testDefaultDependenciesModel/build.gradle4
-rw-r--r--plugins/gradle/testData/testDefaultDependenciesModel/settings.gradle5
-rw-r--r--plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle21
-rw-r--r--plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle3
-rw-r--r--plugins/gradle/testData/testGradleSourcesSetsInterpretation/build.gradle74
-rw-r--r--plugins/gradle/testData/testGradleSourcesSetsInterpretation/settings.gradle8
-rw-r--r--plugins/gradle/testData/testModelBuildScriptClasspathBuilder/build.gradle9
-rw-r--r--plugins/gradle/testData/testModelBuildScriptClasspathBuilder/settings.gradle4
-rw-r--r--plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java2
-rw-r--r--plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelBuildScriptClasspathBuilderImplTest.java78
-rw-r--r--plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImplTest.java134
-rw-r--r--plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImplTest.java177
-rw-r--r--plugins/groovy/hotswap/agentSrc/org/groovy/debug/hotswap/ResetAgent.java39
-rw-r--r--plugins/groovy/hotswap/gragent.jarbin49320 -> 49431 bytes
-rw-r--r--plugins/groovy/resources/fileTemplates/code/Spock_SetUp_Method.groovy.ft (renamed from plugins/groovy/resources/fileTemplates/code/Spock SetUp Method.groovy.ft)0
-rw-r--r--plugins/groovy/resources/fileTemplates/code/Spock_SetUp_Method.groovy.html (renamed from plugins/groovy/resources/fileTemplates/code/Spock SetUp Method.groovy.html)0
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/navbar/GrNavBarModelExtension.java7
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockTestFramework.java2
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java45
-rw-r--r--plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenResourcesBuilder.java40
-rw-r--r--plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java2
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/compiler/MavenResourceCompiler.java9
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java2
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java12
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java2
-rw-r--r--plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java21
81 files changed, 2021 insertions, 765 deletions
diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.form b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.form
index b77dd37c29d0..62fdc0efa396 100644
--- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.form
+++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.form
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.plugins.intelliLang.inject.config.ui.MethodParameterPanel">
- <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <xy x="20" y="20" width="500" height="400"/>
+ <xy x="20" y="20" width="500" height="697"/>
</constraints>
<properties/>
<border type="none"/>
@@ -13,16 +13,16 @@
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
- <grid id="84778" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="84778" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="0" vgap="0">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<clientProperties>
- <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
+ <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithoutIndent"/>
</clientProperties>
- <border type="none" title="Class-Name"/>
+ <border type="none" title="Class Methods"/>
<children>
<grid id="5081f" binding="myClassPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
@@ -32,22 +32,9 @@
<border type="none"/>
<children/>
</grid>
- </children>
- </grid>
- <grid id="b75a2" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
- <margin top="0" left="0" bottom="0" right="0"/>
- <constraints>
- <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties/>
- <clientProperties>
- <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithoutIndent"/>
- </clientProperties>
- <border type="none" title="Parameters"/>
- <children>
<scrollpane id="5dfaa" class="com.intellij.ui.components.JBScrollPane">
<constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -62,7 +49,7 @@
</grid>
<nested-form id="b6e0b" form-file="org/intellij/plugins/intelliLang/inject/config/ui/AdvancedPanel.form" binding="myAdvancedPanel" custom-create="true">
<constraints>
- <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
</children>
diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.java
index 36da2a930603..0c1cf6408c26 100644
--- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.java
+++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.java
@@ -28,6 +28,7 @@ import com.intellij.openapi.util.Condition;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.psi.util.PsiFormatUtilBase;
import com.intellij.ui.*;
import com.intellij.ui.dualView.TreeTableView;
import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns;
@@ -42,6 +43,7 @@ import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.intellij.plugins.intelliLang.inject.config.MethodParameterInjection;
import org.intellij.plugins.intelliLang.util.PsiUtilEx;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -91,23 +93,23 @@ public class MethodParameterPanel extends AbstractInjectionPanel<MethodParameter
myParamsTable.getTree().setShowsRootHandles(true);
myParamsTable.getTree().setCellRenderer(new ColoredTreeCellRenderer() {
- public void customizeCellRenderer(final JTree tree,
- final Object value,
- final boolean selected,
- final boolean expanded,
- final boolean leaf,
- final int row,
- final boolean hasFocus) {
+ public void customizeCellRenderer(@NotNull JTree tree,
+ Object value,
+ boolean selected,
+ boolean expanded,
+ boolean leaf,
+ int row,
+ boolean hasFocus) {
final Object o = ((DefaultMutableTreeNode)value).getUserObject();
setIcon(o instanceof PsiMethod ? PlatformIcons.METHOD_ICON : o instanceof PsiParameter ? PlatformIcons.PARAMETER_ICON : null);
final String name;
if (o instanceof PsiMethod) {
- name = PsiFormatUtil.formatMethod((PsiMethod)o, PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS,
- PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE);
+ name = PsiFormatUtil.formatMethod((PsiMethod)o, PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS,
+ PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_TYPE);
}
else if (o instanceof PsiParameter) {
- name = PsiFormatUtil.formatVariable((PsiParameter)o, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE, PsiSubstitutor.EMPTY);
+ name = PsiFormatUtil.formatVariable((PsiParameter)o, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_TYPE, PsiSubstitutor.EMPTY);
}
else name = null;
final boolean missing = o instanceof PsiElement && !((PsiElement)o).isPhysical();
@@ -362,7 +364,7 @@ public class MethodParameterPanel extends AbstractInjectionPanel<MethodParameter
return valueOf(o) != null;
}
- }, new TreeColumnInfo("Method/Parameters")
+ }, new TreeColumnInfo(" ")
};
}
@@ -386,7 +388,7 @@ public class MethodParameterPanel extends AbstractInjectionPanel<MethodParameter
}
}
- private class MyView extends TreeTableView implements TypeSafeDataProvider {
+ private static class MyView extends TreeTableView implements TypeSafeDataProvider {
public MyView(ListTreeTableModelOnColumns treeTableModel) {
super(treeTableModel);
}
diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/MethodParameterInjectionConfigurable.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/MethodParameterInjectionConfigurable.java
deleted file mode 100644
index 1b14fc204eca..000000000000
--- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/MethodParameterInjectionConfigurable.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2006 Sascha Weinreuter
- *
- * 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.intellij.plugins.intelliLang.inject.config.ui.configurables;
-
-import com.intellij.openapi.project.Project;
-import org.intellij.plugins.intelliLang.inject.config.MethodParameterInjection;
-import org.intellij.plugins.intelliLang.inject.config.ui.MethodParameterPanel;
-
-public class MethodParameterInjectionConfigurable extends InjectionConfigurable<MethodParameterInjection, MethodParameterPanel> {
- public MethodParameterInjectionConfigurable(MethodParameterInjection injection, Runnable treeUpdater, Project project) {
- super(injection, treeUpdater, project);
- }
-
- protected MethodParameterPanel createOptionsPanelImpl() {
- return new MethodParameterPanel(myInjection, myProject);
- }
-
- public String getBannerSlogan() {
- return "Edit Method Parameter Injection";
- }
-}
diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java
index 99a3ccd21eab..14c7535f8044 100644
--- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java
+++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java
@@ -55,7 +55,6 @@ import org.intellij.plugins.intelliLang.inject.config.InjectionPlace;
import org.intellij.plugins.intelliLang.inject.config.MethodParameterInjection;
import org.intellij.plugins.intelliLang.inject.config.ui.AbstractInjectionPanel;
import org.intellij.plugins.intelliLang.inject.config.ui.MethodParameterPanel;
-import org.intellij.plugins.intelliLang.inject.config.ui.configurables.MethodParameterInjectionConfigurable;
import org.intellij.plugins.intelliLang.util.ContextComputationProcessor;
import org.intellij.plugins.intelliLang.util.PsiUtilEx;
import org.jdom.Element;
@@ -175,10 +174,7 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo
}
public BaseInjection createInjection(final Element element) {
- if (element.getName().equals(MethodParameterInjection.class.getSimpleName())) {
- return new MethodParameterInjection();
- }
- else return new BaseInjection(JAVA_SUPPORT_ID);
+ return new BaseInjection(JAVA_SUPPORT_ID);
}
private static boolean doInjectInJava(final Project project,
@@ -371,16 +367,21 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo
originalCopy.setPlaceEnabled(currentPlace.getText(), true);
methodParameterInjection = createFrom(project, originalCopy, contextMethod, false);
}
- if (InjectLanguageAction.doEditConfigurable(project, new MethodParameterInjectionConfigurable(methodParameterInjection, null, project))) {
- final BaseInjection newInjection = new BaseInjection(methodParameterInjection.getSupportId()).copyFrom(methodParameterInjection);
- if (originalInjection != null) {
- newInjection.mergeOriginalPlacesFrom(originalInjection, true);
- }
- configuration.replaceInjectionsWithUndo(
- project, Collections.singletonList(newInjection),
- ContainerUtil.createMaybeSingletonList(originalInjection),
- Collections.<PsiElement>emptyList());
+ mergePlacesAndAddToConfiguration(project, configuration, methodParameterInjection, originalInjection);
+ }
+
+ private static void mergePlacesAndAddToConfiguration(@NotNull Project project,
+ @NotNull Configuration configuration,
+ @NotNull MethodParameterInjection injection,
+ @Nullable BaseInjection originalInjection) {
+ BaseInjection newInjection = new BaseInjection(injection.getSupportId()).copyFrom(injection);
+ if (originalInjection != null) {
+ newInjection.mergeOriginalPlacesFrom(originalInjection, true);
}
+ configuration.replaceInjectionsWithUndo(
+ project, Collections.singletonList(newInjection),
+ ContainerUtil.createMaybeSingletonList(originalInjection),
+ Collections.<PsiElement>emptyList());
}
private static void collectInjections(PsiLiteralExpression host,
diff --git a/plugins/IntelliLang/src/META-INF/plugin.xml b/plugins/IntelliLang/src/META-INF/plugin.xml
index 8dad5cb4e41a..975422e0fdfc 100644
--- a/plugins/IntelliLang/src/META-INF/plugin.xml
+++ b/plugins/IntelliLang/src/META-INF/plugin.xml
@@ -36,7 +36,7 @@
<highlightErrorFilter implementation="org.intellij.plugins.intelliLang.inject.FrankensteinErrorFilter"/>
<daemon.highlightInfoFilter implementation="org.intellij.plugins.intelliLang.inject.FrankensteinErrorFilter"/>
- <projectConfigurable instance="org.intellij.plugins.intelliLang.InjectionsSettingsUI" nonDefaultProject="true"/>
+ <projectConfigurable displayName="Language Injections" instance="org.intellij.plugins.intelliLang.InjectionsSettingsUI" nonDefaultProject="true"/>
<multiHostInjector implementation="org.intellij.plugins.intelliLang.inject.CommentLanguageInjector"/>
<multiHostInjector implementation="org.intellij.plugins.intelliLang.inject.TemporaryPlacesInjector"/>
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/InjectionsSettingsUI.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/InjectionsSettingsUI.java
index 414500ba2096..a0420939dfdc 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/InjectionsSettingsUI.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/InjectionsSettingsUI.java
@@ -30,6 +30,7 @@ import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.SplitterProportionsData;
@@ -47,7 +48,6 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ListTableModel;
-import gnu.trove.THashMap;
import gnu.trove.THashSet;
import gnu.trove.TObjectHashingStrategy;
import org.intellij.plugins.intelliLang.inject.AbstractLanguageInjectionSupport;
@@ -81,19 +81,14 @@ public class InjectionsSettingsUI implements SearchableConfigurable.Parent, Conf
private final JPanel myRoot;
private final InjectionsTable myInjectionsTable;
- private final Map<String, LanguageInjectionSupport> mySupports = new THashMap<String, LanguageInjectionSupport>();
- private final Map<String, AnAction> myEditActions = new THashMap<String, AnAction>();
- private final List<AnAction> myAddActions = new ArrayList<AnAction>();
- private final ActionToolbar myToolbar;
+ private final Map<String, LanguageInjectionSupport> mySupports = ContainerUtil.newLinkedHashMap();
+ private final Map<String, AnAction> myEditActions = ContainerUtil.newLinkedHashMap();
+ private final List<AnAction> myAddActions = ContainerUtil.newArrayList();
private final JLabel myCountLabel;
private Configurable[] myConfigurables;
private Configuration myConfiguration;
- public InjectionsSettingsUI(final Project project) {
- this(project, Configuration.getProjectInstance(project));
- }
-
public InjectionsSettingsUI(final Project project, final Configuration configuration) {
myProject = project;
myConfiguration = configuration;
@@ -107,16 +102,12 @@ public class InjectionsSettingsUI implements SearchableConfigurable.Parent, Conf
myInjectionsTable = new InjectionsTable(getInjInfoList(myInfos));
myInjectionsTable.getEmptyText().setText("No injections configured");
- final JPanel tablePanel = new JPanel(new BorderLayout());
-
- tablePanel.add(ScrollPaneFactory.createScrollPane(myInjectionsTable), BorderLayout.CENTER);
- final DefaultActionGroup group = createActions();
+ ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myInjectionsTable);
+ createActions(decorator);
- myToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true);
- myToolbar.setTargetComponent(myInjectionsTable);
- myRoot.add(myToolbar.getComponent(), BorderLayout.NORTH);
- myRoot.add(tablePanel, BorderLayout.CENTER);
+ //myRoot.add(new TitledSeparator("Languages injection places"), BorderLayout.NORTH);
+ myRoot.add(decorator.createPanel(), BorderLayout.CENTER);
myCountLabel = new JLabel();
myCountLabel.setHorizontalAlignment(SwingConstants.RIGHT);
myCountLabel.setForeground(SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES.getFgColor());
@@ -124,7 +115,7 @@ public class InjectionsSettingsUI implements SearchableConfigurable.Parent, Conf
updateCountLabel();
}
- private DefaultActionGroup createActions() {
+ private void createActions(ToolbarDecorator decorator) {
final Consumer<BaseInjection> consumer = new Consumer<BaseInjection>() {
public void consume(final BaseInjection injection) {
addInjection(injection);
@@ -148,22 +139,22 @@ public class InjectionsSettingsUI implements SearchableConfigurable.Parent, Conf
return Comparing.compare(o1.getTemplatePresentation().getText(), o2.getTemplatePresentation().getText());
}
});
-
- final DefaultActionGroup group = new DefaultActionGroup();
- final AnAction addAction = new AnAction("Add", "Add", IconUtil.getAddIcon()) {
+ decorator.disableUpDownActions();
+ decorator.setAddActionUpdater(new AnActionButtonUpdater() {
@Override
- public void update(final AnActionEvent e) {
- e.getPresentation().setEnabled(!myAddActions.isEmpty());
+ public boolean isEnabled(AnActionEvent e) {
+ return !myAddActions.isEmpty();
}
-
+ });
+ decorator.setAddAction(new AnActionButtonRunnable() {
@Override
- public void actionPerformed(final AnActionEvent e) {
- performAdd(e);
+ public void run(AnActionButton button) {
+ performAdd(button);
}
- };
- final AnAction removeAction = new AnAction("Remove", "Remove", PlatformIcons.DELETE_ICON) {
+ });
+ decorator.setRemoveActionUpdater(new AnActionButtonUpdater() {
@Override
- public void update(final AnActionEvent e) {
+ public boolean isEnabled(AnActionEvent e) {
boolean enabled = false;
for (InjInfo info : getSelectedInjections()) {
if (!info.bundled) {
@@ -171,69 +162,63 @@ public class InjectionsSettingsUI implements SearchableConfigurable.Parent, Conf
break;
}
}
- e.getPresentation().setEnabled(enabled);
+ return enabled;
}
-
+ });
+ decorator.setRemoveAction(new AnActionButtonRunnable() {
@Override
- public void actionPerformed(final AnActionEvent e) {
+ public void run(AnActionButton button) {
performRemove();
}
- };
+ });
- final AnAction editAction = new AnAction("Edit", "Edit", PlatformIcons.PROPERTIES_ICON) {
+ decorator.setEditActionUpdater(new AnActionButtonUpdater() {
@Override
- public void update(final AnActionEvent e) {
- final AnAction action = getEditAction();
- e.getPresentation().setEnabled(action != null);
- if (action != null) action.update(e);
+ public boolean isEnabled(AnActionEvent e) {
+ AnAction edit = getEditAction();
+ if (edit != null) edit.update(e);
+ return edit != null && edit.getTemplatePresentation().isEnabled();
}
-
+ });
+ decorator.setEditAction(new AnActionButtonRunnable() {
@Override
- public void actionPerformed(final AnActionEvent e) {
- performEditAction(e);
+ public void run(AnActionButton button) {
+ performEditAction();
}
- };
- final AnAction copyAction = new AnAction("Duplicate", "Duplicate", PlatformIcons.COPY_ICON) {
+ });
+ decorator.addExtraAction(new DumbAwareActionButton("Duplicate", "Duplicate", PlatformIcons.COPY_ICON) {
+
@Override
- public void update(final AnActionEvent e) {
- final AnAction action = getEditAction();
- e.getPresentation().setEnabled(action != null);
- if (action != null) action.update(e);
+ public boolean isEnabled() {
+ return getEditAction() != null;
}
@Override
- public void actionPerformed(final AnActionEvent e) {
+ public void actionPerformed(AnActionEvent e) {
final InjInfo injection = getSelectedInjection();
if (injection != null) {
addInjection(injection.injection.copy());
//performEditAction(e);
}
}
- };
- group.add(addAction);
- group.add(removeAction);
- group.add(copyAction);
- group.add(editAction);
+ });
- addAction.registerCustomShortcutSet(CommonShortcuts.INSERT, myInjectionsTable);
- removeAction.registerCustomShortcutSet(CommonShortcuts.DELETE, myInjectionsTable);
- editAction.registerCustomShortcutSet(CommonShortcuts.ENTER, myInjectionsTable);
+ decorator.addExtraAction(new DumbAwareActionButton("Enable Selected Injections", "Enable Selected Injections", PlatformIcons.SELECT_ALL_ICON) {
- group.addSeparator();
- group.add(new AnAction("Enable Selected Injections", "Enable Selected Injections", PlatformIcons.SELECT_ALL_ICON) {
@Override
public void actionPerformed(final AnActionEvent e) {
performSelectedInjectionsEnabled(true);
}
});
- group.add(new AnAction("Disable Selected Injections", "Disable Selected Injections", PlatformIcons.UNSELECT_ALL_ICON) {
- @Override
- public void actionPerformed(final AnActionEvent e) {
- performSelectedInjectionsEnabled(false);
- }
- });
+ decorator.addExtraAction(new DumbAwareActionButton("Disable Selected Injections", "Disable Selected Injections", PlatformIcons.UNSELECT_ALL_ICON) {
- new AnAction("Toggle") {
+ @Override
+ public void actionPerformed(final AnActionEvent e) {
+ performSelectedInjectionsEnabled(false);
+ }
+ });
+
+ new DumbAwareAction("Toggle") {
@Override
public void update(AnActionEvent e) {
SpeedSearchSupply supply = SpeedSearchSupply.getSupply(myInjectionsTable);
@@ -247,8 +232,18 @@ public class InjectionsSettingsUI implements SearchableConfigurable.Parent, Conf
}.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0)), myInjectionsTable);
if (myInfos.length > 1) {
- group.addSeparator();
- final AnAction shareAction = new AnAction("Make Global", null, PlatformIcons.IMPORT_ICON) {
+ AnActionButton shareAction = new DumbAwareActionButton("Make Global", null, PlatformIcons.IMPORT_ICON) {
+ {
+ addCustomUpdater(new AnActionButtonUpdater() {
+ @Override
+ public boolean isEnabled(AnActionEvent e) {
+ CfgInfo cfg = getTargetCfgInfo(getSelectedInjections());
+ e.getPresentation().setText(cfg == getDefaultCfgInfo() ? "Make Global" : "Move to Project");
+ return cfg != null;
+ }
+ });
+ }
+
@Override
public void actionPerformed(final AnActionEvent e) {
final List<InjInfo> injections = getSelectedInjections();
@@ -265,14 +260,6 @@ public class InjectionsSettingsUI implements SearchableConfigurable.Parent, Conf
TableUtil.selectRows(myInjectionsTable, selectedRows);
}
- @Override
- public void update(final AnActionEvent e) {
- final CfgInfo cfg = getTargetCfgInfo(getSelectedInjections());
- e.getPresentation().setEnabled(cfg != null);
- e.getPresentation().setText(cfg == getDefaultCfgInfo() ? "Make Global" : "Move to Project");
- super.update(e);
- }
-
@Nullable
private CfgInfo getTargetCfgInfo(final List<InjInfo> injections) {
CfgInfo cfg = null;
@@ -283,25 +270,26 @@ public class InjectionsSettingsUI implements SearchableConfigurable.Parent, Conf
if (cfg == null) cfg = info.cfgInfo;
else if (cfg != info.cfgInfo) return info.cfgInfo;
}
- if (cfg == null) return cfg;
+ if (cfg == null) return null;
for (CfgInfo info : myInfos) {
if (info != cfg) return info;
}
throw new AssertionError();
}
};
- shareAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.SHIFT_DOWN_MASK)), myInjectionsTable);
- group.add(shareAction);
+ shareAction.setShortcut(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.SHIFT_DOWN_MASK)));
+ decorator.addExtraAction(shareAction);
}
- group.addSeparator();
- group.add(new AnAction("Import", "Import", AllIcons.Actions.Install) {
+ decorator.addExtraAction(new DumbAwareActionButton("Import", "Import", AllIcons.Actions.Install) {
+
@Override
public void actionPerformed(final AnActionEvent e) {
doImportAction(e.getDataContext());
updateCountLabel();
}
});
- group.add(new AnAction("Export", "Export", AllIcons.Actions.Export) {
+ decorator.addExtraAction(new DumbAwareActionButton("Export", "Export", AllIcons.Actions.Export) {
+
@Override
public void actionPerformed(final AnActionEvent e) {
final List<BaseInjection> injections = getInjectionList(getSelectedInjections());
@@ -321,20 +309,19 @@ public class InjectionsSettingsUI implements SearchableConfigurable.Parent, Conf
}
@Override
- public void update(final AnActionEvent e) {
- e.getPresentation().setEnabled(!getSelectedInjections().isEmpty());
+ public boolean isEnabled() {
+ return !getSelectedInjections().isEmpty();
}
});
-
- return group;
}
- private void performEditAction(AnActionEvent e) {
+ private void performEditAction() {
final AnAction action = getEditAction();
if (action != null) {
final int row = myInjectionsTable.getSelectedRow();
- action.actionPerformed(e);
+ action.actionPerformed(new AnActionEvent(null, DataManager.getInstance().getDataContext(myInjectionsTable),
+ ActionPlaces.UNKNOWN, new Presentation(""), ActionManager.getInstance(), 0));
myInjectionsTable.getListTableModel().fireTableDataChanged();
myInjectionsTable.getSelectionModel().setSelectionInterval(row, row);
updateCountLabel();
@@ -352,10 +339,8 @@ public class InjectionsSettingsUI implements SearchableConfigurable.Parent, Conf
if (place.isEnabled()) enablePlacesCount++;
}
}
- final StringBuilder sb = new StringBuilder();
- sb.append(items.size()).append(" injection").append(items.size() > 1 ? "s" : "").append(" (").append(enablePlacesCount)
- .append(" of ").append(placesCount).append(" place").append(placesCount > 1 ? "s" : "").append(" enabled) ");
- myCountLabel.setText(sb.toString());
+ myCountLabel.setText(items.size() + " injection" + (items.size() > 1 ? "s" : "") + " (" + enablePlacesCount + " of " +
+ placesCount + " place" + (placesCount > 1 ? "s" : "") + " enabled) ");
}
else {
myCountLabel.setText("no injections configured ");
@@ -511,17 +496,14 @@ public class InjectionsSettingsUI implements SearchableConfigurable.Parent, Conf
return row < 0? null : myInjectionsTable.getItems().get(myInjectionsTable.convertRowIndexToModel(row));
}
- private void performAdd(final AnActionEvent e) {
- final DefaultActionGroup group = new DefaultActionGroup();
- for (AnAction action : myAddActions) {
- group.add(action);
- }
+ private void performAdd(AnActionButton e) {
+ DefaultActionGroup group = new DefaultActionGroup(myAddActions);
JBPopupFactory.getInstance().createActionGroupPopup(null, group, e.getDataContext(), JBPopupFactory.ActionSelectionAid.NUMBERING, true, new Runnable() {
public void run() {
updateCountLabel();
}
- }, -1).showUnderneathOf(myToolbar.getComponent());
+ }, -1).show(e.getPreferredPopupPoint());
}
@Nls
@@ -552,8 +534,7 @@ public class InjectionsSettingsUI implements SearchableConfigurable.Parent, Conf
if (row < 0) return false;
if (columnAtPoint(e.getPoint()) <= 0) return false;
myInjectionsTable.getSelectionModel().setSelectionInterval(row, row);
- performEditAction(new AnActionEvent(e, DataManager.getInstance().getDataContext(InjectionsTable.this),
- ActionPlaces.UNKNOWN, new Presentation(""), ActionManager.getInstance(), 0));
+ performEditAction();
return true;
}
}.installOn(this);
@@ -632,7 +613,7 @@ public class InjectionsSettingsUI implements SearchableConfigurable.Parent, Conf
public TableCellRenderer getRenderer(final InjInfo injection) {
return booleanCellRenderer;
}
- }, new ColumnInfo<InjInfo, InjInfo>("Display Name") {
+ }, new ColumnInfo<InjInfo, InjInfo>("Name") {
@Override
public InjInfo valueOf(final InjInfo info) {
return info;
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java
index a18a26b529af..132393737525 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java
@@ -114,12 +114,13 @@ public abstract class AbstractLanguageInjectionSupport extends LanguageInjection
public static AnAction createDefaultAddAction(final Project project,
final Consumer<BaseInjection> consumer,
final AbstractLanguageInjectionSupport support) {
+ final String supportTitle = StringUtil.capitalize(support.getId());
Icon icon = FileTypeManager.getInstance().getFileTypeByExtension(support.getId()).getIcon();
- return new AnAction("Generic "+ StringUtil.capitalize(support.getId()), null, icon) {
+ return new AnAction("Generic "+ supportTitle, null, icon) {
@Override
public void actionPerformed(AnActionEvent e) {
final BaseInjection injection = new BaseInjection(support.getId());
- injection.setDisplayName("New "+ StringUtil.capitalize(support.getId())+" Injection");
+ injection.setDisplayName("New "+ supportTitle +" Injection");
final BaseInjection newInjection = showDefaultInjectionUI(project, injection);
if (newInjection != null) {
consumer.consume(injection);
@@ -134,7 +135,7 @@ public abstract class AbstractLanguageInjectionSupport extends LanguageInjection
panel.reset();
final DialogBuilder builder = new DialogBuilder(project);
LanguageInjectionSupport support = InjectorUtils.findInjectionSupport(injection.getSupportId());
- if (support != null && support instanceof AbstractLanguageInjectionSupport) {
+ if (support instanceof AbstractLanguageInjectionSupport) {
builder.setHelpId(((AbstractLanguageInjectionSupport)support).getHelpId());
}
builder.addOkAction();
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java
index 18f4c0147b12..b03a07de7233 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java
@@ -28,7 +28,6 @@ import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.keymap.KeymapUtil;
-import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
@@ -221,7 +220,4 @@ public class InjectLanguageAction implements IntentionAction {
return false;
}
- public static boolean doEditConfigurable(final Project project, final Configurable configurable) {
- return true; //ShowSettingsUtil.getInstance().editConfigurable(project, configurable);
- }
}
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/BaseInjection.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/BaseInjection.java
index ffd54be5bd67..f5fddc277c04 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/BaseInjection.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/BaseInjection.java
@@ -56,7 +56,8 @@ public class BaseInjection implements Injection, PersistentStateComponent<Elemen
public static final Key<BaseInjection> INJECTION_KEY = Key.create("INJECTION_KEY");
@NotNull private final String mySupportId;
- private String myDisplayName;
+
+ private String myDisplayName = "";
private String myInjectedLanguageId = "";
private String myPrefix = "";
@@ -98,7 +99,7 @@ public class BaseInjection implements Injection, PersistentStateComponent<Elemen
return myDisplayName;
}
- public void setDisplayName(String displayName) {
+ public void setDisplayName(@NotNull String displayName) {
myDisplayName = displayName;
}
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AbstractInjectionPanel.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AbstractInjectionPanel.java
index 2626d4f433ed..9b6fc83533fa 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AbstractInjectionPanel.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AbstractInjectionPanel.java
@@ -15,8 +15,6 @@
*/
package org.intellij.plugins.intelliLang.inject.config.ui;
-import com.intellij.openapi.editor.event.DocumentAdapter;
-import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.project.Project;
import com.intellij.util.ui.UIUtil;
import org.intellij.plugins.intelliLang.inject.config.BaseInjection;
@@ -73,7 +71,6 @@ public abstract class AbstractInjectionPanel<T extends BaseInjection> implements
final InjectionPanel p = getField(panel);
p.init(copy);
}
- reset();
}
public final boolean isModified() {
@@ -89,23 +86,28 @@ public abstract class AbstractInjectionPanel<T extends BaseInjection> implements
@SuppressWarnings({"unchecked"})
public final void apply() {
- apply(myOrigInjection);
-
for (Field panel : myOtherPanels) {
getField(panel).apply();
}
- myOrigInjection.generatePlaces();
- myEditCopy.copyFrom(myOrigInjection);
+
+ // auto-generated name should go last
+ apply(myOrigInjection);
+ if (!myOtherPanels.isEmpty()) {
+ myOrigInjection.generatePlaces();
+ myEditCopy.copyFrom(myOrigInjection);
+ }
}
protected abstract void apply(T other);
@SuppressWarnings({"unchecked"})
public final void reset() {
+ if (!myOtherPanels.isEmpty()) {
+ myEditCopy.copyFrom(myOrigInjection);
+ }
for (Field panel : myOtherPanels) {
getField(panel).reset();
}
- myEditCopy.copyFrom(myOrigInjection);
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
public void run() {
resetImpl();
@@ -138,10 +140,4 @@ public abstract class AbstractInjectionPanel<T extends BaseInjection> implements
updater.run();
}
}
-
- protected class TreeUpdateListener extends DocumentAdapter {
- public void documentChanged(DocumentEvent e) {
- updateTree();
- }
- }
}
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedPanel.form b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedPanel.form
index a45bfaff44cc..0ac5d480dd01 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedPanel.form
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedPanel.form
@@ -26,7 +26,7 @@
</constraints>
<properties>
<labelFor value="7bf4e"/>
- <text value="&amp;Value Pattern:"/>
+ <text value="&amp;Value pattern:"/>
<toolTipText value="&lt;html&gt;Enter a regular expression that selects the parts of the tag's or attribute's value the language should be injected into.&lt;br&gt;The pattern should contain exactly one capturing group.&lt;/html&gt;"/>
</properties>
</component>
@@ -43,7 +43,7 @@
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
- <text value="&amp;Single File"/>
+ <text value="&amp;Single file"/>
</properties>
</component>
</children>
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/BaseInjectionPanel.form b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/BaseInjectionPanel.form
index 0c9523fbb1ea..79dafacd8fa8 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/BaseInjectionPanel.form
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/BaseInjectionPanel.form
@@ -21,7 +21,7 @@
<clientProperties>
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithoutIndent"/>
</clientProperties>
- <border type="none" title="Places Pattern"/>
+ <border type="none" title="Places Patterns"/>
<children/>
</grid>
<nested-form id="b6e0b" form-file="org/intellij/plugins/intelliLang/inject/config/ui/AdvancedPanel.form" binding="myAdvancedPanel" custom-create="true">
@@ -43,7 +43,7 @@
</constraints>
<properties>
<labelFor value="5916a"/>
- <text value="Display &amp;Name:"/>
+ <text value="&amp;Name:"/>
</properties>
</component>
<component id="5916a" class="javax.swing.JTextField" binding="myNameTextField">
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/LanguagePanel.form b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/LanguagePanel.form
index 1f582bb85f03..e8e087e03189 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/LanguagePanel.form
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/LanguagePanel.form
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.plugins.intelliLang.inject.config.ui.LanguagePanel">
- <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="493" height="143"/>
@@ -44,20 +44,15 @@
</constraints>
<properties/>
</component>
- <hspacer id="7c4e8">
- <constraints>
- <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- </hspacer>
<component id="96508" class="com.intellij.ui.EditorTextField" binding="myPrefix">
<constraints>
- <grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="dcdf7" class="com.intellij.ui.EditorTextField" binding="mySuffix">
<constraints>
- <grid row="2" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/configurables/InjectionConfigurable.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/configurables/InjectionConfigurable.java
deleted file mode 100644
index b09de2e4c915..000000000000
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/configurables/InjectionConfigurable.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2006 Sascha Weinreuter
- *
- * 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.intellij.plugins.intelliLang.inject.config.ui.configurables;
-
-import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.NamedConfigurable;
-import org.intellij.plugins.intelliLang.inject.config.Injection;
-import org.intellij.plugins.intelliLang.inject.config.ui.InjectionPanel;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-
-public abstract class InjectionConfigurable<T extends Injection, P extends InjectionPanel<T>> extends NamedConfigurable<T> {
- private final Runnable myTreeUpdater;
- protected final T myInjection;
- protected final Project myProject;
- private P myPanel;
-
- public InjectionConfigurable(T injection, Runnable treeUpdater, Project project) {
- myProject = project;
- myInjection = injection;
- myTreeUpdater = treeUpdater;
- }
-
- public void setDisplayName(String name) {
- }
-
- public T getEditableObject() {
- return myInjection;
- }
-
- @Nullable
- @NonNls
- public String getHelpTopic() {
- return null;
- }
-
- public JComponent createOptionsPanel() {
- myPanel = createOptionsPanelImpl();
- myPanel.addUpdater(myTreeUpdater);
- return myPanel.getComponent();
- }
-
- protected abstract P createOptionsPanelImpl();
-
- public P getPanel() {
- return myPanel;
- }
-
- public boolean isModified() {
- return myPanel.isModified();
- }
-
- public void apply() throws ConfigurationException {
- myPanel.apply();
- }
-
- public void reset() {
- myPanel.reset();
- }
-
- public void disposeUIResources() {
- myPanel = null;
- }
-
- public String getDisplayName() {
- final P p = getPanel();
- return p != null ? p.getInjection().getDisplayName() : myInjection.getDisplayName();
- }
-}
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java
index 0662837d0574..491b277b9393 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java
@@ -16,7 +16,6 @@
package org.intellij.plugins.intelliLang.inject.config;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.JDOMExternalizer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlAttribute;
@@ -44,7 +43,7 @@ import java.util.TreeSet;
*
* @see org.intellij.plugins.intelliLang.inject.config.XPathSupportProxy
*/
-public class AbstractTagInjection extends BaseInjection {
+public abstract class AbstractTagInjection extends BaseInjection {
private static final Logger LOG = Logger.getInstance("org.intellij.plugins.intelliLang.inject.config.AbstractTagInjection");
@@ -57,7 +56,7 @@ public class AbstractTagInjection extends BaseInjection {
private String myXPathCondition = "";
private XPath myCompiledXPathCondition;
- private boolean myApplyToSubTagTexts;
+ private boolean myApplyToSubTags;
public AbstractTagInjection() {
super(XmlLanguageInjectionSupport.XML_SUPPORT_ID);
@@ -134,9 +133,7 @@ public class AbstractTagInjection extends BaseInjection {
}
@Override
- public AbstractTagInjection copy() {
- return new AbstractTagInjection().copyFrom(this);
- }
+ public abstract AbstractTagInjection copy();
public AbstractTagInjection copyFrom(@NotNull BaseInjection o) {
super.copyFrom(o);
@@ -146,30 +143,21 @@ public class AbstractTagInjection extends BaseInjection {
myTagNamespace = other.myTagNamespace;
setXPathCondition(other.getXPathCondition());
- setApplyToSubTagTexts(other.isApplyToSubTagTexts());
+ setApplyToSubTags(other.isApplyToSubTags());
}
return this;
}
protected void readExternalImpl(Element e) {
- if (e.getAttribute("injector-id") == null) {
- setTagName(JDOMExternalizer.readString(e, "TAGNAME"));
- setTagNamespace(JDOMExternalizer.readString(e, "TAGNAMESPACE"));
- setXPathCondition(JDOMExternalizer.readString(e, "XPATH_CONDITION"));
-
- myApplyToSubTagTexts = JDOMExternalizer.readBoolean(e, "APPLY_TO_SUBTAGS");
- }
- else {
- setXPathCondition(e.getChildText("xpath-condition"));
- myApplyToSubTagTexts = e.getChild("apply-to-subtags") != null;
- }
+ setXPathCondition(e.getChildText("xpath-condition"));
+ myApplyToSubTags = e.getChild("apply-to-subtags") != null;
}
protected void writeExternalImpl(Element e) {
if (StringUtil.isNotEmpty(myXPathCondition)) {
e.addContent(new Element("xpath-condition").setText(myXPathCondition));
}
- if (myApplyToSubTagTexts) {
+ if (myApplyToSubTags) {
e.addContent(new Element("apply-to-subtags"));
}
}
@@ -186,7 +174,7 @@ public class AbstractTagInjection extends BaseInjection {
if (!myTagNamespace.equals(that.myTagNamespace)) return false;
if (!myXPathCondition.equals(that.myXPathCondition)) return false;
- if (myApplyToSubTagTexts != that.myApplyToSubTagTexts) return false;
+ if (myApplyToSubTags != that.myApplyToSubTags) return false;
return true;
}
@@ -196,7 +184,7 @@ public class AbstractTagInjection extends BaseInjection {
result = 31 * result + myTagNamespace.hashCode();
result = 31 * result + myXPathCondition.hashCode();
- result = 31 * result + (myApplyToSubTagTexts ? 1 : 0);
+ result = 31 * result + (myApplyToSubTags ? 1 : 0);
return result;
}
@@ -215,12 +203,12 @@ public class AbstractTagInjection extends BaseInjection {
return myXPathCondition.length() == 0;
}
- public boolean isApplyToSubTagTexts() {
- return myApplyToSubTagTexts;
+ public boolean isApplyToSubTags() {
+ return myApplyToSubTags;
}
- public void setApplyToSubTagTexts(final boolean applyToSubTagTexts) {
- myApplyToSubTagTexts = applyToSubTagTexts;
+ public void setApplyToSubTags(final boolean applyToSubTagTexts) {
+ myApplyToSubTags = applyToSubTagTexts;
}
@Override
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlAttributeInjection.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlAttributeInjection.java
index 5ffe3271bb07..32a2239dd3a1 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlAttributeInjection.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlAttributeInjection.java
@@ -15,7 +15,6 @@
*/
package org.intellij.plugins.intelliLang.inject.config;
-import com.intellij.openapi.util.JDOMExternalizer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlAttribute;
@@ -57,8 +56,7 @@ public class XmlAttributeInjection extends AbstractTagInjection {
return element instanceof XmlAttribute && matches((XmlAttribute)element);
}
- @NotNull
- public String getDisplayName() {
+ public String getGeneratedName() {
final String tag = getTagName();
final String attributeName = getAttributeName();
if (!attributeName.equals(StringMatcher.NONE.getPattern())) {
@@ -74,6 +72,7 @@ public class XmlAttributeInjection extends AbstractTagInjection {
@Override
public void generatePlaces() {
+ if (StringUtil.isEmpty(getDisplayName())) setDisplayName(getGeneratedName());
setInjectionPlaces(new InjectionPlace(getCompiler().createElementPattern(getPatternString(this), getDisplayName()), true));
}
@@ -95,25 +94,14 @@ public class XmlAttributeInjection extends AbstractTagInjection {
public XmlAttributeInjection copyFrom(@NotNull BaseInjection o) {
super.copyFrom(o);
if (o instanceof XmlAttributeInjection) {
- final XmlAttributeInjection other = (XmlAttributeInjection)o;
+ XmlAttributeInjection other = (XmlAttributeInjection)o;
+ setApplyToSubTags(other.isApplyToSubTags());
setAttributeName(other.getAttributeName());
setAttributeNamespace(other.getAttributeNamespace());
}
return this;
}
- protected void readExternalImpl(Element e) {
- super.readExternalImpl(e);
- if (e.getAttribute("injector-id") == null) {
- setAttributeName(JDOMExternalizer.readString(e, "ATT_NAME"));
- setAttributeNamespace(JDOMExternalizer.readString(e, "ATT_NAMESPACE"));
- }
- }
-
- protected void writeExternalImpl(Element e) {
- super.writeExternalImpl(e);
- }
-
@SuppressWarnings({"RedundantIfStatement"})
public boolean equals(Object o) {
if (this == o) return true;
@@ -142,7 +130,8 @@ public class XmlAttributeInjection extends AbstractTagInjection {
if (StringUtil.isNotEmpty(name)) appendStringPattern(result, ".withLocalName(", name, ")");
if (StringUtil.isNotEmpty(namespace)) appendStringPattern(result, ".withNamespace(", namespace, ")");
if (StringUtil.isNotEmpty(injection.getTagName()) || StringUtil.isNotEmpty(injection.getTagNamespace())) {
- result.append(".withParent(").append(XmlTagInjection.getPatternString(injection)).append(")");
+ result.append(".").append(injection.isApplyToSubTags() ? "inside" : "withParent").append("(")
+ .append(XmlTagInjection.getPatternString(injection)).append(")");
}
return result.toString();
}
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlTagInjection.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlTagInjection.java
index ade0c399c84d..19d3a8c64f3b 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlTagInjection.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlTagInjection.java
@@ -31,8 +31,7 @@ public class XmlTagInjection extends AbstractTagInjection {
return matches(context) && matchXPath(context);
}
- @NotNull
- public String getDisplayName() {
+ public String getGeneratedName() {
final String name = getTagName();
return name.length() > 0 ? name : "*";
}
@@ -49,6 +48,7 @@ public class XmlTagInjection extends AbstractTagInjection {
@Override
public void generatePlaces() {
+ if (StringUtil.isEmpty(getDisplayName())) setDisplayName(getGeneratedName());
setInjectionPlaces(new InjectionPlace(getCompiler().createElementPattern(getPatternString(this), getDisplayName()), true));
}
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedXmlPanel.form b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedXmlPanel.form
index c4cd838349cd..48df40018f5a 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedXmlPanel.form
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedXmlPanel.form
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.plugins.intelliLang.inject.config.ui.AdvancedXmlPanel">
- <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <xy x="20" y="20" width="531" height="97"/>
+ <xy x="20" y="20" width="531" height="123"/>
</constraints>
<properties/>
<border type="none"/>
@@ -25,7 +25,7 @@
</constraints>
<properties>
<labelFor value="7bf4e"/>
- <text value="&amp;Value Pattern:"/>
+ <text value="&amp;Value pattern:"/>
<toolTipText value="&lt;html&gt;Enter a regular expression that selects the parts of the tag's or attribute's value the language should be injected into.&lt;br&gt;The pattern should contain exactly one capturing group.&lt;/html&gt;"/>
</properties>
</component>
@@ -43,7 +43,7 @@
</constraints>
<properties>
<labelFor value="a6f2"/>
- <text value="&amp;XPath Condition:"/>
+ <text value="&amp;XPath condition:"/>
<toolTipText value="&lt;html&gt;Enter an XPath expression that the tag/attribute must match additionally to the name-condition specified above.&lt;br&gt;This requires the XPathView plugin to be installed&lt;/html&gt;"/>
</properties>
</component>
@@ -60,11 +60,16 @@
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
- <text value="&amp;Single File"/>
+ <text value="Single &amp;file"/>
</properties>
</component>
</children>
</grid>
+ <vspacer id="5c79c">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </vspacer>
</children>
</grid>
</form>
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.form b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.form
index bcbe680d8e0d..70051cbf3730 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.form
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.form
@@ -8,7 +8,7 @@
<properties/>
<border type="none"/>
<children>
- <grid id="7e115" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="49b27" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -19,25 +19,25 @@
</clientProperties>
<border type="none" title="XML Tag"/>
<children>
- <component id="edc9a" class="javax.swing.JLabel">
+ <component id="9c78e" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
- <labelFor value="16487"/>
- <text value="&amp;Local Name:"/>
+ <labelFor value="8f17"/>
+ <text value="&amp;Local name:"/>
</properties>
</component>
- <component id="1068d" class="javax.swing.JLabel">
+ <component id="7d32d" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
- <labelFor value="eeee3"/>
+ <labelFor value="3d65f"/>
<text value="&amp;Namespace:"/>
</properties>
</component>
- <component id="16487" class="com.intellij.ui.EditorTextField" binding="myLocalName" custom-create="true">
+ <component id="8f17" class="com.intellij.ui.EditorTextField" binding="myLocalName" custom-create="true">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
@@ -45,24 +45,29 @@
</constraints>
<properties/>
</component>
- <component id="eeee3" class="com.intellij.openapi.ui.ComboBox" binding="myNamespace" custom-create="true">
+ <component id="3d65f" class="com.intellij.openapi.ui.ComboBox" binding="myNamespace" custom-create="true">
<constraints>
- <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="7" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<editable value="true"/>
</properties>
</component>
+ <component id="3ed2c" class="javax.swing.JCheckBox" binding="myWithSubtags">
+ <constraints>
+ <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Sub-&amp;tags"/>
+ </properties>
+ </component>
</children>
</grid>
- <component id="bc807" class="javax.swing.JCheckBox" binding="myApplyRecursivelyCheckBox">
+ <vspacer id="bdf19">
<constraints>
- <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
- <properties>
- <text value="Apply to all text fragments &amp;recursively"/>
- </properties>
- </component>
+ </vspacer>
</children>
</grid>
</form>
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.java
index 42db562728ff..2b224a1be58d 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.java
@@ -28,7 +28,6 @@ import com.intellij.ui.LanguageTextField;
import org.intellij.lang.regexp.RegExpLanguage;
import org.intellij.plugins.intelliLang.inject.config.AbstractTagInjection;
import org.intellij.plugins.intelliLang.inject.config.JspSupportProxy;
-import org.intellij.plugins.intelliLang.inject.config.XmlTagInjection;
import javax.swing.*;
import java.util.ArrayList;
@@ -43,14 +42,13 @@ public class TagPanel extends AbstractInjectionPanel<AbstractTagInjection> {
private EditorTextField myLocalName;
private ComboBox myNamespace;
- private JCheckBox myApplyRecursivelyCheckBox;
+ private JCheckBox myWithSubtags;
public TagPanel(Project project, AbstractTagInjection injection) {
super(injection, project);
$$$setupUI$$$();
myNamespace.setModel(createNamespaceUriModel(myProject));
- myLocalName.getDocument().addDocumentListener(new TreeUpdateListener());
}
public static ComboBoxModel createNamespaceUriModel(Project project) {
@@ -95,19 +93,13 @@ public class TagPanel extends AbstractInjectionPanel<AbstractTagInjection> {
protected void resetImpl() {
myLocalName.setText(myOrigInjection.getTagName());
myNamespace.getEditor().setItem(myOrigInjection.getTagNamespace());
- final boolean isXmlTag = myOrigInjection instanceof XmlTagInjection;
- myApplyRecursivelyCheckBox.setVisible(isXmlTag);
- if (isXmlTag) {
- myApplyRecursivelyCheckBox.setSelected(((XmlTagInjection)myOrigInjection).isApplyToSubTagTexts());
- }
+ myWithSubtags.setSelected(myOrigInjection.isApplyToSubTags());
}
- protected void apply(AbstractTagInjection i) {
- i.setTagName(myLocalName.getText());
- i.setTagNamespace(getNamespace());
- if (i instanceof XmlTagInjection) {
- ((XmlTagInjection)i).setApplyToSubTagTexts(myApplyRecursivelyCheckBox.isSelected());
- }
+ protected void apply(AbstractTagInjection other) {
+ other.setTagName(myLocalName.getText());
+ other.setTagNamespace(getNamespace());
+ other.setApplyToSubTags(myWithSubtags.isSelected());
}
private String getNamespace() {
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.form b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.form
index 1dce7a917205..a9d67f3f938d 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.form
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.form
@@ -1,22 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.plugins.intelliLang.inject.config.ui.XmlAttributePanel">
- <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="6" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <xy x="20" y="20" width="500" height="479"/>
+ <xy x="20" y="20" width="500" height="551"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<nested-form id="260fa" form-file="org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.form" binding="myTagPanel" custom-create="true">
<constraints>
- <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
<grid id="ea19" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="3" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<clientProperties>
@@ -30,7 +30,7 @@
</constraints>
<properties>
<labelFor value="cca5"/>
- <text value="L&amp;ocal Name:"/>
+ <text value="L&amp;ocal name:"/>
<toolTipText value="Regular expression to match the attribute name, e.g. &quot;on.*&quot;"/>
</properties>
</component>
@@ -65,19 +65,46 @@
</grid>
<vspacer id="f7910">
<constraints>
- <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ <grid row="5" column="0" row-span="1" col-span="2" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<nested-form id="8cfe8" form-file="org/intellij/plugins/intelliLang/inject/config/ui/LanguagePanel.form" binding="myLanguagePanel" custom-create="true">
<constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="1" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
<nested-form id="b6e0b" form-file="org/intellij/plugins/intelliLang/inject/config/ui/AdvancedXmlPanel.form" binding="myAdvancedPanel" custom-create="true">
<constraints>
- <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="4" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
+ <grid id="2032c" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="e174b" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <labelFor value="80ca6"/>
+ <text value="&amp;Name:"/>
+ </properties>
+ </component>
+ <component id="80ca6" class="javax.swing.JTextField" binding="myNameTextField">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ </children>
+ </grid>
</children>
</grid>
</form>
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.java
index 9e8e935c39e8..79f451dd31f9 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.java
@@ -17,6 +17,8 @@ package org.intellij.plugins.intelliLang.inject.config.ui;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.LanguageTextField;
import org.intellij.lang.regexp.RegExpLanguage;
@@ -35,6 +37,9 @@ public class XmlAttributePanel extends AbstractInjectionPanel<XmlAttributeInject
private EditorTextField myLocalName;
private ComboBox myNamespace;
+ private JTextField myNameTextField;
+
+ private boolean myUseGeneratedName;
public XmlAttributePanel(XmlAttributeInjection injection, Project project) {
super(injection, project);
@@ -43,9 +48,6 @@ public class XmlAttributePanel extends AbstractInjectionPanel<XmlAttributeInject
myNamespace.setModel(TagPanel.createNamespaceUriModel(project));
init(injection.copy());
-
- // be sure to add the listener after initializing the textfield's value
- myLocalName.getDocument().addDocumentListener(new TreeUpdateListener());
}
public JPanel getComponent() {
@@ -53,13 +55,21 @@ public class XmlAttributePanel extends AbstractInjectionPanel<XmlAttributeInject
}
protected void resetImpl() {
+ myNameTextField.setText(myOrigInjection.getDisplayName());
myLocalName.setText(myOrigInjection.getAttributeName());
myNamespace.getEditor().setItem(myOrigInjection.getAttributeNamespace());
+
+ myUseGeneratedName = Comparing.equal(myOrigInjection.getDisplayName(), myOrigInjection.getGeneratedName());
}
- protected void apply(XmlAttributeInjection i) {
- i.setAttributeName(myLocalName.getText());
- i.setAttributeNamespace(getNamespace());
+ protected void apply(XmlAttributeInjection other) {
+ other.setAttributeName(myLocalName.getText());
+ other.setAttributeNamespace(getNamespace());
+
+ String name = myNameTextField.getText();
+ boolean useGenerated = myUseGeneratedName && Comparing.equal(myOrigInjection.getDisplayName(), name);
+ String newName = useGenerated || StringUtil.isEmptyOrSpaces(name) ? other.getGeneratedName() : name;
+ other.setDisplayName(newName);
}
private String getNamespace() {
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.form b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.form
index d19d8571c038..36585ab8a020 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.form
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.form
@@ -1,33 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.plugins.intelliLang.inject.config.ui.XmlTagPanel">
- <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <xy x="20" y="20" width="500" height="400"/>
+ <xy x="20" y="20" width="500" height="437"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<nested-form id="4c744" form-file="org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.form" binding="myPanel" custom-create="true">
<constraints>
- <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
<vspacer id="12f92">
<constraints>
- <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<nested-form id="4e64b" form-file="org/intellij/plugins/intelliLang/inject/config/ui/LanguagePanel.form" binding="myLanguagePanel" custom-create="true">
<constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
<nested-form id="fa14a" form-file="org/intellij/plugins/intelliLang/inject/config/ui/AdvancedXmlPanel.form" binding="myAdvancedPanel" custom-create="true">
<constraints>
- <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
+ <grid id="d9c54" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="d2267" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <labelFor value="6c531"/>
+ <text value="&amp;Name:"/>
+ </properties>
+ </component>
+ <component id="6c531" class="javax.swing.JTextField" binding="myNameTextField">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ </children>
+ </grid>
</children>
</grid>
</form>
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.java
index ffc92143ba0c..342cfd61cbe7 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.java
@@ -16,6 +16,8 @@
package org.intellij.plugins.intelliLang.inject.config.ui;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.text.StringUtil;
import org.intellij.plugins.intelliLang.inject.config.XmlTagInjection;
import javax.swing.*;
@@ -28,6 +30,9 @@ public class XmlTagPanel extends AbstractInjectionPanel<XmlTagInjection> {
AdvancedXmlPanel myAdvancedPanel;
private JPanel myRoot;
+ private JTextField myNameTextField;
+
+ private boolean myUseGeneratedName;
public XmlTagPanel(XmlTagInjection injection, Project project) {
super(injection, project);
@@ -37,11 +42,16 @@ public class XmlTagPanel extends AbstractInjectionPanel<XmlTagInjection> {
}
protected void apply(XmlTagInjection other) {
- // nothing to do, TagPanel.apply() already does this
+ String name = myNameTextField.getText();
+ boolean useGenerated = myUseGeneratedName && Comparing.equal(myOrigInjection.getDisplayName(), name);
+ String newName = useGenerated || StringUtil.isEmptyOrSpaces(name) ? other.getGeneratedName() : name;
+ other.setDisplayName(newName);
}
protected void resetImpl() {
- // same here^
+ myNameTextField.setText(myOrigInjection.getDisplayName());
+
+ myUseGeneratedName = Comparing.equal(myOrigInjection.getDisplayName(), myOrigInjection.getGeneratedName());
}
public JPanel getComponent() {
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/XmlAttributeInjectionConfigurable.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/XmlAttributeInjectionConfigurable.java
deleted file mode 100644
index a0898e0e8664..000000000000
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/XmlAttributeInjectionConfigurable.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2006 Sascha Weinreuter
- *
- * 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.intellij.plugins.intelliLang.inject.config.ui.configurables;
-
-import com.intellij.openapi.project.Project;
-import org.intellij.plugins.intelliLang.inject.config.XmlAttributeInjection;
-import org.intellij.plugins.intelliLang.inject.config.ui.XmlAttributePanel;
-
-public class XmlAttributeInjectionConfigurable extends InjectionConfigurable<XmlAttributeInjection, XmlAttributePanel> {
- public XmlAttributeInjectionConfigurable(XmlAttributeInjection injection, Runnable treeUpdater, Project project) {
- super(injection, treeUpdater, project);
- }
-
- protected XmlAttributePanel createOptionsPanelImpl() {
- return new XmlAttributePanel(myInjection, myProject);
- }
-
- public String getBannerSlogan() {
- return "Edit XML Attribute Injection";
- }
-}
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/XmlTagInjectionConfigurable.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/XmlTagInjectionConfigurable.java
deleted file mode 100644
index 655590b2f4cf..000000000000
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/XmlTagInjectionConfigurable.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2006 Sascha Weinreuter
- *
- * 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.intellij.plugins.intelliLang.inject.config.ui.configurables;
-
-import com.intellij.openapi.project.Project;
-import org.intellij.plugins.intelliLang.inject.config.XmlTagInjection;
-import org.intellij.plugins.intelliLang.inject.config.ui.XmlTagPanel;
-
-public class XmlTagInjectionConfigurable extends InjectionConfigurable<XmlTagInjection, XmlTagPanel> {
- public XmlTagInjectionConfigurable(XmlTagInjection injection, Runnable treeUpdater, Project project) {
- super(injection, treeUpdater, project);
- }
-
- public String getBannerSlogan() {
- return "Edit XML Text Injection";
- }
-
- protected XmlTagPanel createOptionsPanelImpl() {
- return new XmlTagPanel(myInjection, myProject);
- }
-}
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java
index 6c84a879b1a6..abe3349a9c15 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java
@@ -43,8 +43,6 @@ import org.intellij.plugins.intelliLang.inject.config.*;
import org.intellij.plugins.intelliLang.inject.config.ui.AbstractInjectionPanel;
import org.intellij.plugins.intelliLang.inject.config.ui.XmlAttributePanel;
import org.intellij.plugins.intelliLang.inject.config.ui.XmlTagPanel;
-import org.intellij.plugins.intelliLang.inject.config.ui.configurables.XmlAttributeInjectionConfigurable;
-import org.intellij.plugins.intelliLang.inject.config.ui.configurables.XmlTagInjectionConfigurable;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -66,7 +64,7 @@ public class XmlLanguageInjectionSupport extends AbstractLanguageInjectionSuppor
final PsiElement p = host.getParent();
if (p instanceof XmlAttribute) {
final String s = ((XmlAttribute)p).getName();
- return !(s.equals("xmlns") || s.startsWith("xmlns:"));
+ return !("xmlns".equals(s) || s.startsWith("xmlns:"));
}
}
else if (host instanceof XmlText) {
@@ -177,7 +175,7 @@ public class XmlLanguageInjectionSupport extends AbstractLanguageInjectionSuppor
}
});
if (builder.show() == DialogWrapper.OK_EXIT_CODE) {
- return new AbstractTagInjection().copyFrom(xmlInjection);
+ return xmlInjection.copy();
}
return null;
}
@@ -219,12 +217,15 @@ public class XmlLanguageInjectionSupport extends AbstractLanguageInjectionSuppor
result.setTagNamespace(value);
}
}
- else if (result instanceof XmlAttributeInjection &&
- "inside".equals(condition.getDebugMethodName()) && condition instanceof PatternConditionPlus) {
- final ElementPattern<?> insidePattern = ((PatternConditionPlus)condition).getValuePattern();
+ else if (result instanceof XmlAttributeInjection && condition instanceof PatternConditionPlus) {
+ boolean strict = "withParent".equals(condition.getDebugMethodName());
+ if (!strict && !"inside".equals(condition.getDebugMethodName())) return null;
+
+ result.setApplyToSubTags(!strict);
+ ElementPattern<?> insidePattern = ((PatternConditionPlus)condition).getValuePattern();
if (!XmlTag.class.equals(insidePattern.getCondition().getInitialCondition().getAcceptedClass())) return null;
for (PatternCondition<?> insideCondition : insidePattern.getCondition().getConditions()) {
- final String tagValue = extractValue(insideCondition);
+ String tagValue = extractValue(insideCondition);
if (tagValue == null) return null;
if ("withLocalName".equals(insideCondition.getDebugMethodName())) {
result.setTagName(tagValue);
@@ -232,10 +233,11 @@ public class XmlLanguageInjectionSupport extends AbstractLanguageInjectionSuppor
else if ("withNamespace".equals(insideCondition.getDebugMethodName())) {
result.setTagNamespace(tagValue);
}
-
}
}
- else return null;
+ else {
+ return null;
+ }
}
result.generatePlaces();
return result;
@@ -265,14 +267,17 @@ public class XmlLanguageInjectionSupport extends AbstractLanguageInjectionSuppor
return null;
}
- public BaseInjection createInjection(final Element element) {
- if (element.getName().equals(XmlAttributeInjection.class.getSimpleName())) {
+ public BaseInjection createInjection(Element element) {
+ String place = StringUtil.notNullize(element.getChildText("place"), "");
+ if (place.startsWith("xmlAttribute")) {
return new XmlAttributeInjection();
}
- else if (element.getName().equals(XmlTagInjection.class.getSimpleName())) {
+ else if (place.startsWith("xmlTag")) {
return new XmlTagInjection();
}
- return new AbstractTagInjection();
+ else {
+ return new BaseInjection(XML_SUPPORT_ID);
+ }
}
public Configurable[] createSettings(final Project project, final Configuration configuration) {
@@ -298,12 +303,10 @@ public class XmlLanguageInjectionSupport extends AbstractLanguageInjectionSuppor
final AbstractTagInjection originalInjection = (AbstractTagInjection)configuration.findExistingInjection(template);
final XmlTagInjection newInjection = originalInjection == null? template : new XmlTagInjection().copyFrom(originalInjection);
- if (InjectLanguageAction.doEditConfigurable(project, new XmlTagInjectionConfigurable(newInjection, null, project))) {
- configuration.replaceInjectionsWithUndo(
- project, Collections.singletonList(newInjection),
- ContainerUtil.createMaybeSingletonList(originalInjection),
- Collections.<PsiElement>emptyList());
- }
+ configuration.replaceInjectionsWithUndo(
+ project, Collections.singletonList(newInjection),
+ ContainerUtil.createMaybeSingletonList(originalInjection),
+ Collections.<PsiElement>emptyList());
}
private static boolean doInjectInAttributeValue(final XmlAttributeValue host, final String languageId) {
@@ -327,12 +330,10 @@ public class XmlLanguageInjectionSupport extends AbstractLanguageInjectionSuppor
final Configuration configuration = InjectorUtils.getEditableInstance(project);
final BaseInjection originalInjection = configuration.findExistingInjection(template);
final BaseInjection newInjection = originalInjection == null ? template : originalInjection.copy();
- if (InjectLanguageAction.doEditConfigurable(project, new XmlAttributeInjectionConfigurable((XmlAttributeInjection)newInjection, null, project))) {
- configuration.replaceInjectionsWithUndo(
- project, Collections.singletonList(newInjection),
- ContainerUtil.createMaybeSingletonList(originalInjection),
- Collections.<PsiElement>emptyList());
- }
+ configuration.replaceInjectionsWithUndo(
+ project, Collections.singletonList(newInjection),
+ ContainerUtil.createMaybeSingletonList(originalInjection),
+ Collections.<PsiElement>emptyList());
}
private static ArrayList<BaseInjection> collectInjections(final PsiElement host,
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java
index f8026edb4f11..c7808b0c1c40 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java
@@ -32,6 +32,7 @@ import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.xml.*;
import com.intellij.util.PairProcessor;
import com.intellij.util.PatternValuesIndex;
+import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashMap;
import org.intellij.plugins.intelliLang.Configuration;
import org.intellij.plugins.intelliLang.inject.InjectedLanguage;
@@ -113,8 +114,7 @@ public final class XmlLanguageInjector implements MultiHostInjector {
if (language == null) continue;
final boolean separateFiles = !injection.isSingleFile() && StringUtil.isNotEmpty(injection.getValuePattern());
- final List<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>> result =
- new ArrayList<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>>();
+ final List<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>> result = ContainerUtil.newArrayList();
xmlTag.acceptChildren(new PsiElementVisitor() {
@Override
@@ -130,7 +130,7 @@ public final class XmlLanguageInjector implements MultiHostInjector {
}
else if (element instanceof XmlTag) {
if (!separateFiles) unparsableRef.set(Boolean.TRUE);
- if (injection instanceof AbstractTagInjection && ((AbstractTagInjection)injection).isApplyToSubTagTexts()) {
+ if (injection instanceof AbstractTagInjection && ((AbstractTagInjection)injection).isApplyToSubTags()) {
element.acceptChildren(this);
}
}
diff --git a/plugins/git4idea/src/git4idea/log/GitLogProvider.java b/plugins/git4idea/src/git4idea/log/GitLogProvider.java
index 0a8bc3723d3f..672e4eb8dead 100644
--- a/plugins/git4idea/src/git4idea/log/GitLogProvider.java
+++ b/plugins/git4idea/src/git4idea/log/GitLogProvider.java
@@ -29,12 +29,7 @@ import com.intellij.util.ExceptionUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.*;
-import com.intellij.vcs.log.data.VcsLogBranchFilter;
-import com.intellij.vcs.log.data.VcsLogDateFilter;
-import com.intellij.vcs.log.data.VcsLogStructureFilter;
-import com.intellij.vcs.log.data.VcsLogUserFilter;
import com.intellij.vcs.log.impl.HashImpl;
-import com.intellij.vcs.log.ui.filter.VcsLogTextFilter;
import git4idea.GitLocalBranch;
import git4idea.GitRemoteBranch;
import git4idea.GitVcs;
@@ -189,7 +184,11 @@ public class GitLogProvider implements VcsLogProvider {
@NotNull
@Override
public List<? extends VcsFullCommitDetails> getFilteredDetails(@NotNull final VirtualFile root,
- @NotNull Collection<VcsLogFilter> filters,
+ @NotNull Collection<VcsLogBranchFilter> branchFilters,
+ @NotNull Collection<VcsLogUserFilter> userFilters,
+ @NotNull Collection<VcsLogDateFilter> dateFilters,
+ @NotNull Collection<VcsLogTextFilter> textFilters,
+ @NotNull Collection<VcsLogStructureFilter> structureFilters,
int maxCount) throws VcsException {
if (!isRepositoryReady(root)) {
return Collections.emptyList();
@@ -197,21 +196,19 @@ public class GitLogProvider implements VcsLogProvider {
List<String> filterParameters = ContainerUtil.newArrayList();
- List<VcsLogBranchFilter> branchFilters = ContainerUtil.findAll(filters, VcsLogBranchFilter.class);
if (!branchFilters.isEmpty()) {
// git doesn't support filtering by several branches very well (--branches parameter give a weak pattern capabilities)
// => by now assuming there is only one branch filter.
if (branchFilters.size() > 1) {
LOG.warn("More than one branch filter was passed. Using only the first one.");
}
- VcsLogBranchFilter branchFilter = branchFilters.get(0);
+ VcsLogBranchFilter branchFilter = branchFilters.iterator().next();
filterParameters.add(branchFilter.getBranchName());
}
else {
filterParameters.addAll(GitHistoryUtils.LOG_ALL);
}
- List<VcsLogUserFilter> userFilters = ContainerUtil.findAll(filters, VcsLogUserFilter.class);
if (!userFilters.isEmpty()) {
String authorFilter = joinFilters(userFilters, new Function<VcsLogUserFilter, String>() {
@Override
@@ -222,7 +219,6 @@ public class GitLogProvider implements VcsLogProvider {
filterParameters.add(prepareParameter("author", authorFilter));
}
- List<VcsLogDateFilter> dateFilters = ContainerUtil.findAll(filters, VcsLogDateFilter.class);
if (!dateFilters.isEmpty()) {
// assuming there is only one date filter, until filter expressions are defined
VcsLogDateFilter filter = dateFilters.iterator().next();
@@ -234,7 +230,6 @@ public class GitLogProvider implements VcsLogProvider {
}
}
- List<VcsLogTextFilter> textFilters = ContainerUtil.findAll(filters, VcsLogTextFilter.class);
if (textFilters.size() > 1) {
LOG.warn("Expected only one text filter: " + textFilters);
}
@@ -249,8 +244,7 @@ public class GitLogProvider implements VcsLogProvider {
}
filterParameters.add("--date-order");
- // note: this filter must be the last parameter, because it uses "--" which separates parameters from paths
- List<VcsLogStructureFilter> structureFilters = ContainerUtil.findAll(filters, VcsLogStructureFilter.class);
+ // note: structure filter must be the last parameter, because it uses "--" which separates parameters from paths
if (!structureFilters.isEmpty()) {
filterParameters.add("--");
for (VcsLogStructureFilter filter : structureFilters) {
@@ -281,7 +275,7 @@ public class GitLogProvider implements VcsLogProvider {
return "--" + paramName + "=" + value; // no value escaping needed, because the parameter itself will be quoted by GeneralCommandLine
}
- private static <T> String joinFilters(List<T> filters, Function<T, String> toString) {
+ private static <T> String joinFilters(Collection<T> filters, Function<T, String> toString) {
return StringUtil.join(filters, toString, "\\|");
}
diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml
index fc7d25465569..034ef355421d 100644
--- a/plugins/gradle/src/META-INF/plugin.xml
+++ b/plugins/gradle/src/META-INF/plugin.xml
@@ -67,12 +67,14 @@
<externalSystemConfigLocator implementation="org.jetbrains.plugins.gradle.service.settings.GradleConfigLocator"/>
<externalSystemManager implementation="org.jetbrains.plugins.gradle.GradleManager"/>
+ <externalProjectDataService implementation="org.jetbrains.plugins.gradle.service.project.data.BuildClasspathModuleGradleDataService"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.service.GradleInstallationManager"/>
<projectService serviceImplementation="org.jetbrains.plugins.gradle.settings.GradleSettings"/>
<projectService serviceImplementation="org.jetbrains.plugins.gradle.settings.GradleLocalSettings"/>
<projectService serviceImplementation="org.jetbrains.plugins.gradle.service.project.GradleNotification"/>
+ <projectService serviceImplementation="org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager"/>
<configurationProducer implementation="org.jetbrains.plugins.gradle.service.execution.GradleRuntimeConfigurationProducer"/>
diff --git a/plugins/gradle/src/META-INF/services/org.jetbrains.plugins.gradle.model.ModelBuilderService b/plugins/gradle/src/META-INF/services/org.jetbrains.plugins.gradle.model.ModelBuilderService
index 3989c7cb0610..430ac6f37ba0 100644
--- a/plugins/gradle/src/META-INF/services/org.jetbrains.plugins.gradle.model.ModelBuilderService
+++ b/plugins/gradle/src/META-INF/services/org.jetbrains.plugins.gradle.model.ModelBuilderService
@@ -16,3 +16,4 @@
org.jetbrains.plugins.gradle.model.builder.WarModelBuilderImpl
org.jetbrains.plugins.gradle.model.builder.ModelDependenciesBuilderImpl
org.jetbrains.plugins.gradle.model.builder.ModuleExtendedModelBuilderImpl
+org.jetbrains.plugins.gradle.model.builder.ModelBuildScriptClasspathBuilderImpl
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleClassFinder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleClassFinder.java
index f85c75acce16..d1fa23ad150e 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleClassFinder.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleClassFinder.java
@@ -16,13 +16,15 @@
package org.jetbrains.plugins.gradle.config;
+import com.intellij.openapi.externalSystem.psi.search.ExternalModuleBuildGlobalSearchScope;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.NonClasspathClassFinder;
+import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.gradle.service.GradleInstallationManager;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager;
-import java.util.Collections;
import java.util.List;
/**
@@ -30,19 +32,31 @@ import java.util.List;
*/
public class GradleClassFinder extends NonClasspathClassFinder {
- @NotNull private final GradleInstallationManager myLibraryManager;
+ @NotNull private final GradleBuildClasspathManager myBuildClasspathManager;
- public GradleClassFinder(Project project, @NotNull GradleInstallationManager manager) {
- super(project, true, true);
- myLibraryManager = manager;
+ public GradleClassFinder(Project project, @NotNull GradleBuildClasspathManager buildClasspathManager) {
+ super(project, true);
+ myBuildClasspathManager = buildClasspathManager;
}
@Override
protected List<VirtualFile> calcClassRoots() {
- final List<VirtualFile> roots = myLibraryManager.getClassRoots(myProject);
- if (roots != null) {
- return roots;
+ // do not use default NonClasspathClassFinder caching strategy based on PSI change
+ // the caching performed in GradleBuildClasspathManager
+ throw new AssertionError();
+ }
+
+ @Override
+ protected List<VirtualFile> getClassRoots() {
+ return myBuildClasspathManager.getAllClasspathEntries();
+ }
+
+ @Override
+ protected List<VirtualFile> getClassRoots(@Nullable GlobalSearchScope scope) {
+ if (scope instanceof ExternalModuleBuildGlobalSearchScope) {
+ ExternalModuleBuildGlobalSearchScope externalModuleBuildGlobalSearchScope = (ExternalModuleBuildGlobalSearchScope)scope;
+ return myBuildClasspathManager.getModuleClasspathEntries(externalModuleBuildGlobalSearchScope.getExternalModulePath());
}
- return Collections.emptyList();
+ return myBuildClasspathManager.getAllClasspathEntries();
}
} \ No newline at end of file
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java
index b7ecd351d58d..d5984903fe90 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java
@@ -21,12 +21,18 @@ import com.intellij.execution.*;
import com.intellij.execution.configurations.JavaParameters;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.externalSystem.psi.search.ExternalModuleBuildGlobalSearchScope;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.JdkOrderEntry;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.roots.OrderEnumerator;
+import com.intellij.openapi.roots.impl.LibraryScopeCache;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
@@ -40,8 +46,10 @@ import icons.GradleIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.execution.GradleTaskLocation;
-import org.jetbrains.plugins.gradle.util.GradleConstants;
+import org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager;
import org.jetbrains.plugins.gradle.service.GradleInstallationManager;
+import org.jetbrains.plugins.gradle.service.resolve.GradleResolverUtil;
+import org.jetbrains.plugins.gradle.util.GradleConstants;
import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
import org.jetbrains.plugins.groovy.extensions.GroovyScriptType;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
@@ -72,9 +80,9 @@ public class GradleScriptType extends GroovyScriptType {
private static final Pattern MAIN_CLASS_NAME_PATTERN = Pattern.compile("\nSTARTER_MAIN_CLASS=(.*)\n");
public static final GroovyScriptType INSTANCE = new GradleScriptType();
-
+
private GradleScriptType() {
- super(GradleConstants.EXTENSION);
+ super(GradleConstants.EXTENSION);
}
@NotNull
@@ -89,7 +97,7 @@ public class GradleScriptType extends GroovyScriptType {
if (params == null) {
return false;
}
-
+
final List<String> tasks = getTasksTarget(location);
if (tasks == null) {
return false;
@@ -218,7 +226,9 @@ public class GradleScriptType extends GroovyScriptType {
throw new CantRunException(String.format("Module '%s' is not backed by gradle", module.getName()));
}
final VirtualFile gradleHome = libraryManager.getGradleHome(module, project, rootProjectPath);
- assert gradleHome != null;
+ if(gradleHome == null) {
+ throw new CantRunException("Gradle home can not be found");
+ }
params.setMainClass(findMainClass(gradleHome, script, project));
@@ -249,11 +259,11 @@ public class GradleScriptType extends GroovyScriptType {
params.getVMParametersList().add("-Dgradle.home=" + FileUtil.toSystemDependentName(gradleHome.getPath()));
setToolsJar(params);
-
+
final String scriptPath = configuration.getScriptPath();
if (scriptPath == null) {
throw new CantRunException("Target script is undefined");
- }
+ }
params.getProgramParametersList().add("--build-file");
params.getProgramParametersList().add(FileUtil.toSystemDependentName(scriptPath));
params.getProgramParametersList().addParametersString(configuration.getProgramParameters());
@@ -298,22 +308,28 @@ public class GradleScriptType extends GroovyScriptType {
@Override
public GlobalSearchScope patchResolveScope(@NotNull GroovyFile file, @NotNull GlobalSearchScope baseScope) {
+ if (!FileUtilRt.extensionEquals(file.getName(), GradleConstants.EXTENSION)) return baseScope;
+
+ final Collection<VirtualFile> files;
+ GlobalSearchScope result = GlobalSearchScope.EMPTY_SCOPE;
final Module module = ModuleUtilCore.findModuleForPsiElement(file);
- final GradleInstallationManager libraryManager = ServiceManager.getService(GradleInstallationManager.class);
if (module != null) {
- if (libraryManager.getGradleHome(module) != null) {
- return baseScope;
+ for (OrderEntry entry : ModuleRootManager.getInstance(module).getOrderEntries()) {
+ if (entry instanceof JdkOrderEntry) {
+ GlobalSearchScope scopeForSdk = LibraryScopeCache.getInstance(module.getProject()).getScopeForSdk((JdkOrderEntry)entry);
+ result = result.uniteWith(scopeForSdk);
+ }
}
- }
- final Collection<VirtualFile> files = libraryManager.getClassRoots(file.getProject());
- if (files == null || files.isEmpty()) {
- return baseScope;
- }
+ String modulePath = module.getOptionValue(ExternalSystemConstants.LINKED_PROJECT_PATH_KEY);
+ if(modulePath == null) return result;
+
+ files = GradleBuildClasspathManager.getInstance(file.getProject()).getModuleClasspathEntries(modulePath);
- GlobalSearchScope result = baseScope;
- for (final VirtualFile root : files) {
- result = result.uniteWith(new NonClasspathDirectoryScope(root));
+ for (final VirtualFile root : files) {
+ result = result.uniteWith(new NonClasspathDirectoryScope(root));
+ }
+ result = new ExternalModuleBuildGlobalSearchScope(result, modulePath);
}
return result;
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/maven/ImportMavenRepositoriesTask.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/maven/ImportMavenRepositoriesTask.java
index f34748e44487..d14125e85122 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/maven/ImportMavenRepositoriesTask.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/maven/ImportMavenRepositoriesTask.java
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.gradle.integrations.maven;
+import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
@@ -97,9 +98,9 @@ public class ImportMavenRepositoriesTask implements Runnable {
final PsiFile[] psiFiles = ArrayUtil.toObjectArray(psiFileList, PsiFile.class);
- final Set<MavenRemoteRepository> mavenRemoteRepositories = new WriteCommandAction<Set<MavenRemoteRepository>>(myProject, psiFiles) {
+ final Set<MavenRemoteRepository> mavenRemoteRepositories = new ReadAction<Set<MavenRemoteRepository>>() {
@Override
- protected void run(Result<Set<MavenRemoteRepository>> result) throws Throwable {
+ protected void run(@NotNull Result<Set<MavenRemoteRepository>> result) throws Throwable {
Set<MavenRemoteRepository> myRemoteRepositories = ContainerUtil.newHashSet();
for (PsiFile psiFile : psiFiles) {
List<GrClosableBlock> repositoriesBlocks = ContainerUtil.newArrayList();
@@ -118,7 +119,7 @@ public class ImportMavenRepositoriesTask implements Runnable {
}
}.execute().getResultObject();
- if (mavenRemoteRepositories.isEmpty()) return;
+ if (mavenRemoteRepositories == null || mavenRemoteRepositories.isEmpty()) return;
MavenRepositoriesHolder.getInstance(myProject).update(mavenRemoteRepositories);
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/BuildScriptClasspathModel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/BuildScriptClasspathModel.java
new file mode 100644
index 000000000000..6854655609ca
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/BuildScriptClasspathModel.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model;
+
+import org.gradle.tooling.model.DomainObjectSet;
+
+import java.io.Serializable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/20/13
+ */
+public interface BuildScriptClasspathModel extends Serializable {
+ DomainObjectSet<? extends ClasspathEntryModel> getClasspath();
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/ClasspathEntryModel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/ClasspathEntryModel.java
new file mode 100644
index 000000000000..09120caccacf
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/ClasspathEntryModel.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/20/13
+ */
+public interface ClasspathEntryModel {
+ @NotNull
+ File getClassesFile();
+
+ @Nullable
+ File getSourcesFile();
+
+ @Nullable
+ File getJavadocFile();
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleDependencyScope.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleDependencyScope.java
index 7186312c24b4..78caa4d9f4d5 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleDependencyScope.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleDependencyScope.java
@@ -22,11 +22,6 @@ import org.jetbrains.annotations.Nullable;
* @since 11/25/13
*/
public enum GradleDependencyScope {
- // Implicit scopes
- PROVIDED("provided", "provided", true, true, true, true),
- OPTIONAL("optional", "compile", true, true, true, true),
-
-
// Java Plugin Scopes
/**
* Compile time dependencies
@@ -74,7 +69,11 @@ public enum GradleDependencyScope {
/**
* Compiles test Scala source files.
*/
- COMPILE_TEST_SCALA("compileTestScala", "test", false, false, true, true);
+ COMPILE_TEST_SCALA("compileTestScala", "test", false, false, true, true),
+
+ // Implicit scopes
+ PROVIDED("provided", "provided", true, true, true, true),
+ OPTIONAL("optional", "compile", true, true, true, true),;
private final String myGradleName;
private final String myIdeaMappingName;
@@ -124,7 +123,7 @@ public enum GradleDependencyScope {
@Nullable
public static GradleDependencyScope fromIdeaMappingName(final String ideaMappingName) {
for (GradleDependencyScope scope : values()) {
- if (scope.myIdeaMappingName.equals(ideaMappingName.toLowerCase())) return scope;
+ if (scope.myIdeaMappingName.equals(ideaMappingName)) return scope;
}
return null;
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelBuildScriptClasspathBuilderImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelBuildScriptClasspathBuilderImpl.java
new file mode 100644
index 000000000000..875d9cc26bc6
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelBuildScriptClasspathBuilderImpl.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model.builder;
+
+import org.gradle.api.Project;
+import org.gradle.api.artifacts.Configuration;
+import org.gradle.plugins.ide.idea.IdeaPlugin;
+import org.gradle.plugins.ide.idea.model.IdeaModel;
+import org.gradle.plugins.ide.internal.IdeDependenciesExtractor;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.model.BuildScriptClasspathModel;
+import org.jetbrains.plugins.gradle.model.ModelBuilderService;
+import org.jetbrains.plugins.gradle.model.internal.BuildScriptClasspathModelImpl;
+import org.jetbrains.plugins.gradle.model.internal.ClasspathEntryModelImpl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/20/13
+ */
+public class ModelBuildScriptClasspathBuilderImpl implements ModelBuilderService {
+
+ @Override
+ public boolean canBuild(String modelName) {
+ return BuildScriptClasspathModel.class.getName().equals(modelName);
+ }
+
+ @Nullable
+ @Override
+ public Object buildAll(final String modelName, final Project project) {
+ boolean offline = false;
+ boolean downloadJavadoc = false;
+ boolean downloadSources = true;
+
+ final IdeaPlugin ideaPlugin = project.getPlugins().getPlugin(IdeaPlugin.class);
+
+ if (ideaPlugin != null) {
+ IdeaModel ideaModel = ideaPlugin.getModel();
+ if (ideaModel != null && ideaModel.getModule() != null) {
+ offline = ideaModel.getModule().isOffline();
+ downloadJavadoc = ideaModel.getModule().isDownloadJavadoc();
+ downloadSources = ideaModel.getModule().isDownloadSources();
+ }
+ }
+
+ final IdeDependenciesExtractor dependenciesExtractor = new IdeDependenciesExtractor();
+
+ final Configuration configuration = project.getBuildscript().getConfigurations().findByName("classpath");
+ Collection<Configuration> plusConfigurations = Collections.singletonList(configuration);
+
+ BuildScriptClasspathModelImpl buildScriptClasspath = new BuildScriptClasspathModelImpl();
+
+ if (!offline) {
+ // download sources and/or javadoc
+ List<IdeDependenciesExtractor.IdeRepoFileDependency> repoFileDependencies = dependenciesExtractor.extractRepoFileDependencies(
+ project.getConfigurations(), plusConfigurations, new ArrayList<Configuration>(), downloadSources, downloadJavadoc);
+
+ for (IdeDependenciesExtractor.IdeRepoFileDependency dependency : repoFileDependencies) {
+ if (dependency.getFile() == null) continue;
+
+ buildScriptClasspath.add(
+ new ClasspathEntryModelImpl(dependency.getFile(), dependency.getSourceFile(), dependency.getJavadocFile()));
+ }
+ }
+
+ final List<IdeDependenciesExtractor.IdeLocalFileDependency> localFileDependencies =
+ dependenciesExtractor.extractLocalFileDependencies(plusConfigurations, new ArrayList<Configuration>());
+
+ for (IdeDependenciesExtractor.IdeLocalFileDependency dependency : localFileDependencies) {
+ if (dependency.getFile() == null) continue;
+ buildScriptClasspath.add(new ClasspathEntryModelImpl(dependency.getFile(), null, null));
+ }
+
+ return buildScriptClasspath;
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java
index 05864829e6ed..4c0e3914185e 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java
@@ -24,6 +24,7 @@ import org.gradle.plugins.ide.idea.IdeaPlugin;
import org.gradle.plugins.ide.idea.model.IdeaModel;
import org.gradle.plugins.ide.internal.IdeDependenciesExtractor;
import org.gradle.tooling.model.idea.IdeaDependency;
+import org.gradle.util.GradleVersion;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.model.GradleDependencyScope;
import org.jetbrains.plugins.gradle.model.ModelBuilderService;
@@ -54,7 +55,7 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService {
public Object buildAll(final String modelName, final Project project) {
final List<IdeaDependency> dependencies = new ArrayList<IdeaDependency>();
- final Map<DependencyVersionId, Scopes> scopesMap = new HashMap<DependencyVersionId, Scopes>();
+ final Map<DependencyVersionId, Scopes> scopesMap = new LinkedHashMap<DependencyVersionId, Scopes>();
final IdeDependenciesExtractor dependenciesExtractor = new IdeDependenciesExtractor();
boolean offline = false;
@@ -148,6 +149,7 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService {
versionId.getClassifier()
);
libraryDependency.setFile(fileDependency.getFile());
+ attachGradleSdkSources(libraryDependency, fileDependency);
dependencies.add(libraryDependency);
}
}
@@ -156,6 +158,32 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService {
return new ProjectDependenciesModelImpl(project.getPath(), dependencies);
}
+ private static void attachGradleSdkSources(IdeaSingleEntryLibraryDependencyImpl libraryDependency,
+ IdeDependenciesExtractor.IdeLocalFileDependency localFileDependency) {
+ final String libName = localFileDependency.getFile().getName();
+ if (localFileDependency.getFile() == null || !libName.startsWith("gradle-")) return;
+
+ File libOrPluginsFile = localFileDependency.getFile().getParentFile();
+ if (libOrPluginsFile != null && ("plugins".equals(libOrPluginsFile.getName()))) {
+ libOrPluginsFile = libOrPluginsFile.getParentFile();
+ }
+
+ if (libOrPluginsFile != null && "lib".equals(libOrPluginsFile.getName()) && libOrPluginsFile.getParentFile() != null) {
+ File srcDir = new File(libOrPluginsFile.getParentFile(), "src");
+ if (GradleVersion.current().compareTo(GradleVersion.version("1.9")) >= 0) {
+ int endIndex = libName.indexOf(GradleVersion.current().getVersion() + ".jar");
+ if (endIndex != -1) {
+ String srcDirChild = libName.substring("gradle-".length(), endIndex - 1);
+ srcDir = new File(srcDir, srcDirChild);
+ }
+ }
+
+ if (srcDir.isDirectory()) {
+ libraryDependency.setSource(srcDir);
+ }
+ }
+ }
+
@Nullable
private static String findDeDuplicatedModuleName(Project project) {
if (project.hasProperty(MODULE_PROPERTY)) {
@@ -261,15 +289,13 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService {
private static GradleDependencyScope deduceScope(String configurationName,
Map<String, Map<String, Collection<Configuration>>> userScopes) {
GradleDependencyScope scope = GradleDependencyScope.fromName(configurationName);
- if (scope == null) {
- for (Map.Entry<String, Map<String, Collection<Configuration>>> entry : userScopes.entrySet()) {
- Collection<Configuration> plusConfigurations = entry.getValue().get("plus");
- if (plusConfigurations == null) continue;
-
- for (Configuration plus : plusConfigurations) {
- if (plus.getName().equals(configurationName)) {
- return GradleDependencyScope.fromIdeaMappingName(entry.getKey());
- }
+ for (Map.Entry<String, Map<String, Collection<Configuration>>> entry : userScopes.entrySet()) {
+ Collection<Configuration> plusConfigurations = entry.getValue().get("plus");
+ if (plusConfigurations == null) continue;
+
+ for (Configuration plus : plusConfigurations) {
+ if (plus.getName().equals(configurationName)) {
+ return GradleDependencyScope.fromIdeaMappingName(entry.getKey().toLowerCase());
}
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImpl.java
index 3dc854020c6c..44eb6cfe328b 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImpl.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImpl.java
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.gradle.model.builder;
+import groovy.lang.GroovyObject;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.tasks.SourceSet;
@@ -69,10 +70,17 @@ public class ModuleExtendedModelBuilderImpl implements ModelBuilderService {
moduleVersionModel.setArtifacts(artifacts);
+ final Set<String> sourceDirectories = new HashSet<String>();
final Set<String> testDirectories = new HashSet<String>();
+ final Set<String> resourceDirectories = new HashSet<String>();
+ final Set<String> testResourceDirectories = new HashSet<String>();
+
+ final List<File> testClassesDirs = new ArrayList<File>();
for (Task task : project.getTasks()) {
if (task instanceof Test) {
Test test = (Test)task;
+ testClassesDirs.add(test.getTestClassesDir());
+
if (test.hasProperty(TEST_SRC_DIRS_PROPERTY)) {
Object testSrcDirs = test.property(TEST_SRC_DIRS_PROPERTY);
if (testSrcDirs instanceof Iterable) {
@@ -84,40 +92,58 @@ public class ModuleExtendedModelBuilderImpl implements ModelBuilderService {
}
}
- final Set<String> javaDirectories = new HashSet<String>();
- final Set<String> resourceDirectories = new HashSet<String>();
-
if (project.hasProperty(SOURCE_SETS_PROPERTY)) {
Object sourceSets = project.property(SOURCE_SETS_PROPERTY);
if (sourceSets instanceof SourceSetContainer) {
SourceSetContainer sourceSetContainer = (SourceSetContainer)sourceSets;
for (SourceSet sourceSet : sourceSetContainer) {
- for (File javaSrcDir : sourceSet.getAllJava().getSrcDirs()) {
- addFilePath(javaDirectories, javaSrcDir);
+ for (File javaSrcDir : sourceSet.getJava().getSrcDirs()) {
+ boolean isTestDir = isTestDir(sourceSet, testClassesDirs);
+ addFilePath(isTestDir ? testDirectories : sourceDirectories, javaSrcDir);
}
for (File resourcesSrcDir : sourceSet.getResources().getSrcDirs()) {
- addFilePath(resourceDirectories, resourcesSrcDir);
+ boolean isTestDir = isTestDir(sourceSet, testClassesDirs);
+ addFilePath(isTestDir ? testResourceDirectories : resourceDirectories, resourcesSrcDir);
}
}
}
}
-
File projectDir = project.getProjectDir();
IdeaContentRootImpl contentRoot = new IdeaContentRootImpl(projectDir);
- enrichDataFromIdeaPlugin(project, contentRoot, javaDirectories, testDirectories);
+ final Set<String> ideaSourceDirectories = new HashSet<String>();
+ final Set<String> ideaTestDirectories = new HashSet<String>();
+ final Set<String> ideaExtResourceDirectories = new HashSet<String>();
+ final Set<String> ideaExtTestResourceDirectories = new HashSet<String>();
+ final Set<File> excludeDirectories = new HashSet<File>();
+
+ enrichDataFromIdeaPlugin(project, excludeDirectories, ideaSourceDirectories, ideaTestDirectories,
+ ideaExtResourceDirectories, ideaExtTestResourceDirectories);
- javaDirectories.removeAll(testDirectories);
- javaDirectories.removeAll(resourceDirectories);
+ if (ideaSourceDirectories.isEmpty()) {
+ sourceDirectories.clear();
+ resourceDirectories.clear();
+ }
+ if (ideaTestDirectories.isEmpty()) {
+ testDirectories.clear();
+ testResourceDirectories.clear();
+ }
- final Set<String> testResourceDirectories = new HashSet<String>(resourceDirectories);
- testResourceDirectories.retainAll(testDirectories);
+ ideaSourceDirectories.removeAll(resourceDirectories);
+ sourceDirectories.addAll(ideaSourceDirectories);
+ ideaTestDirectories.removeAll(testResourceDirectories);
+ testDirectories.addAll(ideaTestDirectories);
- testDirectories.removeAll(resourceDirectories);
- resourceDirectories.removeAll(testResourceDirectories);
+ resourceDirectories.addAll(ideaExtResourceDirectories);
+ testResourceDirectories.addAll(ideaExtTestResourceDirectories);
- for (String javaDir : javaDirectories) {
+ // ensure disjoint directories with different type
+ resourceDirectories.removeAll(sourceDirectories);
+ testDirectories.removeAll(sourceDirectories);
+ testResourceDirectories.removeAll(testDirectories);
+
+ for (String javaDir : sourceDirectories) {
contentRoot.addSourceDirectory(new IdeaSourceDirectoryImpl(new File(javaDir)));
}
for (String testDir : testDirectories) {
@@ -129,11 +155,29 @@ public class ModuleExtendedModelBuilderImpl implements ModelBuilderService {
for (String testResourceDir : testResourceDirectories) {
contentRoot.addTestResourceDirectory(new IdeaSourceDirectoryImpl(new File(testResourceDir)));
}
+ for (File excludeDir : excludeDirectories) {
+ contentRoot.addExcludeDirectory(excludeDir);
+ }
moduleVersionModel.setContentRoots(Collections.<ExtIdeaContentRoot>singleton(contentRoot));
return moduleVersionModel;
}
+ private static boolean isTestDir(SourceSet sourceSet, List<File> testClassesDirs) {
+ if (SourceSet.TEST_SOURCE_SET_NAME.equals(sourceSet.getName())) return true;
+ if (SourceSet.MAIN_SOURCE_SET_NAME.equals(sourceSet.getName())) return false;
+
+ File sourceSetClassesDir = sourceSet.getOutput().getClassesDir();
+ for (File testClassesDir : testClassesDirs) {
+ do {
+ if (sourceSetClassesDir.getPath().equals(testClassesDir.getPath())) return true;
+ }
+ while ((testClassesDir = testClassesDir.getParentFile()) != null);
+ }
+
+ return false;
+ }
+
private static void addFilePath(Set<String> filePathSet, Object file) {
if (file instanceof File) {
try {
@@ -145,9 +189,11 @@ public class ModuleExtendedModelBuilderImpl implements ModelBuilderService {
}
private static void enrichDataFromIdeaPlugin(Project project,
- IdeaContentRootImpl contentRoot,
+ Set<File> excludeDirectories,
Set<String> javaDirectories,
- Set<String> testDirectories) {
+ Set<String> testDirectories,
+ Set<String> ideaExtResourceDirectories,
+ Set<String> ideaExtTestResourceDirectories) {
IdeaPlugin ideaPlugin = project.getPlugins().getPlugin(IdeaPlugin.class);
if (ideaPlugin == null) return;
@@ -156,7 +202,7 @@ public class ModuleExtendedModelBuilderImpl implements ModelBuilderService {
if (ideaModel == null || ideaModel.getModule() == null) return;
for (File excludeDir : ideaModel.getModule().getExcludeDirs()) {
- contentRoot.addExcludeDirectory(excludeDir);
+ excludeDirectories.add(excludeDir);
}
for (File file : ideaModel.getModule().getSourceDirs()) {
javaDirectories.add(file.getPath());
@@ -164,5 +210,25 @@ public class ModuleExtendedModelBuilderImpl implements ModelBuilderService {
for (File file : ideaModel.getModule().getTestSourceDirs()) {
testDirectories.add(file.getPath());
}
+
+ ideaExtResourceDirectories.addAll(getExtDirs("resourceDirs", ideaModel.getModule()));
+ ideaExtTestResourceDirectories.addAll(getExtDirs("testResourceDirs", ideaModel.getModule()));
+ }
+
+ private static List<String> getExtDirs(String propertyName, GroovyObject ideaModule) {
+ List<String> directories = new ArrayList<String>();
+ Object resourceDirs = ideaModule.getProperty(propertyName);
+ if (resourceDirs instanceof Iterable) {
+ for (Object o : Iterable.class.cast(resourceDirs)) {
+ if (o instanceof File) {
+ directories.add(File.class.cast(o).getPath());
+ }
+ else if (o instanceof String) {
+ directories.add((String)o);
+ }
+ }
+ }
+
+ return directories;
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/BuildScriptClasspathData.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/BuildScriptClasspathData.java
new file mode 100644
index 000000000000..cc252a9750a0
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/BuildScriptClasspathData.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model.data;
+
+import com.intellij.openapi.externalSystem.model.Key;
+import com.intellij.openapi.externalSystem.model.ProjectKeys;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/20/13
+ */
+public class BuildScriptClasspathData extends AbstractExternalEntityData {
+ private static final long serialVersionUID = 1L;
+ @NotNull
+ public static final Key<BuildScriptClasspathData> KEY =
+ Key.create(BuildScriptClasspathData.class, ProjectKeys.LIBRARY_DEPENDENCY.getProcessingWeight() + 1);
+
+ @NotNull
+ private final List<ClasspathEntry> myClasspathEntries;
+
+
+ public BuildScriptClasspathData(@NotNull ProjectSystemId owner, @NotNull List<ClasspathEntry> classpathEntries) {
+ super(owner);
+ myClasspathEntries = classpathEntries;
+ }
+
+ @NotNull
+ public List<ClasspathEntry> getClasspathEntries() {
+ return myClasspathEntries;
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/ClasspathEntry.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/ClasspathEntry.java
new file mode 100644
index 000000000000..fa0959ff74ad
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/ClasspathEntry.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model.data;
+
+import com.intellij.openapi.util.io.FileUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/23/13
+ */
+public class ClasspathEntry implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @NotNull
+ private final File myClassesFile;
+
+ @Nullable
+ private final File mySourcesFile;
+
+ @Nullable
+ private final File myJavadocFile;
+
+ public ClasspathEntry(@NotNull File classesFile, @Nullable File sourcesFile, @Nullable File javadocFile) {
+ myClassesFile = classesFile;
+ mySourcesFile = sourcesFile;
+ myJavadocFile = javadocFile;
+ }
+
+ @NotNull
+ public File getClassesFile() {
+ return myClassesFile;
+ }
+
+ @Nullable
+ public File getSourcesFile() {
+ return mySourcesFile;
+ }
+
+ @Nullable
+ public File getJavadocFile() {
+ return myJavadocFile;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ClasspathEntry)) return false;
+
+ ClasspathEntry entry = (ClasspathEntry)o;
+
+ if (!FileUtil.filesEqual(myClassesFile, entry.myClassesFile)) return false;
+ if (!FileUtil.filesEqual(myJavadocFile, entry.myJavadocFile)) return false;
+ if (!FileUtil.filesEqual(mySourcesFile, entry.mySourcesFile)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = FileUtil.fileHashCode(myClassesFile);
+ result = 31 * result + FileUtil.fileHashCode(mySourcesFile);
+ result = 31 * result + FileUtil.fileHashCode(myJavadocFile);
+ return result;
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/BuildScriptClasspathModelImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/BuildScriptClasspathModelImpl.java
new file mode 100644
index 000000000000..b59241181110
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/BuildScriptClasspathModelImpl.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model.internal;
+
+import org.gradle.tooling.model.DomainObjectSet;
+import org.gradle.tooling.model.internal.ImmutableDomainObjectSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.gradle.model.BuildScriptClasspathModel;
+import org.jetbrains.plugins.gradle.model.ClasspathEntryModel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/20/13
+ */
+public class BuildScriptClasspathModelImpl implements BuildScriptClasspathModel {
+
+ private final List<ClasspathEntryModel> myClasspathEntries;
+
+ public BuildScriptClasspathModelImpl() {
+ myClasspathEntries = new ArrayList<ClasspathEntryModel>();
+ }
+
+ @Override
+ public DomainObjectSet<? extends ClasspathEntryModel> getClasspath() {
+ return ImmutableDomainObjectSet.of(myClasspathEntries);
+ }
+
+ public void add(@NotNull ClasspathEntryModel classpathEntryModel) {
+ myClasspathEntries.add(classpathEntryModel);
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/ClasspathEntryModelImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/ClasspathEntryModelImpl.java
new file mode 100644
index 000000000000..06188100d4ab
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/ClasspathEntryModelImpl.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model.internal;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.model.ClasspathEntryModel;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/20/13
+ */
+public class ClasspathEntryModelImpl implements ClasspathEntryModel, Serializable {
+ @NotNull
+ private final File classesFile;
+ @Nullable
+ private final File sourcesFile;
+ @Nullable
+ private final File javadocFile;
+
+ public ClasspathEntryModelImpl(@NotNull File classesFile, @Nullable File sourcesFile, @Nullable File javadocFile) {
+ this.classesFile = classesFile;
+ this.sourcesFile = sourcesFile;
+ this.javadocFile = javadocFile;
+ }
+
+ @NotNull
+ @Override
+ public File getClassesFile() {
+ return classesFile;
+ }
+
+ @Nullable
+ @Override
+ public File getSourcesFile() {
+ return sourcesFile;
+ }
+
+ @Nullable
+ @Override
+ public File getJavadocFile() {
+ return javadocFile;
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/buildSrcInit.gradle b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/buildSrcInit.gradle
new file mode 100644
index 000000000000..91140f2fcec6
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/buildSrcInit.gradle
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2000-2014 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.
+ */
+
+allprojects { project ->
+ if(project.name == 'buildSrc') {
+ apply plugin: 'groovy'
+ dependencies {
+ compile gradleApi()
+ compile localGroovy()
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle
index a788cb85d83d..4f382fd42590 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle
@@ -34,6 +34,10 @@ try {
URLClassLoader classLoader = new URLClassLoader(urls, getClass().classLoader)
Class modelClass = classLoader.loadClass('org.jetbrains.plugins.gradle.model.internal.ExtraModelBuilder')
allprojects {
+ apply plugin: 'idea'
+ idea.module.ext.set('resourceDirs', [])
+ idea.module.ext.set('testResourceDirs', [])
+
ext.jetExtraModelBuilderClass = modelClass
apply plugin: JetGradlePlugin
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleBuildClasspathManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleBuildClasspathManager.java
new file mode 100644
index 000000000000..512bd70ecfe0
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleBuildClasspathManager.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2000-2014 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;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.externalSystem.ExternalSystemManager;
+import com.intellij.openapi.externalSystem.model.project.ExternalModuleBuildClasspathPojo;
+import com.intellij.openapi.externalSystem.model.project.ExternalProjectBuildClasspathPojo;
+import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
+import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.gradle.util.GradleConstants;
+
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/27/13
+ */
+public class GradleBuildClasspathManager {
+ @NotNull
+ private final Project myProject;
+
+ @NotNull
+ private volatile List<VirtualFile> allFilesCache;
+
+ @NotNull
+ private final AtomicReference<Map<String/*module path*/, List<VirtualFile> /*module build classpath*/>> myClasspathMap
+ = new AtomicReference<Map<String, List<VirtualFile>>>(new HashMap<String, List<VirtualFile>>());
+
+ public GradleBuildClasspathManager(@NotNull Project project) {
+ myProject = project;
+ reload();
+ }
+
+ @NotNull
+ public static GradleBuildClasspathManager getInstance(@NotNull Project project) {
+ return ServiceManager.getService(project, GradleBuildClasspathManager.class);
+ }
+
+ public void reload() {
+ ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(GradleConstants.SYSTEM_ID);
+ assert manager != null;
+ AbstractExternalSystemLocalSettings localSettings = manager.getLocalSettingsProvider().fun(myProject);
+
+ Map<String/*module path*/, List<VirtualFile> /*module build classpath*/> map = ContainerUtil.newHashMap();
+
+ final LocalFileSystem localFileSystem = LocalFileSystem.getInstance();
+ final JarFileSystem jarFileSystem = JarFileSystem.getInstance();
+ for (ExternalProjectBuildClasspathPojo projectBuildClasspathPojo : localSettings.getProjectBuildClasspath().values()) {
+ List<VirtualFile> projectBuildClasspath = ContainerUtil.newArrayList();
+ for (String path : projectBuildClasspathPojo.getProjectBuildClasspath()) {
+ final VirtualFile virtualFile = localFileSystem.refreshAndFindFileByPath(path);
+ if (virtualFile != null) {
+ ContainerUtil.addIfNotNull(
+ projectBuildClasspath, virtualFile.isDirectory() ? virtualFile : jarFileSystem.getJarRootForLocalFile(virtualFile));
+ }
+ }
+
+ for (ExternalModuleBuildClasspathPojo moduleBuildClasspathPojo : projectBuildClasspathPojo.getModulesBuildClasspath().values()) {
+ List<VirtualFile> moduleBuildClasspath = ContainerUtil.newArrayList(projectBuildClasspath);
+ for (String path : moduleBuildClasspathPojo.getEntries()) {
+ final VirtualFile virtualFile = localFileSystem.refreshAndFindFileByPath(path);
+ if (virtualFile != null) {
+ ContainerUtil.addIfNotNull(moduleBuildClasspath, jarFileSystem.getJarRootForLocalFile(virtualFile));
+ }
+ }
+
+ map.put(moduleBuildClasspathPojo.getPath(), moduleBuildClasspath);
+ }
+ }
+
+ myClasspathMap.set(map);
+
+ Set<VirtualFile> set = new LinkedHashSet<VirtualFile>();
+ for (List<VirtualFile> virtualFiles : myClasspathMap.get().values()) {
+ set.addAll(virtualFiles);
+ }
+ allFilesCache = ContainerUtil.newArrayList(set);
+ }
+
+ @NotNull
+ public List<VirtualFile> getAllClasspathEntries() {
+ return allFilesCache;
+ }
+
+ @NotNull
+ public List<VirtualFile> getModuleClasspathEntries(@NotNull String externalModulePath) {
+ List<VirtualFile> virtualFiles = myClasspathMap.get().get(externalModulePath);
+ return virtualFiles == null ? Collections.<VirtualFile>emptyList() : virtualFiles;
+ }
+}
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 715db5a94015..95fdb0a7f244 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java
@@ -10,6 +10,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
import org.gradle.StartParameter;
@@ -49,6 +50,9 @@ public class GradleInstallationManager {
public static final Pattern GRADLE_JAR_FILE_PATTERN;
public static final Pattern ANY_GRADLE_JAR_FILE_PATTERN;
+ public static final Pattern ANT_JAR_PATTERN = Pattern.compile("ant(-(.*))?\\.jar");
+ public static final Pattern IVY_JAR_PATTERN = Pattern.compile("ivy(-(.*))?\\.jar");
+
private static final String[] GRADLE_START_FILE_NAMES;
@NonNls private static final String GRADLE_ENV_PROPERTY_NAME;
@@ -375,57 +379,83 @@ public class GradleInstallationManager {
*/
@Nullable
public List<VirtualFile> getClassRoots(@Nullable Project project) {
+ List<File> files = getClassRoots(project, null);
+ if(files == null) return null;
+ final LocalFileSystem localFileSystem = LocalFileSystem.getInstance();
+ final JarFileSystem jarFileSystem = JarFileSystem.getInstance();
+ return ContainerUtil.mapNotNull(files, new Function<File, VirtualFile>() {
+ @Override
+ public VirtualFile fun(File file) {
+ final VirtualFile virtualFile = localFileSystem.refreshAndFindFileByIoFile(file);
+ return virtualFile != null ? jarFileSystem.getJarRootForLocalFile(virtualFile) : null;
+ }
+ });
+ }
+
+ @Nullable
+ public List<File> getClassRoots(@Nullable Project project, @Nullable String rootProjectPath) {
if (project == null) return null;
- for (Module module : myPlatformFacade.getModules(project)) {
- String rootProjectPath = module.getOptionValue(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY);
- if (StringUtil.isEmpty(rootProjectPath)) {
- continue;
+ if(rootProjectPath == null) {
+ for (Module module : myPlatformFacade.getModules(project)) {
+ rootProjectPath = module.getOptionValue(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY);
+ List<File> result = findGradleSdkClasspath(project, rootProjectPath);
+ if(!result.isEmpty()) return result;
}
- File gradleHome = getGradleHome(module.getProject(), rootProjectPath);
+ } else {
+ return findGradleSdkClasspath(project, rootProjectPath);
+ }
- if (gradleHome == null || !gradleHome.isDirectory()) {
- continue;
- }
+ return null;
+ }
- final Collection<File> libraries = getAllLibraries(gradleHome);
- if (libraries == null) {
- continue;
- }
- final LocalFileSystem localFileSystem = LocalFileSystem.getInstance();
- final JarFileSystem jarFileSystem = JarFileSystem.getInstance();
- List<VirtualFile> result = new ArrayList<VirtualFile>();
- for (File file : libraries) {
- if (ANY_GRADLE_JAR_FILE_PATTERN.matcher(file.getName()).matches() || GroovyConfigUtils.matchesGroovyAll(file.getName())) {
- final VirtualFile virtualFile = localFileSystem.refreshAndFindFileByIoFile(file);
- if (virtualFile != null) {
- ContainerUtil.addIfNotNull(result, jarFileSystem.getJarRootForLocalFile(virtualFile));
- }
- }
- }
+ private List<File> findGradleSdkClasspath(Project project, String rootProjectPath) {
+ List<File> result = new ArrayList<File>();
- File src = new File(gradleHome, "src");
- if (src.isDirectory()) {
- if(new File(src, "org").isDirectory()) {
- addRoots(localFileSystem, result, src);
- } else {
- addRoots(localFileSystem, result, src.listFiles());
- }
- }
+ if (StringUtil.isEmpty(rootProjectPath)) return result;
+
+ File gradleHome = getGradleHome(project, rootProjectPath);
+ if (gradleHome == null || !gradleHome.isDirectory()) {
return result;
}
- return null;
+
+ final Collection<File> libraries = getAllLibraries(gradleHome);
+ if (libraries == null) {
+ return result;
+ }
+
+ for (File file : libraries) {
+ if (isGradleBuildClasspathLibrary(file)) {
+ ContainerUtil.addIfNotNull(result, file);
+ }
+ }
+
+ File src = new File(gradleHome, "src");
+ if (src.isDirectory()) {
+ if(new File(src, "org").isDirectory()) {
+ addRoots(result, src);
+ } else {
+ addRoots(result, src.listFiles());
+ }
+ }
+
+ return result;
+ }
+
+ private boolean isGradleBuildClasspathLibrary(File file) {
+ String fileName = file.getName();
+ return ANY_GRADLE_JAR_FILE_PATTERN.matcher(fileName).matches()
+ || ANT_JAR_PATTERN.matcher(fileName).matches()
+ || IVY_JAR_PATTERN.matcher(fileName).matches()
+ || GroovyConfigUtils.matchesGroovyAll(fileName);
}
- private void addRoots(@NotNull LocalFileSystem localFileSystem, @NotNull List<VirtualFile> result, @Nullable File... files) {
- if(files == null) return;
+ private void addRoots(@NotNull List<File> result, @Nullable File... files) {
+ if (files == null) return;
for (File file : files) {
- if(file == null || !file.isDirectory()) continue;
- final VirtualFile virtualFile = localFileSystem.refreshAndFindFileByIoFile(file);
- if (virtualFile != null) {
- result.add(0, virtualFile);
- }
+ if (file == null || !file.isDirectory()) continue;
+ result.add(0, file);
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
index 0a28fccd3347..b2eb6a0e089e 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
@@ -35,8 +35,10 @@ import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.roots.DependencyScope;
import com.intellij.openapi.util.KeyValue;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.util.BooleanFunction;
+import com.intellij.util.Function;
import com.intellij.util.PathUtil;
import com.intellij.util.PathsList;
import com.intellij.util.containers.ContainerUtil;
@@ -51,9 +53,9 @@ import org.gradle.tooling.model.idea.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.gradle.model.ExtIdeaContentRoot;
-import org.jetbrains.plugins.gradle.model.ModuleExtendedModel;
-import org.jetbrains.plugins.gradle.model.ProjectDependenciesModel;
+import org.jetbrains.plugins.gradle.model.*;
+import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData;
+import org.jetbrains.plugins.gradle.model.data.ClasspathEntry;
import org.jetbrains.plugins.gradle.util.GradleBundle;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import org.jetbrains.plugins.gradle.util.GradleUtil;
@@ -132,14 +134,16 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
"Creating module data ('%s') with the external config path: '%s'", gradleModule.getGradleProject().getPath(), moduleConfigPath
));
}
- ModuleData moduleData = new ModuleData(gradleModule.getGradleProject().getPath(),
+
+ final String path = gradleModule.getGradleProject().getPath();
+ final ModuleData moduleData = new ModuleData(StringUtil.isEmpty(path) || ":".equals(path) ? moduleName : path,
GradleConstants.SYSTEM_ID,
StdModuleTypes.JAVA.getId(),
moduleName,
moduleConfigPath,
moduleConfigPath);
- ModuleExtendedModel moduleExtendedModel = resolverCtx.getExtraProject(gradleModule, ModuleExtendedModel.class);
+ final ModuleExtendedModel moduleExtendedModel = resolverCtx.getExtraProject(gradleModule, ModuleExtendedModel.class);
if (moduleExtendedModel != null) {
moduleData.setGroup(moduleExtendedModel.getGroup());
moduleData.setVersion(moduleExtendedModel.getVersion());
@@ -150,6 +154,19 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
@Override
public void populateModuleExtraModels(@NotNull IdeaModule gradleModule, @NotNull DataNode<ModuleData> ideModule) {
+ BuildScriptClasspathModel buildScriptClasspathModel = resolverCtx.getExtraProject(gradleModule, BuildScriptClasspathModel.class);
+ if (buildScriptClasspathModel != null) {
+ List<ClasspathEntry> classpathEntries =
+ ContainerUtil.map(buildScriptClasspathModel.getClasspath(), new Function<ClasspathEntryModel, ClasspathEntry>() {
+ @Override
+ public ClasspathEntry fun(ClasspathEntryModel model) {
+ return new ClasspathEntry(model.getClassesFile(), model.getSourcesFile(), model.getJavadocFile());
+ }
+ });
+ BuildScriptClasspathData buildScriptClasspathData =
+ new BuildScriptClasspathData(GradleConstants.SYSTEM_ID, classpathEntries);
+ ideModule.createChild(BuildScriptClasspathData.KEY, buildScriptClasspathData);
+ }
}
@Override
@@ -289,7 +306,7 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
@NotNull
@Override
public Set<Class> getExtraProjectModelClasses() {
- return ContainerUtil.<Class>set(ModuleExtendedModel.class, ProjectDependenciesModel.class);
+ return ContainerUtil.<Class>set(ModuleExtendedModel.class, ProjectDependenciesModel.class, BuildScriptClasspathModel.class);
}
@NotNull
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 e4ae7b389306..39dfe9afdbe5 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
@@ -355,22 +355,46 @@ public class GradleExecutionHelper {
}
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
- public static void setInitScript(LongRunningOperation longRunningOperation) {
+ public static boolean setInitScript(@NotNull LongRunningOperation longRunningOperation, boolean isBuildSrcProject) {
try {
InputStream stream = GradleProjectResolver.class.getResourceAsStream("/org/jetbrains/plugins/gradle/model/internal/init.gradle");
- if (stream == null) return;
+ if (stream == null) return isBuildSrcProject;
String jarPath = PathUtil.getCanonicalPath(PathUtil.getJarPathForClass(GradleProjectResolver.class));
String s = FileUtil.loadTextAndClose(stream).replace("${JAR_PATH}", jarPath);
+ if(isBuildSrcProject) {
+ String buildSrcDefaultInitScript = getBuildSrcDefaultInitScript();
+ if(buildSrcDefaultInitScript == null) return false;
+ s += buildSrcDefaultInitScript;
+ }
+
final File tempFile = FileUtil.createTempFile("ijinit", '.' + GradleConstants.EXTENSION, true);
FileUtil.writeToFile(tempFile, s);
String[] buildExecutorArgs = new String[]{"--init-script", tempFile.getAbsolutePath()};
longRunningOperation.withArguments(buildExecutorArgs);
+
+ return true;
+ }
+ catch (Exception e) {
+ LOG.warn("Can't use IJ gradle init script", e);
+ return false;
+ }
+ }
+
+ @Nullable
+ @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
+ public static String getBuildSrcDefaultInitScript() {
+ try {
+ InputStream stream = GradleProjectResolver.class.getResourceAsStream("/org/jetbrains/plugins/gradle/model/internal/buildSrcInit.gradle");
+ if (stream == null) return null;
+
+ return FileUtil.loadTextAndClose(stream);
}
catch (Exception e) {
LOG.warn("Can't use IJ gradle init script", e);
+ return null;
}
}
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 1b1997b048a2..29a27ba94c0f 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
@@ -32,6 +32,7 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemDebugEnvironment;
import com.intellij.openapi.util.KeyValue;
import com.intellij.openapi.util.Pair;
+import com.intellij.util.BooleanFunction;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
@@ -52,6 +53,7 @@ import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import org.jetbrains.plugins.gradle.util.GradleEnvironment;
+import java.io.File;
import java.util.*;
/**
@@ -110,19 +112,19 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
projectResolverChain = new BaseGradleProjectResolverExtension();
}
- return myHelper.execute(projectPath, settings, new Function<ProjectConnection, DataNode<ProjectData>>() {
- @Override
- public DataNode<ProjectData> fun(ProjectConnection connection) {
- try {
- return doResolveProjectInfo(
- new ProjectResolverContext(id, projectPath, settings, connection, listener, isPreviewMode), projectResolverChain);
- }
- catch (RuntimeException e) {
- LOG.info("Gradle project resolve error", e);
- throw projectResolverChain.getUserFriendlyError(e, projectPath, null);
- }
- }
- });
+ final DataNode<ProjectData> resultProjectDataNode = myHelper.execute(
+ projectPath, settings,
+ new ProjectConnectionDataNodeFunction(
+ id, projectPath, settings, listener, isPreviewMode, projectResolverChain, false)
+ );
+
+ // auto-discover buildSrc project if needed
+ final String buildSrcProjectPath = projectPath + "/buildSrc";
+ handleBuildSrcProject(
+ resultProjectDataNode,
+ new ProjectConnectionDataNodeFunction(id, buildSrcProjectPath, settings, listener, isPreviewMode, projectResolverChain, true)
+ );
+ return resultProjectDataNode;
}
@Override
@@ -133,7 +135,8 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
@NotNull
private DataNode<ProjectData> doResolveProjectInfo(@NotNull final ProjectResolverContext resolverCtx,
- @NotNull final GradleProjectResolverExtension projectResolverChain)
+ @NotNull final GradleProjectResolverExtension projectResolverChain,
+ boolean isBuildSrcProject)
throws IllegalArgumentException, IllegalStateException {
final ProjectImportAction projectImportAction = new ProjectImportAction(resolverCtx.isPreviewMode());
@@ -162,7 +165,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
// TODO [vlad] remove the check
if (!GradleEnvironment.DISABLE_ENHANCED_TOOLING_API) {
- GradleExecutionHelper.setInitScript(buildActionExecutor);
+ GradleExecutionHelper.setInitScript(buildActionExecutor, isBuildSrcProject);
}
ProjectImportAction.AllModels allModels;
@@ -242,8 +245,10 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
projectResolverChain.populateModuleContentRoots(ideaModule, moduleDataNode);
projectResolverChain.populateModuleCompileOutputSettings(ideaModule, moduleDataNode);
projectResolverChain.populateModuleDependencies(ideaModule, moduleDataNode, projectDataNode);
- final Collection<TaskData> moduleTasks = projectResolverChain.populateModuleTasks(ideaModule, moduleDataNode, projectDataNode);
- allTasks.addAll(moduleTasks);
+ if(!isBuildSrcProject) {
+ final Collection<TaskData> moduleTasks = projectResolverChain.populateModuleTasks(ideaModule, moduleDataNode, projectDataNode);
+ allTasks.addAll(moduleTasks);
+ }
}
// populate root project tasks
@@ -275,4 +280,78 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
return null;
}
}
+
+ private void handleBuildSrcProject(@NotNull final DataNode<ProjectData> resultProjectDataNode,
+ @NotNull final ProjectConnectionDataNodeFunction projectConnectionDataNodeFunction) {
+
+ if (projectConnectionDataNodeFunction.myIsPreviewMode || GradleEnvironment.DISABLE_ENHANCED_TOOLING_API ||
+ !new File(projectConnectionDataNodeFunction.myProjectPath).isDirectory()) return;
+
+ final DataNode<ModuleData> buildSrcModuleDataNode =
+ ExternalSystemApiUtil.find(resultProjectDataNode, ProjectKeys.MODULE, new BooleanFunction<DataNode<ModuleData>>() {
+ @Override
+ public boolean fun(DataNode<ModuleData> node) {
+ return projectConnectionDataNodeFunction.myProjectPath.equals(node.getData().getLinkedExternalProjectPath());
+ }
+ });
+
+ // check if buildSrc project was already exposed in settings.gradle file
+ if (buildSrcModuleDataNode != null) return;
+
+ final DataNode<ProjectData> buildSrcProjectDataDataNode = myHelper.execute(
+ projectConnectionDataNodeFunction.myProjectPath, projectConnectionDataNodeFunction.mySettings, projectConnectionDataNodeFunction);
+
+ if (buildSrcProjectDataDataNode != null) {
+ final DataNode<ModuleData> moduleDataNode = ExternalSystemApiUtil.find(buildSrcProjectDataDataNode, ProjectKeys.MODULE);
+ if (moduleDataNode != null) {
+ for (DataNode<LibraryData> libraryDataNode : ExternalSystemApiUtil.findAll(buildSrcProjectDataDataNode, ProjectKeys.LIBRARY)) {
+ resultProjectDataNode.createChild(libraryDataNode.getKey(), libraryDataNode.getData());
+ }
+
+ final DataNode<ModuleData> newModuleDataNode = resultProjectDataNode.createChild(ProjectKeys.MODULE, moduleDataNode.getData());
+ for (DataNode node : moduleDataNode.getChildren()) {
+ newModuleDataNode.createChild(node.getKey(), node.getData());
+ }
+ }
+ }
+ }
+
+ private class ProjectConnectionDataNodeFunction implements Function<ProjectConnection, DataNode<ProjectData>> {
+ @NotNull private final ExternalSystemTaskId myId;
+ @NotNull private final String myProjectPath;
+ @Nullable private final GradleExecutionSettings mySettings;
+ @NotNull private final ExternalSystemTaskNotificationListener myListener;
+ private final boolean myIsPreviewMode;
+ @NotNull private final GradleProjectResolverExtension myProjectResolverChain;
+ private final boolean myIsBuildSrcProject;
+
+ public ProjectConnectionDataNodeFunction(@NotNull ExternalSystemTaskId id,
+ @NotNull String projectPath,
+ @Nullable GradleExecutionSettings settings,
+ @NotNull ExternalSystemTaskNotificationListener listener,
+ boolean isPreviewMode,
+ @NotNull GradleProjectResolverExtension projectResolverChain,
+ boolean isBuildSrcProject) {
+ myId = id;
+ myProjectPath = projectPath;
+ mySettings = settings;
+ myListener = listener;
+ myIsPreviewMode = isPreviewMode;
+ myProjectResolverChain = projectResolverChain;
+ myIsBuildSrcProject = isBuildSrcProject;
+ }
+
+ @Override
+ public DataNode<ProjectData> fun(ProjectConnection connection) {
+ try {
+ return doResolveProjectInfo(
+ new ProjectResolverContext(myId, myProjectPath, mySettings, connection, myListener, myIsPreviewMode),
+ myProjectResolverChain, myIsBuildSrcProject);
+ }
+ catch (RuntimeException e) {
+ LOG.info("Gradle project resolve error", e);
+ throw myProjectResolverChain.getUserFriendlyError(e, myProjectPath, null);
+ }
+ }
+ }
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleStartupActivity.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleStartupActivity.java
index 623a79736028..fc4805e81058 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleStartupActivity.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleStartupActivity.java
@@ -30,6 +30,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager;
import org.jetbrains.plugins.gradle.service.project.wizard.GradleProjectImportBuilder;
import org.jetbrains.plugins.gradle.service.project.wizard.GradleProjectImportProvider;
import org.jetbrains.plugins.gradle.settings.GradleSettings;
@@ -52,9 +53,14 @@ public class GradleStartupActivity implements StartupActivity {
@Override
public void runActivity(@NotNull Project project) {
+ configureBuildClasspath(project);
showNotificationForUnlinkedGradleProject(project);
}
+ private static void configureBuildClasspath(@NotNull final Project project) {
+ GradleBuildClasspathManager.getInstance(project).reload();
+ }
+
private static void showNotificationForUnlinkedGradleProject(@NotNull final Project project) {
if (!PropertiesComponent.getInstance(project).getBoolean(SHOW_UNLINKED_GRADLE_POPUP, true)
|| !GradleSettings.getInstance(project).getLinkedProjectsSettings().isEmpty()
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/BuildClasspathModuleGradleDataService.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/BuildClasspathModuleGradleDataService.java
new file mode 100644
index 000000000000..907f2903ef09
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/BuildClasspathModuleGradleDataService.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2000-2014 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.data;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.externalSystem.ExternalSystemManager;
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.Key;
+import com.intellij.openapi.externalSystem.model.ProjectKeys;
+import com.intellij.openapi.externalSystem.model.project.ExternalModuleBuildClasspathPojo;
+import com.intellij.openapi.externalSystem.model.project.ExternalProjectBuildClasspathPojo;
+import com.intellij.openapi.externalSystem.model.project.ModuleData;
+import com.intellij.openapi.externalSystem.model.project.ProjectData;
+import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataService;
+import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
+import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
+import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
+import com.intellij.openapi.externalSystem.util.Order;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.FactoryMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData;
+import org.jetbrains.plugins.gradle.model.data.ClasspathEntry;
+import org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager;
+import org.jetbrains.plugins.gradle.service.GradleInstallationManager;
+import org.jetbrains.plugins.gradle.settings.GradleProjectSettings;
+import org.jetbrains.plugins.gradle.settings.GradleSettings;
+import org.jetbrains.plugins.gradle.util.GradleConstants;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 8/27/13
+ */
+@Order(ExternalSystemConstants.UNORDERED)
+public class BuildClasspathModuleGradleDataService implements ProjectDataService<BuildScriptClasspathData, Module> {
+
+ @NotNull
+ @Override
+ public Key<BuildScriptClasspathData> getTargetDataKey() {
+ return BuildScriptClasspathData.KEY;
+ }
+
+ @Override
+ public void importData(@NotNull final Collection<DataNode<BuildScriptClasspathData>> toImport,
+ @NotNull final Project project,
+ boolean synchronous) {
+ if (toImport.isEmpty()) {
+ return;
+ }
+ if (!project.isInitialized()) {
+ return;
+ }
+
+ final GradleInstallationManager gradleInstallationManager = ServiceManager.getService(GradleInstallationManager.class);
+
+ ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(GradleConstants.SYSTEM_ID);
+ assert manager != null;
+ AbstractExternalSystemLocalSettings localSettings = manager.getLocalSettingsProvider().fun(project);
+
+ //noinspection MismatchedQueryAndUpdateOfCollection
+ Map<String/* externalProjectPath */, Set<String>> externalProjectGradleSdkLibs = new FactoryMap<String, Set<String>>() {
+ @Nullable
+ @Override
+ protected Set<String> create(String externalProjectPath) {
+ GradleProjectSettings settings = GradleSettings.getInstance(project).getLinkedProjectSettings(externalProjectPath);
+ if (settings == null || settings.getDistributionType() == null) return null;
+
+ final Set<String> gradleSdkLibraries = ContainerUtil.newHashSet();
+ File gradleHome =
+ gradleInstallationManager.getGradleHome(settings.getDistributionType(), externalProjectPath, settings.getGradleHome());
+ if (gradleHome != null && gradleHome.isDirectory()) {
+
+ final Collection<File> libraries = gradleInstallationManager.getClassRoots(project, externalProjectPath);
+ if (libraries != null) {
+ for (File library : libraries) {
+ gradleSdkLibraries.add(FileUtil.toCanonicalPath(library.getPath()));
+ }
+ }
+ }
+ return gradleSdkLibraries;
+ }
+ };
+
+ for (final DataNode<BuildScriptClasspathData> node : toImport) {
+ if (GradleConstants.SYSTEM_ID.equals(node.getData().getOwner())) {
+
+
+ DataNode<ProjectData> projectDataNode = ExternalSystemApiUtil.findParent(node, ProjectKeys.PROJECT);
+ assert projectDataNode != null;
+
+ String linkedExternalProjectPath = projectDataNode.getData().getLinkedExternalProjectPath();
+ DataNode<ModuleData> moduleDataNode = ExternalSystemApiUtil.findParent(node, ProjectKeys.MODULE);
+ if (moduleDataNode == null) continue;
+
+ String externalModulePath = moduleDataNode.getData().getLinkedExternalProjectPath();
+ GradleProjectSettings settings = GradleSettings.getInstance(project).getLinkedProjectSettings(linkedExternalProjectPath);
+ if (settings == null || settings.getDistributionType() == null) continue;
+
+ final Set<String> buildClasspath = ContainerUtil.newHashSet();
+ BuildScriptClasspathData buildScriptClasspathData = node.getData();
+ for (ClasspathEntry classpathEntry : buildScriptClasspathData.getClasspathEntries()) {
+ if (classpathEntry.getSourcesFile() != null) {
+ buildClasspath.add(FileUtil.toCanonicalPath(classpathEntry.getSourcesFile().getPath()));
+ }
+ else {
+ buildClasspath.add(FileUtil.toCanonicalPath(classpathEntry.getClassesFile().getPath()));
+ }
+ }
+
+ ExternalProjectBuildClasspathPojo projectBuildClasspathPojo =
+ localSettings.getProjectBuildClasspath().get(linkedExternalProjectPath);
+ if (projectBuildClasspathPojo == null) {
+ projectBuildClasspathPojo = new ExternalProjectBuildClasspathPojo(
+ moduleDataNode.getData().getExternalName(),
+ ContainerUtil.<String>newArrayList(),
+ ContainerUtil.<String, ExternalModuleBuildClasspathPojo>newHashMap());
+ localSettings.getProjectBuildClasspath().put(linkedExternalProjectPath, projectBuildClasspathPojo);
+ }
+
+ List<String> projectBuildClasspath = ContainerUtil.newArrayList(externalProjectGradleSdkLibs.get(linkedExternalProjectPath));
+ // add main java root of buildSrc project
+ projectBuildClasspath.add(linkedExternalProjectPath + "/buildSrc/src/main/java");
+ // add main groovy root of buildSrc project
+ projectBuildClasspath.add(linkedExternalProjectPath + "/buildSrc/src/main/groovy");
+
+ projectBuildClasspathPojo.setProjectBuildClasspath(projectBuildClasspath);
+ projectBuildClasspathPojo.getModulesBuildClasspath().put(
+ externalModulePath, new ExternalModuleBuildClasspathPojo(externalModulePath, ContainerUtil.newArrayList(buildClasspath)));
+ }
+ }
+
+ GradleBuildClasspathManager.getInstance(project).reload();
+ }
+
+ @Override
+ public void removeData(@NotNull Collection<? extends Module> toRemove, @NotNull Project project, boolean synchronous) {
+ }
+}
diff --git a/plugins/gradle/testData/testAddMavenDependencyInEmptyFile.gradle b/plugins/gradle/testData/testAddMavenDependencyInEmptyFile.gradle
index f90814d636ed..e69de29bb2d1 100644
--- a/plugins/gradle/testData/testAddMavenDependencyInEmptyFile.gradle
+++ b/plugins/gradle/testData/testAddMavenDependencyInEmptyFile.gradle
@@ -1 +0,0 @@
-//empty file \ No newline at end of file
diff --git a/plugins/gradle/testData/testAddMavenDependencyInEmptyFile_after.gradle b/plugins/gradle/testData/testAddMavenDependencyInEmptyFile_after.gradle
index aa2892d73dc4..54c09742fd5c 100644
--- a/plugins/gradle/testData/testAddMavenDependencyInEmptyFile_after.gradle
+++ b/plugins/gradle/testData/testAddMavenDependencyInEmptyFile_after.gradle
@@ -1,4 +1,3 @@
-//empty file
dependencies{
compile 'testGroupId:testArtifactId:1.0'
} \ No newline at end of file
diff --git a/plugins/gradle/testData/testDefaultDependenciesModel/build.gradle b/plugins/gradle/testData/testDefaultDependenciesModel/build.gradle
index 849b1b486dd2..a6c9dde56871 100644
--- a/plugins/gradle/testData/testDefaultDependenciesModel/build.gradle
+++ b/plugins/gradle/testData/testDefaultDependenciesModel/build.gradle
@@ -4,8 +4,8 @@ allprojects{
apply plugin: 'java'
}
-project(":group2:subgroup11:project") {
+project("dependentProject") {
dependencies {
- compile project(":project")
+ compile project(":dependencyProject")
}
} \ No newline at end of file
diff --git a/plugins/gradle/testData/testDefaultDependenciesModel/settings.gradle b/plugins/gradle/testData/testDefaultDependenciesModel/settings.gradle
index cf870fe6d6d1..ef853f062e1c 100644
--- a/plugins/gradle/testData/testDefaultDependenciesModel/settings.gradle
+++ b/plugins/gradle/testData/testDefaultDependenciesModel/settings.gradle
@@ -1,5 +1,4 @@
//noinspection GrPackage
-include 'group1:subgroup11:project'
-include 'group2:subgroup11:project'
-include 'project' \ No newline at end of file
+include 'dependencyProject'
+include 'dependentProject' \ No newline at end of file
diff --git a/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle
index 6f9afa4b8d09..73cb6a15b5cd 100644
--- a/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle
+++ b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle
@@ -27,7 +27,7 @@ allprojects {
project(":service") {
dependencies {
- compile (project(':api'))
+ compile(project(':api'))
}
}
@@ -35,4 +35,21 @@ project(":api") {
dependencies {
provided(project(':lib'))
}
-} \ No newline at end of file
+}
+
+project(":withIdeaModelCustomisations") {
+ dependencies {
+ //compile 'org.slf4j:slf4j-api:1.7.5'
+ //testCompile 'junit:junit:4.11'
+
+ compile files("lib/someDep.jar")
+ testCompile files("lib/someTestDep.jar")
+ }
+
+ idea {
+ module {
+ scopes.COMPILE.plus += scopes.TEST.plus
+ scopes.TEST.plus = []
+ }
+ }
+}
diff --git a/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle
index 271f7343d37b..26ee835a9fb1 100644
--- a/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle
+++ b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle
@@ -1,4 +1,5 @@
//noinspection GrPackage
include "lib"
include "api"
-include "service" \ No newline at end of file
+include "service"
+include "withIdeaModelCustomisations" \ No newline at end of file
diff --git a/plugins/gradle/testData/testGradleSourcesSetsInterpretation/build.gradle b/plugins/gradle/testData/testGradleSourcesSetsInterpretation/build.gradle
new file mode 100644
index 000000000000..8c7584942858
--- /dev/null
+++ b/plugins/gradle/testData/testGradleSourcesSetsInterpretation/build.gradle
@@ -0,0 +1,74 @@
+//noinspection GrPackage
+
+project("defaultJavaModule") {
+ apply plugin: "java"
+}
+
+project("moduleWithSourceSetDirBothAsResourceAndJava") {
+ apply plugin: "java"
+
+ sourceSets.main.resources.srcDir 'src/main/java'
+ sourceSets.test.resources.srcDir 'src/test/java'
+}
+
+project("moduleWithCustomSourceSet") {
+ apply plugin: "java"
+
+ sourceSets {
+ custom
+ }
+
+ sourceSets.custom.java.srcDir 'src/custom/java'
+}
+
+project("withIntegrationTests") {
+ apply plugin: 'java'
+
+ sourceSets {
+ integrationTest {
+ java.srcDir file('src/integration-test/java')
+ resources.srcDir file('src/integration-test/resources')
+ }
+ }
+
+ dependencies {
+ integrationTestCompile sourceSets.main.output
+ integrationTestCompile configurations.testCompile
+ integrationTestCompile sourceSets.test.output
+ integrationTestRuntime configurations.testRuntime
+ }
+
+ //noinspection GrUnresolvedAccess
+ task integrationTest(type: Test, dependsOn: jar) {
+ testClassesDir = sourceSets.integrationTest.output.classesDir
+ classpath = sourceSets.integrationTest.runtimeClasspath
+ }
+
+ check.dependsOn integrationTest
+}
+
+project("withIdeaPluginCustomization1") {
+ apply plugin: 'java'
+
+ idea {
+ module {
+ testSourceDirs += file('src/intTest/java')
+ testSourceDirs += file('src/intTest/resources')
+ excludeDirs += file('some-extra-exclude-folder')
+ }
+ }
+}
+
+// see http://youtrack.jetbrains.com/issue/IDEA-119365
+project("withIdeaPluginCustomization2") {
+ apply plugin: 'java'
+
+ idea {
+ module {
+ sourceDirs += testSourceDirs
+ testSourceDirs = []
+ ext.resourceDirs += file('some-extra-resource-folder')
+ ext.testResourceDirs += file('some-extra-test-resource-folder')
+ }
+ }
+}
diff --git a/plugins/gradle/testData/testGradleSourcesSetsInterpretation/settings.gradle b/plugins/gradle/testData/testGradleSourcesSetsInterpretation/settings.gradle
new file mode 100644
index 000000000000..4f7ab785f8fd
--- /dev/null
+++ b/plugins/gradle/testData/testGradleSourcesSetsInterpretation/settings.gradle
@@ -0,0 +1,8 @@
+//noinspection GrPackage
+
+include 'defaultJavaModule'
+include 'moduleWithSourceSetDirBothAsResourceAndJava'
+include 'moduleWithCustomSourceSet'
+include 'withIntegrationTests'
+include 'withIdeaPluginCustomization1'
+include 'withIdeaPluginCustomization2' \ No newline at end of file
diff --git a/plugins/gradle/testData/testModelBuildScriptClasspathBuilder/build.gradle b/plugins/gradle/testData/testModelBuildScriptClasspathBuilder/build.gradle
new file mode 100644
index 000000000000..5b09fca15f4d
--- /dev/null
+++ b/plugins/gradle/testData/testModelBuildScriptClasspathBuilder/build.gradle
@@ -0,0 +1,9 @@
+//noinspection GrPackage
+
+project("moduleWithAdditionalClasspath") {
+ buildscript {
+ dependencies {
+ classpath files("lib/someDep.jar")
+ }
+ }
+}
diff --git a/plugins/gradle/testData/testModelBuildScriptClasspathBuilder/settings.gradle b/plugins/gradle/testData/testModelBuildScriptClasspathBuilder/settings.gradle
new file mode 100644
index 000000000000..02978875f494
--- /dev/null
+++ b/plugins/gradle/testData/testModelBuildScriptClasspathBuilder/settings.gradle
@@ -0,0 +1,4 @@
+//noinspection GrPackage
+
+include 'moduleWithoutAdditionalClasspath'
+include 'moduleWithAdditionalClasspath'
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java
index 835d7305bd1b..0cdd2f032b78 100644
--- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java
@@ -73,7 +73,7 @@ public abstract class AbstractModelBuilderTest {
final ProjectImportAction projectImportAction = new ProjectImportAction(true);
projectImportAction.addExtraProjectModelClasses(getModels());
BuildActionExecuter<ProjectImportAction.AllModels> buildActionExecutor = connection.action(projectImportAction);
- GradleExecutionHelper.setInitScript(buildActionExecutor);
+ GradleExecutionHelper.setInitScript(buildActionExecutor, false);
allModels = buildActionExecutor.run();
assertNotNull(allModels);
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelBuildScriptClasspathBuilderImplTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelBuildScriptClasspathBuilderImplTest.java
new file mode 100644
index 000000000000..d812d8df6a68
--- /dev/null
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelBuildScriptClasspathBuilderImplTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model.builder;
+
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.gradle.tooling.model.DomainObjectSet;
+import org.gradle.tooling.model.idea.IdeaModule;
+import org.jetbrains.plugins.gradle.model.BuildScriptClasspathModel;
+import org.jetbrains.plugins.gradle.model.ClasspathEntryModel;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Set;
+
+import static junit.framework.Assert.*;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 1/16/14
+ */
+public class ModelBuildScriptClasspathBuilderImplTest extends AbstractModelBuilderTest {
+
+ @Test
+ public void testModelBuildScriptClasspathBuilder() throws Exception {
+ ModelBuildScriptClasspathBuilderImpl buildScriptClasspathBuilder = new ModelBuildScriptClasspathBuilderImpl();
+ assertTrue(buildScriptClasspathBuilder.canBuild("org.jetbrains.plugins.gradle.model.BuildScriptClasspathModel"));
+
+ DomainObjectSet<? extends IdeaModule> ideaModules = allModels.getIdeaProject().getModules();
+
+ List<BuildScriptClasspathModel> ideaModule =
+ ContainerUtil.mapNotNull(ideaModules, new Function<IdeaModule, BuildScriptClasspathModel>() {
+ @Override
+ public BuildScriptClasspathModel fun(IdeaModule module) {
+ BuildScriptClasspathModel classpathModel = allModels.getExtraProject(module, BuildScriptClasspathModel.class);
+
+ if (module.getName().equals("moduleWithAdditionalClasspath")) {
+ assertNotNull(classpathModel);
+ assertEquals(1, classpathModel.getClasspath().size());
+
+ ClasspathEntryModel classpathEntry = classpathModel.getClasspath().getAt(0);
+ assertEquals("someDep.jar", classpathEntry.getClassesFile().getName());
+ }
+ else if (module.getName().equals("moduleWithoutAdditionalClasspath") ||
+ module.getName().equals("testModelBuildScriptClasspathBuilder")) {
+ assertNotNull(classpathModel);
+ assertTrue(classpathModel.getClasspath().isEmpty());
+ }
+ else {
+ fail();
+ }
+
+ return classpathModel;
+ }
+ });
+
+ assertEquals(3, ideaModule.size());
+ }
+
+ @Override
+ protected Set<Class> getModels() {
+ return ContainerUtil.<Class>set(BuildScriptClasspathModel.class);
+ }
+}
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImplTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImplTest.java
index 6bb9b6f5eb9c..8cf50ef62af5 100644
--- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImplTest.java
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImplTest.java
@@ -15,19 +15,26 @@
*/
package org.jetbrains.plugins.gradle.model.builder;
-import com.intellij.openapi.util.Condition;
+import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.gradle.tooling.model.DomainObjectSet;
import org.gradle.tooling.model.idea.IdeaDependency;
import org.gradle.tooling.model.idea.IdeaModule;
import org.gradle.tooling.model.idea.IdeaModuleDependency;
+import org.gradle.tooling.model.idea.IdeaSingleEntryLibraryDependency;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.model.GradleDependencyScope;
import org.jetbrains.plugins.gradle.model.ProjectDependenciesModel;
+import org.junit.Assert;
import org.junit.Test;
+import java.util.List;
import java.util.Set;
-import static org.junit.Assert.*;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
/**
* @author Vladislav.Soroka
@@ -42,17 +49,29 @@ public class ModelDependenciesBuilderImplTest extends AbstractModelBuilderTest {
DomainObjectSet<? extends IdeaModule> ideaModules = allModels.getIdeaProject().getModules();
- IdeaModule ideaModule = ContainerUtil.find(ideaModules, new Condition<IdeaModule>() {
- @Override
- public boolean value(IdeaModule module) {
- return module.getName().equals("group2-subgroup11-project");
- }
- });
-
- assertNotNull(ideaModule);
+ final int modulesSize = 3;
+ assertEquals(modulesSize, ideaModules.size());
- DomainObjectSet<? extends IdeaDependency> dependencies = ideaModule.getDependencies();
- assertEquals(1, dependencies.size());
+ for (IdeaModule ideaModule : ideaModules) {
+ if (ideaModule.getName().equals("dependencyProject") ||
+ ideaModule.getName().equals("testDefaultDependenciesModel")) {
+ DomainObjectSet<? extends IdeaDependency> dependencies = ideaModule.getDependencies();
+ assertTrue((dependencies.isEmpty()));
+ }
+ else if (ideaModule.getName().equals("dependentProject")) {
+ DomainObjectSet<? extends IdeaDependency> dependencies = ideaModule.getDependencies();
+ assertEquals(1, dependencies.size());
+ assertTrue(dependencies.getAt(0) instanceof IdeaModuleDependency);
+ IdeaModuleDependency moduleDependency = (IdeaModuleDependency)dependencies.getAt(0);
+
+ assertEquals("dependencyProject", moduleDependency.getDependencyModule().getName());
+ assertEquals("COMPILE", moduleDependency.getScope().getScope());
+ assertTrue(moduleDependency.getExported());
+ }
+ else {
+ fail();
+ }
+ }
}
@Test
@@ -62,44 +81,71 @@ public class ModelDependenciesBuilderImplTest extends AbstractModelBuilderTest {
DomainObjectSet<? extends IdeaModule> ideaModules = allModels.getIdeaProject().getModules();
- // test api module dependencies
- IdeaModule apiModule = ContainerUtil.find(ideaModules, new Condition<IdeaModule>() {
- @Override
- public boolean value(IdeaModule module) {
- return module.getName().equals("api");
+ final int modulesSize = 5;
+ assertEquals(modulesSize, ideaModules.size());
+
+ for (IdeaModule ideaModule : ideaModules) {
+ DomainObjectSet<? extends IdeaDependency> dependencies = ideaModule.getDependencies();
+ if (ideaModule.getName().equals("lib") ||
+ ideaModule.getName().equals("testGradleIdeaPluginPlusScopesDependenciesModel")) {
+ assertTrue((dependencies.isEmpty()));
}
- });
- assertNotNull(apiModule);
+ else if (ideaModule.getName().equals("api")) {
+ assertEquals(1, dependencies.size());
+ IdeaDependency libDependency = dependencies.getAt(0);
+ assertEquals(GradleDependencyScope.PROVIDED.getIdeaMappingName(), libDependency.getScope().getScope().toLowerCase());
+ assertTrue(libDependency instanceof IdeaModuleDependency);
+
+ IdeaModuleDependency libModuleDependency = (IdeaModuleDependency)libDependency;
+ assertNotNull(libModuleDependency.getDependencyModule());
+ assertEquals("lib", libModuleDependency.getDependencyModule().getName());
+ }
+ else if (ideaModule.getName().equals("service")) {
+ assertEquals(1, dependencies.size());
+ IdeaDependency apiDependency = dependencies.getAt(0);
+ assertEquals(GradleDependencyScope.COMPILE.getIdeaMappingName(), apiDependency.getScope().getScope().toLowerCase());
+ assertTrue(apiDependency instanceof IdeaModuleDependency);
+
+ IdeaModuleDependency apiModuleDependency = (IdeaModuleDependency)apiDependency;
+ assertNotNull(apiModuleDependency.getDependencyModule());
+ assertEquals("api", apiModuleDependency.getDependencyModule().getName());
+ }
+ else if (ideaModule.getName().equals("withIdeaModelCustomisations")) {
+
+ assertTrue(findLocalLibraries(dependencies, GradleDependencyScope.TEST_COMPILE.getIdeaMappingName()).isEmpty());
- DomainObjectSet<? extends IdeaDependency> dependencies = apiModule.getDependencies();
- assertEquals(1, dependencies.size());
- IdeaDependency libDependency = dependencies.getAt(0);
- assertEquals(GradleDependencyScope.PROVIDED.name(), libDependency.getScope().getScope());
- assertTrue(libDependency instanceof IdeaModuleDependency);
+ List<IdeaSingleEntryLibraryDependency> libraryDependencies =
+ findLocalLibraries(dependencies, GradleDependencyScope.COMPILE.getIdeaMappingName());
+ assertEquals(2, libraryDependencies.size());
- IdeaModuleDependency libModuleDependency = (IdeaModuleDependency)libDependency;
- assertNotNull(libModuleDependency.getDependencyModule());
- assertEquals("lib", libModuleDependency.getDependencyModule().getName());
+ IdeaSingleEntryLibraryDependency someDep = libraryDependencies.get(0);
+ assertEquals(GradleDependencyScope.COMPILE.getIdeaMappingName(), someDep.getScope().getScope().toLowerCase());
+ assertEquals("someDep.jar", someDep.getFile().getName());
+ IdeaSingleEntryLibraryDependency someTestDep = libraryDependencies.get(1);
+ assertEquals(GradleDependencyScope.COMPILE.getIdeaMappingName(), someTestDep.getScope().getScope().toLowerCase());
+ assertEquals("someTestDep.jar", someTestDep.getFile().getName());
+ }
+ else {
+ fail();
+ }
+ }
+ }
- // test service module dependencies
- IdeaModule serviceModule = ContainerUtil.find(ideaModules, new Condition<IdeaModule>() {
- @Override
- public boolean value(IdeaModule module) {
- return module.getName().equals("service");
+ @NotNull
+ private static List<IdeaSingleEntryLibraryDependency> findLocalLibraries(
+ @NotNull final DomainObjectSet<? extends IdeaDependency> dependencies, @NotNull final String scope) {
+ return ContainerUtil.mapNotNull(
+ dependencies,
+ new Function<IdeaDependency, IdeaSingleEntryLibraryDependency>() {
+ @Override
+ public IdeaSingleEntryLibraryDependency fun(IdeaDependency dependency) {
+ return dependency instanceof IdeaSingleEntryLibraryDependency && scope.equals(dependency.getScope().getScope().toLowerCase())
+ ? (IdeaSingleEntryLibraryDependency)dependency
+ : null;
+ }
}
- });
- assertNotNull(serviceModule);
-
- DomainObjectSet<? extends IdeaDependency> serviceModuleDependencies = serviceModule.getDependencies();
- assertEquals(1, serviceModuleDependencies.size());
- IdeaDependency apiDependency = serviceModuleDependencies.getAt(0);
- assertEquals(GradleDependencyScope.COMPILE.name(), apiDependency.getScope().getScope());
- assertTrue(apiDependency instanceof IdeaModuleDependency);
-
- IdeaModuleDependency apiModuleDependency = (IdeaModuleDependency)apiDependency;
- assertNotNull(apiModuleDependency.getDependencyModule());
- assertEquals("api", apiModuleDependency.getDependencyModule().getName());
+ );
}
@Override
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImplTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImplTest.java
new file mode 100644
index 000000000000..9694c9d37345
--- /dev/null
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImplTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model.builder;
+
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.gradle.tooling.model.DomainObjectSet;
+import org.gradle.tooling.model.idea.IdeaModule;
+import org.gradle.tooling.model.idea.IdeaSourceDirectory;
+import org.jetbrains.plugins.gradle.model.ExtIdeaContentRoot;
+import org.jetbrains.plugins.gradle.model.ModuleExtendedModel;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.fail;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 1/16/14
+ */
+public class ModuleExtendedModelBuilderImplTest extends AbstractModelBuilderTest {
+
+ @Test
+ public void testGradleSourcesSetsInterpretation() throws Exception {
+ final int modulesSize = 7;
+
+ ModuleExtendedModelBuilderImpl moduleExtendedModelBuilder = new ModuleExtendedModelBuilderImpl();
+ assertTrue(moduleExtendedModelBuilder.canBuild("org.jetbrains.plugins.gradle.model.ModuleExtendedModel"));
+
+ DomainObjectSet<? extends IdeaModule> ideaModules = allModels.getIdeaProject().getModules();
+
+ List<ModuleExtendedModel> models =
+ ContainerUtil.mapNotNull(ideaModules, new Function<IdeaModule, ModuleExtendedModel>() {
+ @Override
+ public ModuleExtendedModel fun(IdeaModule module) {
+ ModuleExtendedModel moduleExtendedModel = allModels.getExtraProject(module, ModuleExtendedModel.class);
+
+ assertNotNull(moduleExtendedModel);
+
+ List<String> sourceDirectories = ContainerUtil.newArrayList();
+ List<String> resourceDirectories = ContainerUtil.newArrayList();
+ List<String> testResourceDirectories = ContainerUtil.newArrayList();
+ List<String> testDirectories = ContainerUtil.newArrayList();
+ List<String> excludeDirectories = ContainerUtil.newArrayList();
+
+ fillDirectories(moduleExtendedModel,
+ sourceDirectories, resourceDirectories,
+ testDirectories, testResourceDirectories,
+ excludeDirectories);
+
+ if (module.getName().equals("defaultJavaModule") || module.getName().equals("moduleWithSourceSetDirBothAsResourceAndJava")) {
+ assertEquals(ContainerUtil.newArrayList("src/main/java"), sourceDirectories);
+ assertEquals(ContainerUtil.newArrayList("src/main/resources"), resourceDirectories);
+ assertEquals(ContainerUtil.newArrayList("src/test/java"), testDirectories);
+ assertEquals(ContainerUtil.newArrayList("src/test/resources"), testResourceDirectories);
+ assertEquals(ContainerUtil.newArrayList(".gradle", "build"), excludeDirectories);
+ }
+ else if (module.getName().equals("moduleWithCustomSourceSet")) {
+ assertEquals(ContainerUtil.newArrayList("src/custom/java", "src/main/java"), sourceDirectories);
+ assertEquals(ContainerUtil.newArrayList("src/custom/resources", "src/main/resources"), resourceDirectories);
+ assertEquals(ContainerUtil.newArrayList("src/test/java"), testDirectories);
+ assertEquals(ContainerUtil.newArrayList("src/test/resources"), testResourceDirectories);
+ assertEquals(ContainerUtil.newArrayList(".gradle", "build"), excludeDirectories);
+ }
+ else if (module.getName().equals("withIntegrationTests")) {
+ assertEquals(ContainerUtil.newArrayList("src/main/java"), sourceDirectories);
+ assertEquals(ContainerUtil.newArrayList("src/main/resources"), resourceDirectories);
+ assertEquals(ContainerUtil.newArrayList(
+ "src/integration-test/java", "src/integrationTest/java", "src/test/java"), testDirectories);
+ assertEquals(ContainerUtil.newArrayList(
+ "src/integration-test/resources",
+ "src/integrationTest/resources",
+ "src/test/resources"), testResourceDirectories);
+ assertEquals(ContainerUtil.newArrayList(".gradle", "build"), excludeDirectories);
+ }
+ else if (module.getName().equals("testGradleSourcesSetsInterpretation")) {
+ assertTrue(sourceDirectories.isEmpty());
+ assertTrue(resourceDirectories.isEmpty());
+ assertTrue(testDirectories.isEmpty());
+ assertTrue(testResourceDirectories.isEmpty());
+ assertEquals(ContainerUtil.newArrayList(".gradle", "build"), excludeDirectories);
+ }
+ else if (module.getName().equals("withIdeaPluginCustomization1")) {
+ assertEquals(ContainerUtil.newArrayList("src/main/java"), sourceDirectories);
+ assertEquals(ContainerUtil.newArrayList("src/main/resources"), resourceDirectories);
+ assertEquals(ContainerUtil.newArrayList("src/intTest/java", "src/intTest/resources", "src/test/java"), testDirectories);
+ assertEquals(ContainerUtil.newArrayList("src/test/resources"), testResourceDirectories);
+ assertEquals(ContainerUtil.newArrayList(".gradle", "build", "some-extra-exclude-folder"), excludeDirectories);
+ }
+ else if (module.getName().equals("withIdeaPluginCustomization2")) {
+ assertEquals(ContainerUtil.newArrayList("src/main/java", "src/test/java", "src/test/resources"), sourceDirectories);
+ assertEquals(ContainerUtil.newArrayList("some-extra-resource-folder", "src/main/resources"), resourceDirectories);
+ assertTrue(testDirectories.isEmpty());
+ assertEquals(ContainerUtil.newArrayList("some-extra-test-resource-folder"), testResourceDirectories);
+ assertEquals(ContainerUtil.newArrayList(".gradle", "build"), excludeDirectories);
+ }
+ else {
+ fail();
+ }
+
+ return moduleExtendedModel;
+ }
+ });
+
+ assertEquals(modulesSize, models.size());
+ }
+
+ private void fillDirectories(final ModuleExtendedModel model,
+ List<String> sourceDirectories, List<String> resourceDirectories,
+ List<String> testDirectories, List<String> resourceTestDirectories,
+ List<String> excludeDirectories) {
+ for (ExtIdeaContentRoot contentRoot : model.getContentRoots()) {
+ sourceDirectories.addAll(getAllPaths(contentRoot.getSourceDirectories(), model.getName()));
+ resourceDirectories.addAll(getAllPaths(contentRoot.getResourceDirectories(), model.getName()));
+ testDirectories.addAll(getAllPaths(contentRoot.getTestDirectories(), model.getName()));
+ resourceTestDirectories.addAll(getAllPaths(contentRoot.getTestResourceDirectories(), model.getName()));
+ excludeDirectories.addAll(getAllPaths(contentRoot.getExcludeDirectories(), model.getName()));
+ }
+ }
+
+ private Collection<? extends String> getAllPaths(Collection<? extends File> directories, final String moduleName) {
+ List<String> list = ContainerUtil.map2List(directories, new Function<File, String>() {
+ @Override
+ public String fun(File sourceDirectory) {
+ String path =
+ FileUtil.toCanonicalPath(FileUtil.getRelativePath(new File(testDir, moduleName), sourceDirectory));
+ Assert.assertNotNull(path);
+ return path.substring(path.indexOf("/") + 1);
+ }
+ });
+ Collections.sort(list);
+ return list;
+ }
+
+ private Collection<? extends String> getAllPaths(DomainObjectSet<? extends IdeaSourceDirectory> directories, final String moduleName) {
+ List<String> list = ContainerUtil.map2List(directories, new Function<IdeaSourceDirectory, String>() {
+ @Override
+ public String fun(IdeaSourceDirectory sourceDirectory) {
+ String path =
+ FileUtil.toCanonicalPath(FileUtil.getRelativePath(new File(testDir, moduleName), sourceDirectory.getDirectory()));
+ Assert.assertNotNull(path);
+ return path.substring(path.indexOf("/") + 1);
+ }
+ });
+ Collections.sort(list);
+ return list;
+ }
+
+ @Override
+ protected Set<Class> getModels() {
+ return ContainerUtil.<Class>set(ModuleExtendedModel.class);
+ }
+}
+
diff --git a/plugins/groovy/hotswap/agentSrc/org/groovy/debug/hotswap/ResetAgent.java b/plugins/groovy/hotswap/agentSrc/org/groovy/debug/hotswap/ResetAgent.java
index a3e7023cf8f7..35b3577e258b 100644
--- a/plugins/groovy/hotswap/agentSrc/org/groovy/debug/hotswap/ResetAgent.java
+++ b/plugins/groovy/hotswap/agentSrc/org/groovy/debug/hotswap/ResetAgent.java
@@ -2,6 +2,7 @@ package org.groovy.debug.hotswap;
import org.objectweb.asm.*;
+import java.lang.String;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
@@ -18,7 +19,15 @@ import java.security.ProtectionDomain;
*/
@SuppressWarnings({"UtilityClassWithoutPrivateConstructor", "UnusedDeclaration"})
public class ResetAgent {
- private static final String timStampFieldStart = "__timeStamp__239_neverHappen";
+ private static final String timeStampFieldStart = "__timeStamp__239_neverHappen";
+ private static final byte[] timeStampFieldStartBytes;
+
+ static {
+ timeStampFieldStartBytes = new byte[timeStampFieldStart.length()];
+ for (int i = 0; i < timeStampFieldStart.length(); i++) {
+ timeStampFieldStartBytes[i] = (byte)timeStampFieldStart.charAt(i);
+ }
+ }
private static boolean initialized;
@@ -44,18 +53,30 @@ public class ResetAgent {
});
}
- private static boolean hasTimestampField(byte[] buffer) {
- try {
- return new String(buffer, "ISO-8859-1").contains(timStampFieldStart);
- } catch (Throwable e) {
- return true;
+ private static boolean matches(byte[] array, byte[] subArray, int start) {
+ for (int i = 0; i < subArray.length; i++) {
+ if (array[start + i] != subArray[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static boolean containsSubArray(byte[] array, byte[] subArray) {
+ int maxLength = array.length - subArray.length;
+ for (int i = 0; i < maxLength; i++) {
+ if (matches(array, subArray, i)) {
+ return true;
+ }
}
+ return false;
}
private static byte[] removeTimestampField(byte[] newBytes) {
- if (!hasTimestampField(newBytes)) {
+ if (!containsSubArray(newBytes, timeStampFieldStartBytes)) {
return null;
}
+
final boolean[] changed = new boolean[]{false};
final ClassWriter writer = new ClassWriter(0);
@@ -76,7 +97,7 @@ public class ResetAgent {
@Override
public FieldVisitor visitField(int i, String name, String s1, String s2, Object o) {
- if (name.startsWith(timStampFieldStart)) {
+ if (name.startsWith(timeStampFieldStart)) {
//remove the field
changed[0] = true;
return null;
@@ -92,7 +113,7 @@ public class ResetAgent {
return new MethodAdapter(mw) {
@Override
public void visitFieldInsn(int opCode, String s, String name, String desc) {
- if (name.startsWith(timStampFieldStart) && opCode == Opcodes.PUTSTATIC) {
+ if (name.startsWith(timeStampFieldStart) && opCode == Opcodes.PUTSTATIC) {
visitInsn(Type.LONG_TYPE.getDescriptor().equals(desc) ? Opcodes.POP2 : Opcodes.POP);
} else {
super.visitFieldInsn(opCode, s, name, desc);
diff --git a/plugins/groovy/hotswap/gragent.jar b/plugins/groovy/hotswap/gragent.jar
index 8794d675ad24..b0e17671dfaf 100644
--- a/plugins/groovy/hotswap/gragent.jar
+++ b/plugins/groovy/hotswap/gragent.jar
Binary files differ
diff --git a/plugins/groovy/resources/fileTemplates/code/Spock SetUp Method.groovy.ft b/plugins/groovy/resources/fileTemplates/code/Spock_SetUp_Method.groovy.ft
index 303209e1a46f..303209e1a46f 100644
--- a/plugins/groovy/resources/fileTemplates/code/Spock SetUp Method.groovy.ft
+++ b/plugins/groovy/resources/fileTemplates/code/Spock_SetUp_Method.groovy.ft
diff --git a/plugins/groovy/resources/fileTemplates/code/Spock SetUp Method.groovy.html b/plugins/groovy/resources/fileTemplates/code/Spock_SetUp_Method.groovy.html
index 379785f36c3f..379785f36c3f 100644
--- a/plugins/groovy/resources/fileTemplates/code/Spock SetUp Method.groovy.html
+++ b/plugins/groovy/resources/fileTemplates/code/Spock_SetUp_Method.groovy.html
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/navbar/GrNavBarModelExtension.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/navbar/GrNavBarModelExtension.java
index e5b5681fc4fa..9116dbe42fd2 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/navbar/GrNavBarModelExtension.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/navbar/GrNavBarModelExtension.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
import org.jetbrains.plugins.groovy.GroovyFileType;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
@@ -32,6 +33,12 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini
*/
public class GrNavBarModelExtension extends AbstractNavBarModelExtension {
+ @Nullable
+ @Override
+ public String getPresentableText(Object object) {
+ return null;
+ }
+
@Override
public PsiElement adjustElement(PsiElement psiElement) {
final ProjectFileIndex index = ProjectRootManager.getInstance(psiElement.getProject()).getFileIndex();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockTestFramework.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockTestFramework.java
index b7872dcc9730..9a36c8c83990 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockTestFramework.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockTestFramework.java
@@ -51,7 +51,7 @@ public class SpockTestFramework extends GroovyTestFramework {
@Override
public FileTemplateDescriptor getSetUpMethodFileTemplateDescriptor() {
- return new FileTemplateDescriptor("Spock SetUp Method.groovy");
+ return new FileTemplateDescriptor("Spock_SetUp_Method.groovy");
}
@Override
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
index 53cb43d9e457..9fc2b16aedaf 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
@@ -19,20 +19,14 @@ package org.zmlx.hg4idea.log;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
-import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.*;
-import com.intellij.vcs.log.data.VcsLogBranchFilter;
-import com.intellij.vcs.log.data.VcsLogDateFilter;
-import com.intellij.vcs.log.data.VcsLogStructureFilter;
-import com.intellij.vcs.log.data.VcsLogUserFilter;
-import com.intellij.vcs.log.ui.filter.VcsLogTextFilter;
+import com.intellij.vcs.log.VcsLogTextFilter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgNameWithHashInfo;
@@ -162,33 +156,28 @@ public class HgLogProvider implements VcsLogProvider {
@NotNull
@Override
public List<? extends VcsFullCommitDetails> getFilteredDetails(@NotNull final VirtualFile root,
- @NotNull Collection<VcsLogFilter> filters,
+ @NotNull Collection<VcsLogBranchFilter> branchFilters,
+ @NotNull Collection<VcsLogUserFilter> userFilters,
+ @NotNull Collection<VcsLogDateFilter> dateFilters,
+ @NotNull Collection<VcsLogTextFilter> textFilters,
+ @NotNull Collection<VcsLogStructureFilter> structureFilters,
int maxCount) throws VcsException {
List<String> filterParameters = ContainerUtil.newArrayList();
- List<VcsLogBranchFilter> branchFilters = ContainerUtil.findAll(filters, VcsLogBranchFilter.class);
+ // branch filter and user filter may be used several times without delimiter
+ // or -r options with appropriate revset arguments delimited by '|' or 'and'.
if (!branchFilters.isEmpty()) {
- String branchFilter = joinFilters(branchFilters, new Function<VcsLogBranchFilter, String>() {
- @Override
- public String fun(VcsLogBranchFilter filter) {
- return filter.getBranchName();
- }
- });
- filterParameters.add(prepareParameter("branch", branchFilter));
+ for (VcsLogBranchFilter branchFilter : branchFilters) {
+ filterParameters.add(prepareParameter("branch", branchFilter.getBranchName()));
+ }
}
- List<VcsLogUserFilter> userFilters = ContainerUtil.findAll(filters, VcsLogUserFilter.class);
if (!userFilters.isEmpty()) {
- String authorFilter = joinFilters(userFilters, new Function<VcsLogUserFilter, String>() {
- @Override
- public String fun(VcsLogUserFilter filter) {
- return filter.getUserName(root);
- }
- });
- filterParameters.add(prepareParameter("user", authorFilter));
+ for (VcsLogUserFilter authorFilter : userFilters) {
+ filterParameters.add(prepareParameter("user", authorFilter.getUserName(root)));
+ }
}
- List<VcsLogDateFilter> dateFilters = ContainerUtil.findAll(filters, VcsLogDateFilter.class);
if (!dateFilters.isEmpty()) {
StringBuilder args = new StringBuilder();
final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
@@ -208,7 +197,6 @@ public class HgLogProvider implements VcsLogProvider {
filterParameters.add(args.toString());
}
- List<VcsLogTextFilter> textFilters = ContainerUtil.findAll(filters, VcsLogTextFilter.class);
if (textFilters.size() > 1) {
LOG.warn("Expected only one text filter: " + textFilters);
}
@@ -217,7 +205,6 @@ public class HgLogProvider implements VcsLogProvider {
filterParameters.add(prepareParameter("keyword", textFilter));
}
- List<VcsLogStructureFilter> structureFilters = ContainerUtil.findAll(filters, VcsLogStructureFilter.class);
if (!structureFilters.isEmpty()) {
for (VcsLogStructureFilter filter : structureFilters) {
for (VirtualFile file : filter.getFiles(root)) {
@@ -249,8 +236,4 @@ public class HgLogProvider implements VcsLogProvider {
private static String prepareParameter(String paramName, String value) {
return "--" + paramName + "=" + value; // no value escaping needed, because the parameter itself will be quoted by GeneralCommandLine
}
-
- private static <T> String joinFilters(List<T> filters, Function<T, String> toString) {
- return StringUtil.join(filters, toString, "\\|");
- }
}
diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenResourcesBuilder.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenResourcesBuilder.java
index 8f9a7b85b9cc..13bf78686482 100644
--- a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenResourcesBuilder.java
+++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenResourcesBuilder.java
@@ -1,6 +1,7 @@
package org.jetbrains.jps.maven.compiler;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.BuildOutputConsumer;
@@ -116,7 +117,13 @@ public class MavenResourcesBuilder extends TargetBuilder<MavenResourceRootDescri
private Pattern getDelimitersPattern() {
Pattern pattern = myDelimitersPattern;
if (pattern == null) {
- pattern = Pattern.compile(config.delimitersPattern);
+ if (StringUtil.isEmpty(config.escapeString)) {
+ pattern = Pattern.compile(config.delimitersPattern);
+ }
+ else {
+ String quotedEscapeString = Pattern.quote(config.escapeString);
+ pattern = Pattern.compile("(" + quotedEscapeString + quotedEscapeString + ")|(?:(" + quotedEscapeString + ")?(" + config.delimitersPattern + "))");
+ }
myDelimitersPattern = pattern;
}
return pattern;
@@ -168,28 +175,31 @@ public class MavenResourcesBuilder extends TargetBuilder<MavenResourceRootDescri
Map<String, String> resolvedProperties = resolvedPropertiesParam;
final Matcher matcher = delimitersPattern.matcher(text);
+
+ boolean hasEscapeString = !StringUtil.isEmpty(moduleConfig.escapeString);
+
final int groupCount = matcher.groupCount();
- final String escapeString = moduleConfig.escapeString;
+ int firstPropertyGroupIndex = hasEscapeString ? 3 : 0;
+
int last = 0;
while (matcher.find()) {
- if (escapeString != null) {
- int escapeStringStartIndex = matcher.start() - escapeString.length();
- if (escapeStringStartIndex >= last) {
- if (text.startsWith(escapeString, escapeStringStartIndex)) {
- out.append(text, last, escapeStringStartIndex);
- out.append(matcher.group());
- last = matcher.end();
- continue;
- }
- }
- }
-
out.append(text, last, matcher.start());
last = matcher.end();
+ if (hasEscapeString) {
+ if (matcher.group(1) != null) {
+ out.append(moduleConfig.escapeString).append(moduleConfig.escapeString); // double escape string
+ continue;
+ }
+ else if (matcher.group(2) != null) {
+ out.append(matcher.group(3)); // escaped value
+ continue;
+ }
+ }
+
String propertyName = null;
- for (int i = 0; i < groupCount; i++) {
+ for (int i = firstPropertyGroupIndex; i < groupCount; i++) {
propertyName = matcher.group(i + 1);
if (propertyName != null) {
break;
diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java
index 3c4c47c18e56..86340adf0ea7 100644
--- a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java
+++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java
@@ -58,7 +58,7 @@ public class MavenModuleResourceConfiguration {
public Set<String> filteringExclusions = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
@OptionTag
- public String escapeString = MavenProjectConfiguration.DEFAULT_ESCAPE_STRING;
+ public String escapeString = null;
@OptionTag
public boolean escapeWindowsPaths = true;
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/compiler/MavenResourceCompiler.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/compiler/MavenResourceCompiler.java
index 209583b6f731..d5eb4a69d7f7 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/compiler/MavenResourceCompiler.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/compiler/MavenResourceCompiler.java
@@ -167,7 +167,7 @@ public class MavenResourceCompiler implements ClassPostProcessingCompiler {
Set<String> nonFilteredExtensions = collectNonFilteredExtensions(mavenProject);
String escapeString = MavenJDOMUtil.findChildValueByPath(mavenProject.getPluginConfiguration("org.apache.maven.plugins",
"maven-resources-plugin"),
- "escapeString", "\\");
+ "escapeString", null);
List<MyProcessingItem> moduleItemsToProcess = new ArrayList<MyProcessingItem>();
collectProcessingItems(eachModule, mavenProject, context, properties, propertiesHashCode,
@@ -245,7 +245,7 @@ public class MavenResourceCompiler implements ClassPostProcessingCompiler {
Properties properties,
long propertiesHashCode,
Set<String> nonFilteredExtensions,
- String escapeString,
+ @Nullable String escapeString,
boolean tests,
List<MyProcessingItem> result) {
String outputDir = CompilerPaths.getModuleOutputPath(module, tests);
@@ -305,7 +305,7 @@ public class MavenResourceCompiler implements ClassPostProcessingCompiler {
final Properties properties,
final long propertiesHashCode,
final Set<String> nonFilteredExtensions,
- final String escapeString,
+ @Nullable final String escapeString,
final List<MyProcessingItem> result,
final ProgressIndicator indicator) {
VfsUtilCore.visitChildrenRecursively(currentDir, new VirtualFileVisitor() {
@@ -476,7 +476,7 @@ public class MavenResourceCompiler implements ClassPostProcessingCompiler {
boolean isFiltered,
Properties properties,
long propertiesHashCode,
- String escapeString) {
+ @Nullable String escapeString) {
myModule = module;
mySourceFile = sourceFile;
myOutputPath = outputPath;
@@ -507,6 +507,7 @@ public class MavenResourceCompiler implements ClassPostProcessingCompiler {
return myProperties;
}
+ @Nullable
public String getEscapeString() {
return myEscapeString;
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java
index 979e182bad25..66875895f278 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java
@@ -47,7 +47,7 @@ public class MavenPropertyResolver {
public static void doFilterText(Module module,
String text,
Properties additionalProperties,
- String propertyEscapeString,
+ @Nullable String propertyEscapeString,
Appendable out) throws IOException {
MavenProjectsManager manager = MavenProjectsManager.getInstance(module.getProject());
MavenProject mavenProject = manager.findProject(module);
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java
index 553175e5a07e..0d4b06b21cb0 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java
@@ -294,9 +294,7 @@ public class MavenModuleImporter {
if (file == null) continue;
if (libraryModel == null) {
- String libraryName = artifact.getLibraryName();
- assert libraryName.startsWith(MavenArtifact.MAVEN_LIB_PREFIX);
- libraryName = MavenArtifact.MAVEN_LIB_PREFIX + "ATTACHED-JAR: " + libraryName.substring(MavenArtifact.MAVEN_LIB_PREFIX.length());
+ String libraryName = getAttachedJarsLibName(artifact);
Library library = myModifiableModelsProvider.getLibraryByName(libraryName);
if (library == null) {
@@ -314,6 +312,14 @@ public class MavenModuleImporter {
}
@NotNull
+ public static String getAttachedJarsLibName(@NotNull MavenArtifact artifact) {
+ String libraryName = artifact.getLibraryName();
+ assert libraryName.startsWith(MavenArtifact.MAVEN_LIB_PREFIX);
+ libraryName = MavenArtifact.MAVEN_LIB_PREFIX + "ATTACHED-JAR: " + libraryName.substring(MavenArtifact.MAVEN_LIB_PREFIX.length());
+ return libraryName;
+ }
+
+ @NotNull
public static DependencyScope selectScope(String mavenScope) {
if (MavenConstants.SCOPE_RUNTIME.equals(mavenScope)) return DependencyScope.RUNTIME;
if (MavenConstants.SCOPE_TEST.equals(mavenScope)) return DependencyScope.TEST;
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java
index 523d5cbec958..c2b0aa9ba49b 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java
@@ -129,7 +129,7 @@ public class MavenResourceCompilerConfigurationGenerator {
}
Element pluginConfiguration = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-resources-plugin");
- resourceConfig.escapeString = MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeString", "\\");
+ resourceConfig.escapeString = MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeString", null);
String escapeWindowsPaths = MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeWindowsPaths");
if (escapeWindowsPaths != null) {
resourceConfig.escapeWindowsPaths = Boolean.parseBoolean(escapeWindowsPaths);
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java
index 4c2c7815e5ff..80e738fa6a81 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java
@@ -868,10 +868,15 @@ public abstract class ResourceFilteringTest extends MavenImportingTestCase {
}
public void testEscapingFiltering() throws Exception {
+ if (!useJps()) return;
+
createProjectSubFile("filters/filter.properties", "xxx=value");
createProjectSubFile("resources/file.properties",
"value1=\\${xxx}\n" +
- "value2=${xxx}\n");
+ "value2=\\\\${xxx}\n" +
+ "value3=\\\\\\${xxx}\n" +
+ "value3=\\\\\\\\${xxx}\n" +
+ "value4=.\\.\\\\.\\\\\\.");
importProject("<groupId>test</groupId>" +
"<artifactId>project</artifactId>" +
@@ -887,12 +892,24 @@ public abstract class ResourceFilteringTest extends MavenImportingTestCase {
" <filtering>true</filtering>" +
" </resource>" +
" </resources>" +
+ " <plugins>" +
+ " <plugin>" +
+ " <groupId>org.apache.maven.plugins</groupId>" +
+ " <artifactId>maven-resources-plugin</artifactId>" +
+ " <configuration>" +
+ " <escapeString>\\</escapeString>" +
+ " </configuration>" +
+ " </plugin>" +
+ " </plugins>" +
"</build>");
compileModules("project");
assertResult("target/classes/file.properties",
"value1=${xxx}\n" +
- "value2=value\n");
+ "value2=\\\\value\n" +
+ "value3=\\\\${xxx}\n" +
+ "value3=\\\\\\\\value\n" +
+ "value4=.\\.\\\\.\\\\\\.");
}
public void testPropertyPriority() throws Exception {