Snapshot cd724ea5e27634f1c84f893f10b646937a677d56 from idea/132.425 of git://git.jetbrains.org/idea/community.git
cd724ea: Code cleanup - Idea's warnings fixed - message moved to .properties file
c84855b: for performance use processNames api for java symbol contributor
334c509: IDEA-114064 Create "From Maven" library dialog doesn't handle full coords correctly (as advertised)
4e10a17: IDEA-109943 Download Library from Maven Repository: artifacts from repository with provider != maven2 are suggested, but repository is filtered off
d4bc48d: IDEA-114037 Code completion should prefer variable names to unimported class names
b7e5e6c: refix RUBY-11716: do not play with fire, always save and load in UTF-8 !
bb7ed8a: cleanup
15bd24e: cleanup
e56b270: ProjectId, don't add project level provider if project is not mapped
a0fb6a5: let IsNullCheck mean null->true, the former !null->false meaning was useless
26402542: test data fixed
f800733: new inference: input/output inference variables
56d872d: NPE: find usage for db element
3ffd6a0: IDEA-114003 XDebuger breakpoint properties: strage selection jumps in breakpoint tree
bbdef54: IDEA-114001 XDebuger Breakpoint Properties: enable in tree is not saved IDEA-114002 XDebuger breakpoint properties: don't close the dialog by double click IDEA-114004 XDebugger breakpoint properties: checkboxes synchronization is broken
f6ff871: IDEA-114001 XDebuger Breakpoint Properties: enable in tree is not saved IDEA-114002 XDebuger breakpoint properties: don't close the dialog by double click IDEA-114004 XDebugger breakpoint properties: checkboxes synchronization is broken
8f3d962: IDEABKL-6897 Enter inserts closing brace in wrong place
6a78643: IDEABKL-6897 Enter inserts closing brace in wrong place
06b899c: IDEA-114001 XDebuger Breakpoint Properties: enable in tree is not saved IDEA-114002 XDebuger breakpoint properties: don't close the dialog by double click IDEA-114004 XDebugger breakpoint properties: checkboxes synchronization is broken
aeda985: don't give focus to ant messages view
f525708: new inference: overload resolution for SAM return type for implicit lambda should be ignored
6692602: cleanup current file from highlighting markup
27c6645: compilation fix
1936bb2: IDEA-107453 Compilation error if overriding methods have different access modifiers
0ddcc36: api
a7f05e1: card layout fixed
b007608: IDEA-110203 IDEA ignores space after comma setting for methods declaration/call [CR-IC-2022]
ae02c17: hiding artifacts
90e6ed2: back to AddModuleWizard
4a029e9: Groovy: Pull-up members
6f9e810: NPE
fc48bab: pull-up
cbf7531: prepare pull-up refactoring for Groovy
6762d5f: cleanup
b26ffb2: spaces around inner classes
41e8e70: IDEA-113333 Java formatter breaks source code: Merges statements into line comments [CR-IC-2245]
ea91b55: IDEA-113815 keep "simple methods in one line" does not keep long methods [CR-IC-2486]
ecd65ad: Import Eclipse code style settings from XML profile (a part of IDEA-104068) [CR-IC-2219]
aacf1e4: IDEA-113844 (handling of core component initialization failures when spoiled by plugins)
8dc3ede: IDEA-112387 Reformat code with rearrange entires on = fail on enum [CR-IC-2205]
72ddb9e: Merge remote-tracking branch 'origin/master'
209340b: Add the description for MavenDuplicatePluginInspection.
de367e1: Merge branch 'svn1_8_new'
1a70497: IdeaTestAssistant: fix test data
d6a2510: svn: Fixed "Import" when path/url contains '@' symbol
94c4223: svn: Implemented "Export" action for command line
8913712: parameter popup: escape for annotation methods (IDEA-113971)
fdf7312: svn: Made event handler for checkout/export utilize passed progress indicator (instead of just current thread progress indicator)
f653713: IDEA-105758: Contradiction between error and fix actions (Java EE artifact)
eac456f: Platform: ability to provide native icons for PsiElements (PsiFile/Directory) AppCode: blue icons for folders
4d5c47a: IDEA-77519: Project fails to open when workspace.xml is empty
c40e732: two classes temporary restored to fix backward compatibility
b6b3bc6: added optional dependencies for framework support providers
a9dae78: IDEA-90661: recognize IBM JDK jars
6b44958: cleanup & javadoc
0c0a6a6: IDEA-108785 Allow applying the same context to many selected live templates
247661b: don't search for unknown path macros in the middle of xml unless asked so by PathMacroFilter (IDEA-102674)
90222d5: hopefully fix control flow building stack inconsistency assertions in case when a PCE is thrown
241e44b: EA-50288 - CCE: RefJavaUtilImpl.getTopLevelClass
22d5c2f: ensure to filter already inserted annotations (IDEA-113785)
27b76b4: inplace introducer: another case to restore expression (IDEA-113352)
603e138: add mnemonics (IDEA-113889)
a8c374c: XSuspendPolicyPanel "Make default" (requires for new JavaBreakpointType) remove unused methods
4f19472: CR-IC-2485 (deprecation policy specified; deprecated API usage upgraded)
7231807: JavaBreakpointType isSuspendThreadSupported true
8637e89: register JavaBreakpointType, but hide under system property java.debugger.xBreakpoint
0b2d5f0: cleanup
5cc1f5e: EA-50289 (CCE: TooBroadScopeInspection$TooBroadScopeInspectionFix.getCommentText)
505b86e: new inference: pertinent to applicability
8ac21fd: cleanup
2c5f39e: cleanup
f6efaa9: simplify DebuggerInvocationUtil
bf8865f: overrides
0d49e5b: JavaBreakpointType canPutAt
33ebea3: extract XLineBreakpointTypeBase
de7d963: extract XDebuggerEditorsProviderBase, init JavaBreakpointType (is not registered, so, not in action now)
ed777e6: remove deprecated canPutAt
9163435: overrides
44af67f8: extract XDebuggerUtil.getInstance().getGroupingByFileRuleAsList()
b93b27c: add missing Overrides
0857036: cleanup
ae791a7: new inference: test preparations
48120ab: IdeaTestAssistant: add resolving and completion inside TestDataPath annotation
971544b: remove empty unused class
c5642d9: hippie completion: split complex tokens by spaces
e1383b1: refix and add test for IDEA-90294 Don't use substring match in word completion
fbae94c: EA-49809 Made client factories final in SvnVcs
2b4b70f: Fix OC-8127: Appcode hangs on reformatting (endless right shift) +review CR-OC @Anton.Makeev, @Rustam.Vishnyakov
b7314cf: fix pycharm detection
5f0bb3c: revert error checking
5f99590: svn: Implemented "Import" action for command line
ad04905: svn: Changed import logic to use common commit event handler (instead of checkout event handler)
1a45be0: custom options
8d278a3: MavenArchetypesPanel extracted
32eeb4c: aggregation panel invisible
9388cc4: new project wizard: project type sorting
2c02a07: svn: Add "Skipped" event processing in commit/import output for command line
d365580: svn: Refactored commit output parsing for command line
b1cc312: immutable dfa offset stack
5c494fb: toolbarIcon is nullable
4304880: dfa: traverse only flushable variables, not all
ed08eab: immutable EqClass
03de519: overrides
f8661d9: return empty collection if list of storage files is empty
81a998c: IDEA-111030: Add Framework Support: Ok is disabled for the only selected Web Application
4ce1cc8: unused class removed
84f7401: svn: Added final status bar message for Import ("Committed revision xxx")
aa1d479: library editor: 'attach javadoc' extracted to separate button so the main '+' button won't show popup
1612198: cleanup
e180456: cleanup
546fffe: Merge remote-tracking branch 'origin/master'
c3caf6c: Merge remote-tracking branch 'origin/master'
5cd2b37: assertion for EA-45385 - NPE: XmlTagImpl.getDescriptor
99563ea: EA-49418 - NPE: InjectLanguageAction.invokeImpl
dc82859: cleanup
f70ef96: EA-50139 - assert: TextRange.<init>
990e410: svn: Removed unused code (from "Ignore" functionality)
6604613: svn: Implemented "Ignore" functionality on subversion level
d544d03: cleanup after notnullification
5330d9e: plugin suggester: suggest plugins from repository by unknown facet
1ccf92a: error which should never happen replaced by assertion
889d3ce: improved dialog for choosing root types of added roots
0eb34fa: hide "use out of process build" option from UI
d79e13e: plugin suggester: suggest plugins from repository by unknown facet
00a127b: Use shell options only if applicable.
b4f21b9: Don't fail to create SSH terminal session if we failed to create local terminal session.
8e5cb57: test for "Unnecessary unicode escape sequence" inspection
dc8acce: temp revert
c7c4431: fix SliceBackwardTest
3e16a04: svn: Implemented "Edit Revision Comment" action for command line
c54948a: 'async' added
e4f7950: svn: Correctly create externals that have '@' in url - add '@' at url end
9b66e1c: svn: Fix line separators duplication for "Create External" action for SVNKit
a98dc14: svn: Implemented "Create External" action for command line
32e30d1: EA-50206 - assert: FileManagerImpl.findFile
4a4c0cc: svn: Unify line separator for multiline properties
4b9422b: Reverted: Semantic highlighting level to avoid conflicts with "unused symbol" annotations [CR-IC-2435]
ad970ef: lambda: propagate wildcards elimination
e78ab51: lambda: check formal params for equality, eliminate wildcards during inference according to 15.27.3
fc9a196: new inference: ignore proper types in mutual eq constraints generation
7bc0048: new inference: void compatible according to return values
939fc45: prepare for test new inference
eef6eb2: new inference: exact method reference
172daec: new inference: eliminate delayed constrains according to 0.6.3
ec93384: postpone type evaluation
e689d68: new inference: make use of ex constraint
7838f8e: Merge branch 'safe-sudo-escaping'
1c22df9: Add grails-app/resources as resources folder, not a source folder.
a7f094d: fix NPE
e1fe819: Added ExecUtil.sudoAndGetOutput() with safe escaping and quoting for Mac and Linux
6bf3a02: fixed EA-48905 - SIOOBE: ParameterInfoComponent$OneLineComponent.buildLabelText
c853c69: system dependent paths in groovy shell
db7d97f: Merge remote-tracking branch 'origin/master'
65426f9: mark as DumbAware
0d1a074: Support active links in GotIt panel
c7297a0: debugging blinking test
755c6b2: IDEA-113938 "Submit feedback" should pre-fill project and affected version
ff45141: dfa: don't go into the same instruction twice with the same state
3361944: a bit more parsimonous DfaMemoryStateImpl.createCopy
028d28b: dfa states should not change while in queue => no need to copy them
1709382: dfa: use UnorderedPair instead of two-element set
e8dbc21: immutable DfaVariableState, for faster copying and less memory usage
666ed52: IDEA-70241 (Replace with '{@code}' inspection doesn't replace all occurrences in file.)
71bd9cf: Merge remote-tracking branch 'origin/master'
c923098: EA-47881 - IOE: GroovyPsiElementFactoryImpl.createGroovyFileChecked
8b97940: cleanup logging
6e4b81e: EA-50137 - assert: TestObject.addClassesListToJavaParameters
5381d51: cleanup
dc2d1b2: notnull
f419fab: "todo" moved out of lang-impl
97cd633: attributes cleanup
75b3eaa: notnull
c7fa9af: cleanup
f5b5bf4: cleanup
776b16b: cleanup
bf3cea4: made fields final
87913f7: cleanup
798e94e: cleanup, get rid of buggy duplicate node renderer
50f13e4: removed deprecated methods from ExternalAnnotator
6d9c887: avoid deprecated methods
4852116: minor
9cd549c: now Searchable. fixes test.
302302a: typo
26d8885: - handle strings with more than one quote used for start / end delimiters - proper retrieving syntax highlighter in case of non languge based syntaxhighlighter (quite often it is bound to file type) - Find: String literals only: Throwable at StringSearcher.scan() on XML with a string (IDEA-113885) - fix for backward search not ending when whole word option used
4dfd0c7: Encapsulate field dialog: explicit value for "Use accessors when field is accessible" when "as is" visibility is selected
e1aff45: typo :(((
6237b9b: test fixed
6c0d31b: test fixed
493cfae: update test data
711bca1: update test data
f1bc615: update test data
8dd18de: update test data
e61a901: update test data
0be96e9: update test data
aac178b: dfa: remove queued state duplication
6a25f5d: dfa: don't reschedule already processed states, cleanup
7559dfc: Semantic highlighting level to avoid conflicts with "unused symbol" annotations [CR-IC-2435], for WI-19396, WI-20126 (cherry picked from commit 56d66dc)
7c27aef: extract collectUsedJars() function
12f59ff: update test data
03df890: update test data
1efd604: update test data
2c1726e: update test data
24bf1d1: Merge remote-tracking branch 'origin/master'
8f26a8b: improved duplicates search in python extract method
9bfcbbe: setup resource roots when project is imported from Maven (IDEA-57398)
64594cd: diagnostics for EA-49831
0d76c32: add support for frameworks step: sorting restored
b510334: IDEA-113294 indentation of brace in a lambda expression corrected [CR-IC-2426]
9651be4: IDEA-113910 Gradle: code insight; dependencies DSL resolving
25595c8: new inference: checked exceptions compatibility constraint
6b8f295: dump highlighting test data without markup
636719b: now that we have dfa state hashing, use it instead of linear lookup
3813120: dfa: don't merge states when there's only one
3fd9ba8: IDEA-113910 Gradle: code insight; dependencies DSL resolving
57a6aeb: IDEA-113910 Gradle: code insight; dependencies resolving
da23b6c: Merge remote-tracking branch 'origin/master'
7ca6ea3: Merge remote branch 'origin/master'
cdc6d6a: show deprecated make implementation warning once on first compilation after project opening
090c4e3: dfa state merging: cache copies
e6ee024: Allows getting Gradle home without having a Project.
0391639: Gradle VM Options are now saved in between sessions.
f5412f0: resource root: show 'New Directory' action instead of 'New Package' under resource roots
1637f6b: notnullification
87f394f: IDEA-113904 (Add New Module from Project Structure dialog wants to create new project)
a7c75f6: IDEA-113865 ('Equals should check class of parameter' shouldn't warn on identity equals)
2486e9e: dfa: merge several states to account for variables with several possible values
4d4f4b0: dfa: some minor things and caching
c14961f: UnorderedPair in platform
5ad442d: Merge remote-tracking branch 'origin/master'
946a281: Scroll to bottom on typing in terminal (PY-10344).
e5a0548: Close all connections on dispose.
f61f6a2: changes from tech-writers
b82b0bb: dfa: state merging interruptibility
3893373: VcsDirtyScopeManagerImpl: log who marks everything dirty
41e5381: Merge remote-tracking branch 'origin/master'
da21efb: JediTerm updated.
beb1d1a: Merge remote-tracking branch 'origin/master'
ed3a2b5: skip the whole document if some component has disabled roaming type (details CR-IU-308)
d66309b: Fix antialiasing.
e55fae1: dfa: abstract out eq class into EqClass class
370d44d: dfa: remove trivial state facts that constant != another constant
4ccfcf7: UsagesStatistic must specify roaming disabled
75894ae: cleanup
784b4e3: DimensionService: cleanup, order of stored data should be stable
36443b6: overrides
b70b1dc: overrides
dfe38fb: simplify some constant conditions and greenify
9a08478: IDEA-85961 (Pattern BACKSLASH_PATTERN = Pattern.compile("\\", Pattern.LITERAL) is always marked red.)
d0bdc3b: simplify load from providers – we don't need to filter again (our save do it, in any case it is absurd to store component with global roaming in the project level file, — should be refine later)
bf85e1b: cleanup
9c30823: remove unused methods
f671c09: overrides
3bd62bc: ComponentRoamingManager should not keep defaults (we use RoamingType.PER_USER by default)
a8f1063: CR-IU-300 remove outdated EP ComponentRoamingType
b182751: CR-IU-300 remove outdated RoamingTypePerPlatform
994389c: another java.util.regex.Pattern.compile() parameter annotation
301710d: IDEA-113866 (this. not suggested for fields of anonymous inner classes)
f5d03c4: dfa: don't consider final getters same as immutable fields
272a6d0: Corresponding parents for console colors.
71298ce: Bright console colors for Monokai.
f39c34b: Console colors for WarmNeon scheme.
7548e47: Black is invisible on dark background (in RegExps for example).
ca6b784: Change bloody red to light pink for numbers (pink is specific to Neon color schemes while red is not, also eyes say thanks).
7f627d9: Console colors for Twilight scheme fixed.
a5eb2fc: Console colors for Monokai scheme fixed.
f7da145: DfaPsiType: add @NotNull
b216102: rebomb test
b349547: diagnostics for inconsistencies during control flow building
6823425: dfa: only perform costly state merging when it has chances - after jumps
fea8871: dfa: fighting too complex methods; join complementary memory states after fork to avoid having too many states
0ac2084: DfaMemoryStateImpl: introduce unwrap; compare variable values with their non-initialized counterparts
e919b8b: dfa: only goto catch on non-trivial method calls and throws
e2ea04f: new inference: initial method reference constraint
a9dde36: new inference: check substituted descriptor return type
3e5b164: new inference: expression inside condition should be poly, target type for conditional expression
ff9f2e9: new inference: emulate fresh variable - do not override vars with captured ones
f415702: new inference: default constructor as poly expression argument
ee56497: new inference: symmetric variable bounds
4a46b24: new inference: init inter call inference
06829c5: Merge remote-tracking branch 'origin/master'
e3f213f: Console colors for Darcula.
f748505: IDEA-57940 Cyclic expand word should take into account all open files
460ef47: StreamProvider.isVersioningRequired
8029f47: Bright yellow made more visible on white background.
96006be: Default console colors as in xterm palette, gray and dark gray from standard vga palette for better readability.
a378414: Bight console colors added to settings.
54e6582: builder-based project types
b0b2cf8: template-based project types?
e741484: CPU hogging fix again
eb22a99: fix todo duplication when several pattern match -> prefer finding match with last pattern (in settings list), thus default TODO pattern is matched last
a4d4371: fix compilation
2f823ba: Difference Groovy Shell & Groovy Console actions
3e876f4: IDEA-113590 annotations as annotation values
732cafd: dead code
a712f87: pull up 'isQualified()' method
4edd102: extract base class from PullUpDialog
10d89d6: remove obsolete test
a0750e4: delete envFile manually
114cbb2: IDEA-113861 Gradle: it could be possible to hide 'Gradle: download' progress to the background
ca416b8: 'More' element for classes, files, action, and settings. Better renderer.
b2a550c: test framework: drop temp directory on light project close
8aaf53b: greenify ActionsTreeUtil a bit
922d41a: layout
2cd7326: adding frameworks support
2bd8fb0: cleanup
4ea6442: ProjectSummaryStep
9fdcdcd: commit project name
bd39918: new project wizard: first test
630fc14: External system: use URLs in compile output paths
85dbe5f: IDEA-65114 "Add Maven projects" cannot be undone
5041ae5: test framework: returning of the data provider
16e2072: @Nullable XBreakpoint.getProperties reverted +review CR-IC-2418
df4da38: dump shell environment to a temporary file to reduce probability of malformed lines occurrence
280d52a: let event log warning color be orange (IDEA-113802)
a30b2ae: IDEA-113836 Console folding: add TestNG related patterns
cbeb0f1: don't change mouse cursor during goto name population (IDEA-113800)
fb5ad5b: IDEA-113638 ChooseByName restart on write action spawns a new thread
89b3767: disable autopopup in groovy shell if selection by chars is enabled (IDEA-112820)
9fa36be: CompletionConfidence: don't force API users to implement unused method
34cf7eb: Console Folding: proper capitalization
5e8aa44: IDEA-113855 Search Everywhere looks scrambled at first start
71723cb: svn: Refactored executable validation - use separate version client
1114cfe: javadoc
0738800: jps model: simplification, source roots always have default properties
b1d5062: jps model: JpsElementType converted to interface to allow reusing common base class
229deb0: test framework: ok, put light project file into ephemeral directory, but keep it for a project's life
6e8b950: ensure "thread" suspend policy for logging breakpoints
d67c04e: EA-49809 Move client factories creation to SvnVcs constructor (instead of active() method)
935cdba: new inference: initial tests
970a180: encapsulate read access to USE_COMPILE_SERVER option
b9b3fc8: remote agents - extract to remote servers
cfe8e2b: WEB-9335 Bad insert pair brace in CSS
2815c22: WEB-9334 Incremental selection works bad with negative CSS values
d023471: new "Unnecessary unicode escape sequence" inspection
945b069: unicode escape needs at least one 'u'
8e7797b: chrome still crashed, revert to old, not-recursive speed search
1917d86: Merge remote-tracking branch 'origin/master'
c18e6bd: Lense mode "internal" preview
db88427: Merge branch 'svn1_8_new'
7c64e8b: test framework: do not put light project file into ephemeral directory
af09e11: remove @Nullable from key.get as it's too generic
d49df32: svn: Refactored prompting for working copy format - make return not null format
d6086ae: dfa: types with wildcard parameters are not equal
3d28aa5: Optimization: check exiting of griffon-app first
b016c04: correct ephemeral state copy (IDEA-113143 Calling method with contract shouldn't result in nullability suspicion)
189573f: svn: Refactored upgrade working copy format dialog - use list of available formats (instead of separate fields for each format)
60c471b: Rename test
1a42f59: Remove using of unnecessary StringBuilder
a56db90: Use MultiMap
340cf22: Calling method with contract shouldn't result in nullability suspicion (IDEA-113763, IDEA-113699, almost IDEA-113143)
f2a563b: dfa: unify nullability violation processing
709af86: dfa: expand contract test
1cddfb4: dfa cleanup: skipping reports on method calls is now done via unknown variable mechanism
2765dab: dfa: spare some minor cpu cycles
8bc7465: svn: Added "1.8" option to upgrade/checkout dialogs
c266bd2: IDEA-66603 Maven3: provide inspection that checks duplicate declarations of plugins
af32923: SpellChecker: "cyclomatic"
5f4f98f: svn: Refactored working copy format selection dialog to use WorkingCopyFormat instances instead of just strings
e33b58b: MismatchedCollectionQueryUpdateInspection -- added "compute" prefix (from j.u.Map in JDK8)
7d54b2e: new inference: accept nonProper eq bounds
457d95b: new inference: distinguish different captures
5b5f52e: new inference: assertions caused by raw types
3848de4: new inference: open top level captured wildcards
35d59c0: new inference: extend usage of already inferred variables
4f7b572: new inference: inference of calls in arguments during outer call inference
bfa7879: new inference: captured variables from outer calls to be included
ed95269: new inference: eq bound for S<=T constraint reduction
12a0faf: better positioning
13029b7: different position layout algorithms
39e6e21: EA-49923 - Fixed working copy format detection for default project
d521e9d: JDK combobox should show JDK home
17fe05e: Fix typo
7ab769b: IDEA-16077 Maven embedder runs in the 'wrong' JDK add "embedder JDK" option
418ddc0: Inline string constant
6a8f1e2: IDEA-16077 Maven embedder runs in the 'wrong' JDK extract MavenJdkCombobox
46078c4: svn: Refactored detection if command line implementation should be used (use utility method)
24106fc: XDebugger: @Nullable XBreakpoint.getProperties()
3dc6f07: extract util method
476dac4: Reinit checkbox state on create
39cf1fd: Structure viewer for simple editors support fixed
a38a251: Show filters only for table editor + a few model and UI fixes
cbd5630: Initial dynamic filters model + columns header improved
281c008: svn: Support nullable SVNStatusClient in status implementation for SVNKit
1840d42: simplification
fbcba0f: svn: Make command line clients (info, status) use vcs instead of project instances
ae8b41b: Merge remote-tracking branch 'origin/master'
a97397c: Extract method.
3b9eca4: new project wizard: preparing test infrastructure
327ddb0: Lense mode "internal" preview
0ede5e1: new project wizard: AbstractProjectWizard extracted
a94b556: IDEA-111335 Gradle: task tree is incorrectly displayed if tasks are added to sub-projects via 'subprojects' method
bfd366f: Merge remote-tracking branch 'origin/master'
0ef2a82: calls to obsolete method removed from build scripts
2df016f: AntLoggerFactory inner class made static to fix NoSuchMethodException in Logger.setFactory
fe876e2: svn: Clients for update command renamed and moved to corresponding package
a38d90e: Terminal color settings.
bd285b8: svn: Refactored update logic to common ClientFactory model
9cc13da: platform: ignore hidden Windows files
d87664c: test framework: relic property dropped
5f6ef06: svn: Removed unused "common ancestor" behavior from command line update client
3667fe1: Find in strings with reg exp with start / end match markers doesn't work without string delimiters (IDEA-113788)
94a079f: svn: Refactored "update" command - explicitly create new SVNKit update client for each update/switch operation
0344e91: new project wizard: added option to use framework libraries from an app server
2882ac0: svn: Removed unused methods from "update" client
17ea275: svn: Removed unused SvnProxies class
c926181: WEB-9342 External Tool fails on OSX if an executable file basename specified
a3433f9: svn: Removed unused methods from "info" client
ec3112d: Optimize SassExtensionFunctionsIndex
9f1abf7: nosplash shouldn't prevent from plugin update
4c7154d: dfa: use cached nullability
b81e9c3: dfa: less frequent "too long" check
0b0eba9: DfaValueFactory: use List instead of TIntObjectHashMap for sequential keys
95d5433: introduce DfaPsiType without nullability, to quickly check assignability/convertibility in DfaVariableState
b901d90: IDEA-96713 Incorrect options shown for 'implements'
e02e2c4: IDEA-113780 "Annotate" from history fixed for renamed/moved files
fe00f73: test framework: stability improvements
76d664d: platform: suspicious event logging
b204bdf: Cleanup (de-duplication)
7ba9ff0: spelling
ece939c: make public for Upsource
496db4d: xdebugger: rebuild standalone variables view on EDT
eae27cb: xdebugger: supported rebuilding of standalone variables view
8bf5204: xdebugger api: added convenient method
43dbb6f: Terminal options.
3db1f5c: Blink period and antialiasing settings.
88264bd: IDEA-108147 Use "merge sources" wrapper object instead of just string representation as data model for "Merge Sources" column (to correctly get file revision object and show details panel)
111e6ba: IDEA-108147 While building history for element make check "if element parent or child was changed in given revision" only be performed for non-"merge source" revisions
e07828d: svn: Implemented support for "merged revisions" parsing in history logic for command line
1586c4a: svn: history logic refactored for command line - get and parse history data in xml format
0ac1dd2: IDEA-94942 Refactored "Annotate" implementation for command line - use utility method for parsing
ba1e5e0: IDEA-94942 Implemented merge history support for "Annotate" action
4c3b0a8: IDEA-94942 Implemented "Switch" logic (during update)
Change-Id: I7092ae66ff47d353a5b9770d1d91f77369bb7734
diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLexer.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLexer.java
index c37f576..09ee6a5 100644
--- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLexer.java
+++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLexer.java
@@ -16,6 +16,7 @@
package org.intellij.lang.regexp;
import com.intellij.lexer.FlexAdapter;
+import org.jetbrains.annotations.NotNull;
import java.util.EnumSet;
@@ -29,7 +30,7 @@
myCapabilities = capabilities;
}
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
getFlex().commentMode = (initialState & COMMENT_MODE) != 0 || myCapabilities.contains(RegExpCapability.COMMENT_MODE);
super.start(buffer, startOffset, endOffset, initialState & ~COMMENT_MODE);
}
diff --git a/build/scripts/common_tests.gant b/build/scripts/common_tests.gant
index b067618..1af3d7a 100644
--- a/build/scripts/common_tests.gant
+++ b/build/scripts/common_tests.gant
@@ -27,7 +27,6 @@
}
loadProject()
- projectBuilder.useInProcessJavac = false
projectBuilder.targetFolder = out
projectBuilder.cleanOutput()
projectBuilder.buildAll()
diff --git a/build/scripts/dist.gant b/build/scripts/dist.gant
index a03f512..58ece9a 100644
--- a/build/scripts/dist.gant
+++ b/build/scripts/dist.gant
@@ -47,7 +47,6 @@
target(compile: "Compile project") {
loadProject()
- projectBuilder.arrangeModuleCyclesOutputs = true
projectBuilder.stage("Cleaning up sandbox folder")
forceDelete(paths.sandbox)
diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant
index 8f0e940..d1e90c1 100644
--- a/build/scripts/utils.gant
+++ b/build/scripts/utils.gant
@@ -775,11 +775,9 @@
}
})
-binding.setVariable("buildModulesAndCollectUsedJars", { List modules, List approvedJars, List forbiddenJars ->
+binding.setVariable("collectUsedJars", { List modules, List approvedJars, List forbiddenJars, List modulesToBuild ->
def usedJars = new HashSet();
- projectBuilder.cleanOutput()
- def modulesToBuild = []
modules.each {
def module = findModule(it)
if (module != null) {
@@ -794,12 +792,22 @@
}
}
}
- modulesToBuild << module
+ if (modulesToBuild != null) {
+ modulesToBuild << module
+ }
}
else {
projectBuilder.warning("$it is not a module")
}
}
+
+ return usedJars
+})
+
+binding.setVariable("buildModulesAndCollectUsedJars", { List modules, List approvedJars, List forbiddenJars ->
+ def modulesToBuild = []
+ def usedJars = collectUsedJars(modules, approvedJars, forbiddenJars, modulesToBuild)
+ projectBuilder.cleanOutput()
projectBuilder.buildModules(modulesToBuild)
return usedJars
diff --git a/colorSchemes/src/colorSchemes/Darcula.xml b/colorSchemes/src/colorSchemes/Darcula.xml
index f0ad4be..b405024 100644
--- a/colorSchemes/src/colorSchemes/Darcula.xml
+++ b/colorSchemes/src/colorSchemes/Darcula.xml
@@ -157,14 +157,34 @@
<option name="EFFECT_TYPE" value="-1" />
</value>
</option>
+ <option name="CONSOLE_BLACK_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="000000" />
+ </value>
+ </option>
<option name="CONSOLE_BLUE_OUTPUT">
<value>
- <option name="FOREGROUND" value="5394ec" />
+ <option name="FOREGROUND" value="5394EC" />
+ </value>
+ </option>
+ <option name="CONSOLE_BLUE_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="7EAEF1" />
</value>
</option>
<option name="CONSOLE_CYAN_OUTPUT">
<value>
- <option name="FOREGROUND" value="6969" />
+ <option name="FOREGROUND" value="33CCCC" />
+ </value>
+ </option>
+ <option name="CONSOLE_CYAN_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="6CDADA" />
+ </value>
+ </option>
+ <option name="CONSOLE_DARKGRAY_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="555555" />
</value>
</option>
<option name="CONSOLE_ERROR_OUTPUT">
@@ -172,9 +192,29 @@
<option name="FOREGROUND" value="ff6b68" />
</value>
</option>
+ <option name="CONSOLE_GRAY_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="999999" />
+ </value>
+ </option>
+ <option name="CONSOLE_GREEN_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="007F00" />
+ </value>
+ </option>
+ <option name="CONSOLE_GREEN_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="70FF70" />
+ </value>
+ </option>
<option name="CONSOLE_MAGENTA_OUTPUT">
<value>
- <option name="FOREGROUND" value="983498" />
+ <option name="FOREGROUND" value="FF70FF"/>
+ </value>
+ </option>
+ <option name="CONSOLE_MAGENTA_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="FF99FF" />
</value>
</option>
<option name="CONSOLE_NORMAL_OUTPUT">
@@ -189,12 +229,32 @@
</option>
<option name="CONSOLE_RED_OUTPUT">
<value>
- <option name="FOREGROUND" value="ff6b68" />
+ <option name="FOREGROUND" value="FF6B68" />
+ </value>
+ </option>
+ <option name="CONSOLE_RED_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="FF8785" />
</value>
</option>
<option name="CONSOLE_SYSTEM_OUTPUT">
<value>
- <option name="FOREGROUND" value="bbbbbb" />
+ <option name="FOREGROUND" value="BBBBBB" />
+ </value>
+ </option>
+ <option name="CONSOLE_WHITE_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="BBBBBB" />
+ </value>
+ </option>
+ <option name="CONSOLE_YELLOW_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="CDCD00" />
+ </value>
+ </option>
+ <option name="CONSOLE_YELLOW_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="FFFF00" />
</value>
</option>
<option name="CSS.COLOR">
diff --git a/colorSchemes/src/colorSchemes/WarmNeon.xml b/colorSchemes/src/colorSchemes/WarmNeon.xml
index 37bb172..25cd484 100644
--- a/colorSchemes/src/colorSchemes/WarmNeon.xml
+++ b/colorSchemes/src/colorSchemes/WarmNeon.xml
@@ -49,7 +49,7 @@
</option>
<option name="BAD_CHARACTER">
<value>
- <option name="FOREGROUND" value="0" />
+ <option name="FOREGROUND" value="9F0E44" />
<option name="BACKGROUND" value="ffcccc" />
</value>
</option>
@@ -63,10 +63,65 @@
<option name="FOREGROUND" value="f2f0b5" />
</value>
</option>
+ <option name="CONSOLE_BLACK_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="000000" />
+ </value>
+ </option>
+ <option name="CONSOLE_BLUE_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="405EC9" />
+ </value>
+ </option>
+ <option name="CONSOLE_BLUE_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="7A8FD9" />
+ </value>
+ </option>
+ <option name="CONSOLE_CYAN_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="20BAD5" />
+ </value>
+ </option>
+ <option name="CONSOLE_CYAN_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="59D1E6" />
+ </value>
+ </option>
+ <option name="CONSOLE_DARKGRAY_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="555555" />
+ </value>
+ </option>
<option name="CONSOLE_ERROR_OUTPUT">
<value>
- <option name="FOREGROUND" value="e37e7e" />
- <option name="BACKGROUND" value="404040" />
+ <option name="FOREGROUND" value="E54242" />
+ </value>
+ </option>
+ <option name="CONSOLE_GRAY_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="a7a7a7" />
+ </value>
+ </option>
+ <option name="CONSOLE_GREEN_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="34B434" />
+ </value>
+ </option>
+ <option name="CONSOLE_GREEN_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="9BC28E" />
+ </value>
+ </option>
+ #A3E131
+ <option name="CONSOLE_MAGENTA_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="FF00FF" />
+ </value>
+ </option>
+ <option name="CONSOLE_MAGENTA_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="F971BB" />
</value>
</option>
<option name="CONSOLE_NORMAL_OUTPUT">
@@ -75,6 +130,16 @@
<option name="BACKGROUND" value="404040" />
</value>
</option>
+ <option name="CONSOLE_RED_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="E54242" />
+ </value>
+ </option>
+ <option name="CONSOLE_RED_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="EB6F6F" />
+ </value>
+ </option>
<option name="CONSOLE_SYSTEM_OUTPUT">
<value>
<option name="FOREGROUND" value="9d9d9d" />
@@ -88,9 +153,24 @@
<option name="FONT_TYPE" value="2" />
</value>
</option>
+ <option name="CONSOLE_WHITE_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="ffffff" />
+ </value>
+ </option>
+ <option name="CONSOLE_YELLOW_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="DBE439" />
+ </value>
+ </option>
+ <option name="CONSOLE_YELLOW_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="DEDB74" />
+ </value>
+ </option>
<option name="CSS.COMMENT">
<value>
- <option name="FOREGROUND" value="df8a8a" />
+ <option name="FOREGROUND" value="E2E95D" />
</value>
</option>
<option name="CSS.FUNCTION">
@@ -109,12 +189,6 @@
<option name="EFFECT_TYPE" value="1" />
</value>
</option>
- <option name="CSS.NUMBER">
- <value>
- <option name="FOREGROUND" value="ff0000" />
- <option name="FONT_TYPE" value="1" />
- </value>
- </option>
<option name="CSS.PROPERTY_NAME">
<value>
<option name="FONT_TYPE" value="1" />
@@ -177,12 +251,6 @@
<option name="FOREGROUND" value="de6666" />
</value>
</option>
- <option name="CUSTOM_NUMBER_ATTRIBUTES">
- <value>
- <option name="FOREGROUND" value="ff0000" />
- <option name="FONT_TYPE" value="1" />
- </value>
- </option>
<option name="CUSTOM_STRING_ATTRIBUTES">
<value>
<option name="FOREGROUND" value="1cb01c" />
@@ -240,7 +308,7 @@
</option>
<option name="DEFAULT_INVALID_STRING_ESCAPE">
<value>
- <option name="FOREGROUND" value="0" />
+ <option name="FOREGROUND" value="9F0E44" />
<option name="BACKGROUND" value="ffcccc" />
</value>
</option>
@@ -263,7 +331,7 @@
</option>
<option name="DEFAULT_NUMBER">
<value>
- <option name="FOREGROUND" value="ff0000" />
+ <option name="FOREGROUND" value="F971BB" />
</value>
</option>
<option name="DEFAULT_PREDEFINED_SYMBOL">
@@ -339,12 +407,6 @@
<option name="FOREGROUND" value="ca9e4d" />
</value>
</option>
- <option name="DJANGO_NUMBER">
- <value>
- <option name="FOREGROUND" value="ff0000" />
- <option name="FONT_TYPE" value="1" />
- </value>
- </option>
<option name="DJANGO_STRING_LITERAL">
<value>
<option name="FOREGROUND" value="34b434" />
@@ -385,12 +447,6 @@
<option name="FONT_TYPE" value="1" />
</value>
</option>
- <option name="EL.NUMBER">
- <value>
- <option name="FOREGROUND" value="ff0000" />
- <option name="FONT_TYPE" value="1" />
- </value>
- </option>
<option name="EL.PARENTHS">
<value>
<option name="FONT_TYPE" value="1" />
@@ -562,12 +618,6 @@
<option name="EFFECT_TYPE" value="1" />
</value>
</option>
- <option name="JAVA_INVALID_STRING_ESCAPE">
- <value>
- <option name="FOREGROUND" value="0" />
- <option name="BACKGROUND" value="ffcccc" />
- </value>
- </option>
<option name="JAVA_KEYWORD">
<value>
<option name="FOREGROUND" value="ca9e4d" />
@@ -580,12 +630,6 @@
<option name="FOREGROUND" value="e54242" />
</value>
</option>
- <option name="JAVA_NUMBER">
- <value>
- <option name="FOREGROUND" value="ff0000" />
- <option name="FONT_TYPE" value="1" />
- </value>
- </option>
<option name="JAVA_OPERATION_SIGN">
<value>
<option name="FOREGROUND" value="c8c8c8" />
@@ -608,12 +652,6 @@
<option name="FONT_TYPE" value="1" />
</value>
</option>
- <option name="JS.BADCHARACTER">
- <value>
- <option name="FOREGROUND" value="0" />
- <option name="BACKGROUND" value="ff0000" />
- </value>
- </option>
<option name="JS.BLOCK_COMMENT">
<value>
<option name="FOREGROUND" value="e45041" />
@@ -656,12 +694,6 @@
<option name="EFFECT_TYPE" value="1" />
</value>
</option>
- <option name="JS.INVALID_STRING_ESCAPE">
- <value>
- <option name="FOREGROUND" value="8000" />
- <option name="BACKGROUND" value="ffcccc" />
- </value>
- </option>
<option name="JS.LINE_COMMENT">
<value>
<option name="FOREGROUND" value="d14c42" />
@@ -673,12 +705,6 @@
<option name="EFFECT_TYPE" value="-1" />
</value>
</option>
- <option name="JS.NUMBER">
- <value>
- <option name="FOREGROUND" value="e42713" />
- <option name="FONT_TYPE" value="1" />
- </value>
- </option>
<option name="JS.OPERATION_SIGN">
<value />
</option>
@@ -874,12 +900,6 @@
<option name="EFFECT_TYPE" value="-1" />
</value>
</option>
- <option name="PY.INVALID_STRING_ESCAPE">
- <value>
- <option name="FOREGROUND" value="0" />
- <option name="BACKGROUND" value="ffcccc" />
- </value>
- </option>
<option name="PY.KEYWORD">
<value>
<option name="FOREGROUND" value="cc9900" />
@@ -891,12 +911,6 @@
<option name="FOREGROUND" value="ff6666" />
</value>
</option>
- <option name="PY.NUMBER">
- <value>
- <option name="FOREGROUND" value="ff0000" />
- <option name="FONT_TYPE" value="1" />
- </value>
- </option>
<option name="PY.OPERATION_SIGN">
<value>
<option name="FOREGROUND" value="ffffff" />
@@ -1078,12 +1092,6 @@
<option name="FONT_TYPE" value="1" />
</value>
</option>
- <option name="SASS_NUMBER">
- <value>
- <option name="FOREGROUND" value="ff0000" />
- <option name="FONT_TYPE" value="1" />
- </value>
- </option>
<option name="SASS_RULE">
<value>
<option name="FOREGROUND" value="ffffff" />
@@ -1107,12 +1115,6 @@
<option name="BACKGROUND" value="ffa600" />
</value>
</option>
- <option name="SQL_BAD_CHARACTER">
- <value>
- <option name="FOREGROUND" value="0" />
- <option name="BACKGROUND" value="ffcccc" />
- </value>
- </option>
<option name="SQL_COLUMN">
<value>
<option name="FOREGROUND" value="cc9900" />
@@ -1134,12 +1136,6 @@
<option name="FOREGROUND" value="c0c0c0" />
</value>
</option>
- <option name="SQL_NUMBER">
- <value>
- <option name="FOREGROUND" value="ff0000" />
- <option name="FONT_TYPE" value="1" />
- </value>
- </option>
<option name="SQL_PARAMETER">
<value>
<option name="FOREGROUND" value="6699ff" />
diff --git a/colorSchemes/src/colorSchemes/monokai.xml b/colorSchemes/src/colorSchemes/monokai.xml
index 472c99d..f2d6913 100644
--- a/colorSchemes/src/colorSchemes/monokai.xml
+++ b/colorSchemes/src/colorSchemes/monokai.xml
@@ -196,14 +196,34 @@
<option name="FOREGROUND" value="75715E" />
</value>
</option>
+ <option name="CONSOLE_BLACK_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="000000" />
+ </value>
+ </option>
<option name="CONSOLE_BLUE_OUTPUT">
<value>
- <option name="FOREGROUND" value="c7c7ff" />
+ <option name="FOREGROUND" value="0087D5" />
+ </value>
+ </option>
+ <option name="CONSOLE_BLUE_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="0AA5FF" />
</value>
</option>
<option name="CONSOLE_CYAN_OUTPUT">
<value>
- <option name="FOREGROUND" value="06b8b8" />
+ <option name="FOREGROUND" value="41E3F6" />
+ </value>
+ </option>
+ <option name="CONSOLE_CYAN_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="63E9F8" />
+ </value>
+ </option>
+ <option name="CONSOLE_DARKGRAY_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="555555" />
</value>
</option>
<option name="CONSOLE_ERROR_OUTPUT">
@@ -218,12 +238,23 @@
</option>
<option name="CONSOLE_GREEN_OUTPUT">
<value>
- <option name="FOREGROUND" value="68e868" />
+ <option name="FOREGROUND" value="A3E131" />
</value>
</option>
+ <option name="CONSOLE_GREEN_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="B8E85E" />
+ </value>
+ </option>
+ #A3E131
<option name="CONSOLE_MAGENTA_OUTPUT">
<value>
- <option name="FOREGROUND" value="ff2eff" />
+ <option name="FOREGROUND" value="8666CA" />
+ </value>
+ </option>
+ <option name="CONSOLE_MAGENTA_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="9376D0" />
</value>
</option>
<option name="CONSOLE_NORMAL_OUTPUT">
@@ -233,7 +264,12 @@
</option>
<option name="CONSOLE_RED_OUTPUT">
<value>
- <option name="FOREGROUND" value="ff6767" />
+ <option name="FOREGROUND" value="f10000" />
+ </value>
+ </option>
+ <option name="CONSOLE_RED_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="FF1F1F" />
</value>
</option>
<option name="CONSOLE_SYSTEM_OUTPUT">
@@ -247,9 +283,19 @@
<option name="FONT_TYPE" value="2" />
</value>
</option>
+ <option name="CONSOLE_WHITE_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="ffffff" />
+ </value>
+ </option>
<option name="CONSOLE_YELLOW_OUTPUT">
<value>
- <option name="FOREGROUND" value="754200" />
+ <option name="FOREGROUND" value="DEDB74" />
+ </value>
+ </option>
+ <option name="CONSOLE_YELLOW_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="E8E59C" />
</value>
</option>
<option name="CSS.COMMENT">
diff --git a/colorSchemes/src/colorSchemes/twilight.xml b/colorSchemes/src/colorSchemes/twilight.xml
index d30254e..b7f514e 100644
--- a/colorSchemes/src/colorSchemes/twilight.xml
+++ b/colorSchemes/src/colorSchemes/twilight.xml
@@ -208,14 +208,34 @@
<option name="FONT_TYPE" value="2" />
</value>
</option>
+ <option name="CONSOLE_BLACK_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="000000" />
+ </value>
+ </option>
<option name="CONSOLE_BLUE_OUTPUT">
<value>
- <option name="FOREGROUND" value="c7c7ff" />
+ <option name="FOREGROUND" value="5A80B7" />
+ </value>
+ </option>
+ <option name="CONSOLE_BLUE_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="8598B6" />
</value>
</option>
<option name="CONSOLE_CYAN_OUTPUT">
<value>
- <option name="FOREGROUND" value="06b8b8" />
+ <option name="FOREGROUND" value="6BA3AD" />
+ </value>
+ </option>
+ <option name="CONSOLE_CYAN_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="98A9AC" />
+ </value>
+ </option>
+ <option name="CONSOLE_DARKGRAY_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="555555" />
</value>
</option>
<option name="CONSOLE_ERROR_OUTPUT">
@@ -230,12 +250,23 @@
</option>
<option name="CONSOLE_GREEN_OUTPUT">
<value>
- <option name="FOREGROUND" value="68e868" />
+ <option name="FOREGROUND" value="8CB053" />
</value>
</option>
+ <option name="CONSOLE_GREEN_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="9AAF7C" />
+ </value>
+ </option>
+ #A3E131
<option name="CONSOLE_MAGENTA_OUTPUT">
<value>
- <option name="FOREGROUND" value="ff2eff" />
+ <option name="FOREGROUND" value="754273" />
+ </value>
+ </option>
+ <option name="CONSOLE_MAGENTA_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="755273" />
</value>
</option>
<option name="CONSOLE_NORMAL_OUTPUT">
@@ -245,7 +276,12 @@
</option>
<option name="CONSOLE_RED_OUTPUT">
<value>
- <option name="FOREGROUND" value="ff6767" />
+ <option name="FOREGROUND" value="EC4A00" />
+ </value>
+ </option>
+ <option name="CONSOLE_RED_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="E87854" />
</value>
</option>
<option name="CONSOLE_SYSTEM_OUTPUT">
@@ -259,9 +295,19 @@
<option name="FONT_TYPE" value="2" />
</value>
</option>
+ <option name="CONSOLE_WHITE_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="ffffff" />
+ </value>
+ </option>
<option name="CONSOLE_YELLOW_OUTPUT">
<value>
- <option name="FOREGROUND" value="754200" />
+ <option name="FOREGROUND" value="F3CC6D" />
+ </value>
+ </option>
+ <option name="CONSOLE_YELLOW_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="F3CC6D" />
</value>
</option>
<option name="CSS.COMMENT">
diff --git a/community-resources/src/idea/IdeaApplicationInfo.xml b/community-resources/src/idea/IdeaApplicationInfo.xml
index 8e36755..42da604 100644
--- a/community-resources/src/idea/IdeaApplicationInfo.xml
+++ b/community-resources/src/idea/IdeaApplicationInfo.xml
@@ -23,7 +23,7 @@
<help file="ideahelp.jar" root="idea"/>
<documentation url="http://www.jetbrains.com/idea/documentation"/>
<support url="http://www.jetbrains.com/support/idea/index.html"/>
- <feedback eap-url="http://youtrack.jetbrains.com"
+ <feedback eap-url="http://youtrack.jetbrains.com/newissue?project=IDEA&clearDraft=true&c=Affected+versions+$BUILD"
release-url="http://www.jetbrains.com/feedback/feedback.jsp?product=IDEA&build=$BUILD&timezone=$TIMEZONE&eval=$EVAL"/>
<plugins url="http://plugins.jetbrains.com"/>
<whatsnew url="http://www.jetbrains.com/idea/whatsnew/index.html"/>
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
index d03ec5b..167cd7d 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
@@ -787,7 +787,12 @@
});
}
+ private static final Key<Boolean> OLD_IMPLEMENTATION_WARNING_SHOWN = Key.create("_old_make_implementation_warning_shown_");
private void notifyDeprecatedImplementation() {
+ if (OLD_IMPLEMENTATION_WARNING_SHOWN.get(myProject, Boolean.FALSE).booleanValue()) {
+ return;
+ }
+ OLD_IMPLEMENTATION_WARNING_SHOWN.set(myProject, Boolean.TRUE);
final NotificationListener hyperlinkHandler = new NotificationListener.Adapter() {
@Override
protected void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent e) {
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java
index 8ba9de9..d36a3b0 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java
@@ -1759,7 +1759,7 @@
}
public boolean isMarkedForCompilation(Project project, VirtualFile file) {
- if (CompilerWorkspaceConfiguration.getInstance(project).USE_COMPILE_SERVER) {
+ if (CompilerWorkspaceConfiguration.getInstance(project).useOutOfProcessBuild()) {
final CompilerManager compilerManager = CompilerManager.getInstance(project);
return !compilerManager.isUpToDate(compilerManager.createFilesCompileScope(new VirtualFile[]{file}));
}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.form b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.form
index 36f3b45..5e6fdda 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.form
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.form
@@ -38,7 +38,7 @@
<text resource-bundle="messages/CompilerBundle" key="java.compiler.option.generate.no.warnings"/>
</properties>
</component>
- <grid id="d7ddf" layout-manager="GridLayoutManager" row-count="2" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="d7ddf" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="8" bottom="0" right="0"/>
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -62,33 +62,6 @@
</constraints>
<properties/>
</component>
- <component id="327dc" class="javax.swing.JLabel">
- <constraints>
- <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text resource-bundle="messages/CompilerBundle" key="javac.option.max.heap.size"/>
- </properties>
- </component>
- <component id="15c16" class="javax.swing.JTextField" binding="myJavacMaximumHeapField">
- <constraints>
- <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <columns value="4"/>
- <margin top="0" left="2" bottom="0" right="0"/>
- <text value="128"/>
- </properties>
- </component>
- <component id="6f8c2" class="com.intellij.ui.components.JBLabel">
- <constraints>
- <grid row="1" column="2" row-span="1" col-span="2" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <enabled value="false"/>
- <text value="(ineffective when "Use external build" is on)"/>
- </properties>
- </component>
</children>
</grid>
<vspacer id="af30">
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.java
index ad9cb1d..5227dfc 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.java
@@ -35,7 +35,6 @@
private JCheckBox myCbDebuggingInfo;
private JCheckBox myCbGenerateNoWarnings;
private RawCommandLineEditor myAdditionalOptionsField;
- private JTextField myJavacMaximumHeapField;
private JCheckBox myCbProceedOnErrors;
private final EclipseCompilerOptions myCompilerSettings;
@@ -59,7 +58,7 @@
}
public boolean isModified() {
- boolean isModified = ComparingUtils.isModified(myJavacMaximumHeapField, myCompilerSettings.MAXIMUM_HEAP_SIZE);
+ boolean isModified = false;
isModified |= ComparingUtils.isModified(myCbDeprecation, myCompilerSettings.DEPRECATION);
isModified |= ComparingUtils.isModified(myCbDebuggingInfo, myCompilerSettings.DEBUGGING_INFO);
@@ -70,17 +69,6 @@
}
public void apply() throws ConfigurationException {
-
- try {
- myCompilerSettings.MAXIMUM_HEAP_SIZE = Integer.parseInt(myJavacMaximumHeapField.getText());
- if(myCompilerSettings.MAXIMUM_HEAP_SIZE < 1) {
- myCompilerSettings.MAXIMUM_HEAP_SIZE = 128;
- }
- }
- catch(NumberFormatException exception) {
- myCompilerSettings.MAXIMUM_HEAP_SIZE = 128;
- }
-
myCompilerSettings.DEPRECATION = myCbDeprecation.isSelected();
myCompilerSettings.DEBUGGING_INFO = myCbDebuggingInfo.isSelected();
myCompilerSettings.GENERATE_NO_WARNINGS = myCbGenerateNoWarnings.isSelected();
@@ -89,7 +77,6 @@
}
public void reset() {
- myJavacMaximumHeapField.setText(Integer.toString(myCompilerSettings.MAXIMUM_HEAP_SIZE));
myCbDeprecation.setSelected(myCompilerSettings.DEPRECATION);
myCbDebuggingInfo.setSelected(myCompilerSettings.DEBUGGING_INFO);
myCbGenerateNoWarnings.setSelected(myCompilerSettings.GENERATE_NO_WARNINGS);
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacConfigurable.java
index c51f5f30..1c8910a 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacConfigurable.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacConfigurable.java
@@ -34,7 +34,6 @@
private JCheckBox myCbDeprecation;
private JCheckBox myCbGenerateNoWarnings;
private RawCommandLineEditor myAdditionalOptionsField;
- private JTextField myJavacMaximumHeapField;
private final JpsJavaCompilerOptions myJavacSettings;
public JavacConfigurable(final JpsJavaCompilerOptions javacSettings) {
@@ -56,8 +55,6 @@
public boolean isModified() {
boolean isModified = false;
- isModified |= ComparingUtils.isModified(myJavacMaximumHeapField, myJavacSettings.MAXIMUM_HEAP_SIZE);
-
isModified |= ComparingUtils.isModified(myCbDeprecation, myJavacSettings.DEPRECATION);
isModified |= ComparingUtils.isModified(myCbDebuggingInfo, myJavacSettings.DEBUGGING_INFO);
isModified |= ComparingUtils.isModified(myCbGenerateNoWarnings, myJavacSettings.GENERATE_NO_WARNINGS);
@@ -66,17 +63,6 @@
}
public void apply() throws ConfigurationException {
-
- try {
- myJavacSettings.MAXIMUM_HEAP_SIZE = Integer.parseInt(myJavacMaximumHeapField.getText());
- if(myJavacSettings.MAXIMUM_HEAP_SIZE < 1) {
- myJavacSettings.MAXIMUM_HEAP_SIZE = 128;
- }
- }
- catch(NumberFormatException exception) {
- myJavacSettings.MAXIMUM_HEAP_SIZE = 128;
- }
-
myJavacSettings.DEPRECATION = myCbDeprecation.isSelected();
myJavacSettings.DEBUGGING_INFO = myCbDebuggingInfo.isSelected();
myJavacSettings.GENERATE_NO_WARNINGS = myCbGenerateNoWarnings.isSelected();
@@ -84,7 +70,6 @@
}
public void reset() {
- myJavacMaximumHeapField.setText(Integer.toString(myJavacSettings.MAXIMUM_HEAP_SIZE));
myCbDeprecation.setSelected(myJavacSettings.DEPRECATION);
myCbDebuggingInfo.setSelected(myJavacSettings.DEBUGGING_INFO);
myCbGenerateNoWarnings.setSelected(myJavacSettings.GENERATE_NO_WARNINGS);
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOptionsPanel.form b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOptionsPanel.form
index bf4baec..3dc8e99 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOptionsPanel.form
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOptionsPanel.form
@@ -3,7 +3,7 @@
<grid id="280f7" binding="myPanel" 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="79" y="160" width="574" height="210"/>
+ <xy x="79" y="160" width="577" height="210"/>
</constraints>
<properties/>
<clientProperties>
@@ -37,7 +37,7 @@
<text resource-bundle="messages/CompilerBundle" key="java.compiler.option.generate.no.warnings"/>
</properties>
</component>
- <grid id="d7ddf" layout-manager="GridLayoutManager" row-count="2" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="d7ddf" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="8" bottom="0" right="0"/>
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -61,33 +61,6 @@
</constraints>
<properties/>
</component>
- <component id="327dc" class="javax.swing.JLabel">
- <constraints>
- <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text resource-bundle="messages/CompilerBundle" key="javac.option.max.heap.size"/>
- </properties>
- </component>
- <component id="15c16" class="javax.swing.JTextField" binding="myJavacMaximumHeapField">
- <constraints>
- <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <columns value="4"/>
- <margin top="0" left="2" bottom="0" right="0"/>
- <text value="128"/>
- </properties>
- </component>
- <component id="9ae23" class="com.intellij.ui.components.JBLabel">
- <constraints>
- <grid row="1" column="2" row-span="1" col-span="2" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <enabled value="false"/>
- <text value="(ineffective when "Use external build" is on)"/>
- </properties>
- </component>
</children>
</grid>
<vspacer id="72a3c">
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsPanel.form b/java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsPanel.form
index 179dbe2..c89fdca 100644
--- a/java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsPanel.form
+++ b/java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsPanel.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="com.intellij.compiler.options.CompilerUIConfigurable">
- <grid id="1663f" binding="myPanel" layout-manager="GridLayoutManager" row-count="11" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="1663f" binding="myPanel" layout-manager="GridLayoutManager" row-count="10" 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>
<xy x="28" y="24" width="883" height="379"/>
@@ -10,7 +10,7 @@
<children>
<vspacer id="67edf">
<constraints>
- <grid row="10" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ <grid row="9" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<grid id="b341d" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="1">
@@ -76,17 +76,9 @@
<text resource-bundle="messages/CompilerBundle" key="label.option.autoshow.first.error"/>
</properties>
</component>
- <component id="ce617" class="javax.swing.JCheckBox" binding="myCbUseExternalBuild" default-binding="true">
- <constraints>
- <grid row="4" column="0" 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="Use external build"/>
- </properties>
- </component>
<component id="b9b2d" class="javax.swing.JCheckBox" binding="myCbEnableAutomake">
<constraints>
- <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+ <grid row="4" column="0" 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="Make project automatically"/>
@@ -94,7 +86,7 @@
</component>
<component id="17126" class="javax.swing.JLabel" binding="myHeapSizeLabel">
<constraints>
- <grid row="8" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+ <grid row="7" 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>
<text value="Compiler process heap size (Mbytes):"/>
@@ -102,7 +94,7 @@
</component>
<component id="a28b8" class="javax.swing.JTextField" binding="myHeapSizeField">
<constraints>
- <grid row="8" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false">
+ <grid row="7" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false">
<preferred-size width="50" height="-1"/>
</grid>
</constraints>
@@ -110,7 +102,7 @@
</component>
<component id="5b86a" class="javax.swing.JLabel" binding="myVMOptionsLabel">
<constraints>
- <grid row="9" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+ <grid row="8" 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>
<text value="Additional compiler process VM options:"/>
@@ -118,7 +110,7 @@
</component>
<component id="b5547" class="javax.swing.JTextField" binding="myVMOptionsField">
<constraints>
- <grid row="9" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <grid row="8" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
@@ -126,7 +118,7 @@
</component>
<component id="ba694" class="javax.swing.JCheckBox" binding="myCbParallelCompilation">
<constraints>
- <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+ <grid row="5" column="0" 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="Compile independent modules in parallel"/>
@@ -134,7 +126,7 @@
</component>
<component id="91979" class="javax.swing.JLabel" binding="myParallelCompilationLegendLabel">
<constraints>
- <grid row="6" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="5" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="(may require larger heap size)"/>
@@ -142,7 +134,7 @@
</component>
<component id="732b1" class="javax.swing.JLabel" binding="myEnableAutomakeLegendLabel">
<constraints>
- <grid row="5" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="4" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="(only works while not running / debugging)"/>
@@ -150,7 +142,7 @@
</component>
<component id="4b44" class="javax.swing.JCheckBox" binding="myCbRebuildOnDependencyChange" default-binding="true">
<constraints>
- <grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+ <grid row="6" column="0" 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="Rebuild module on dependency change"/>
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java
index 38769dc..b97a103 100644
--- a/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java
+++ b/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java
@@ -36,11 +36,9 @@
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
import java.util.*;
-import static com.intellij.compiler.options.CompilerOptionsFilter.*;
+import static com.intellij.compiler.options.CompilerOptionsFilter.Setting;
public class CompilerUIConfigurable implements SearchableConfigurable, Configurable.NoScroll {
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.options.CompilerUIConfigurable");
@@ -77,7 +75,6 @@
private JCheckBox myCbAssertNotNull;
private JBLabel myPatternLegendLabel;
private JCheckBox myCbAutoShowFirstError;
- private JCheckBox myCbUseExternalBuild;
private JCheckBox myCbEnableAutomake;
private JCheckBox myCbParallelCompilation;
private JTextField myHeapSizeField;
@@ -93,19 +90,12 @@
myProject = project;
myPatternLegendLabel.setText("<html><body>" +
- "Use <b>;</b> to separate patterns and <b>!</b> to negate a pattern. " +
- "Accepted wildcards: <b>?</b> — exactly one symbol; <b>*</b> — zero or more symbols; " +
- "<b>/</b> — path separator; <b>/**/</b> — any number of directories; " +
- "<i><dir_name></i>:<i><pattern></i> — restrict to source roots with the specified name" +
- "</body></html>");
+ "Use <b>;</b> to separate patterns and <b>!</b> to negate a pattern. " +
+ "Accepted wildcards: <b>?</b> — exactly one symbol; <b>*</b> — zero or more symbols; " +
+ "<b>/</b> — path separator; <b>/**/</b> — any number of directories; " +
+ "<i><dir_name></i>:<i><pattern></i> — restrict to source roots with the specified name" +
+ "</body></html>");
myPatternLegendLabel.setForeground(new JBColor(Gray._50, Gray._130));
- myCbUseExternalBuild.addItemListener(new ItemListener() {
- @Override
- public void itemStateChanged(ItemEvent e) {
- updateExternalMakeOptionControls(myCbUseExternalBuild.isSelected());
- }
- });
-
tweakControls(project);
}
@@ -141,7 +131,6 @@
controls.put(Setting.CLEAR_OUTPUT_DIR_ON_REBUILD, Collections.<JComponent>singleton(myCbClearOutputDirectory));
controls.put(Setting.ADD_NOT_NULL_ASSERTIONS, Collections.<JComponent>singleton(myCbAssertNotNull));
controls.put(Setting.AUTO_SHOW_FIRST_ERROR_IN_EDITOR, Collections.<JComponent>singleton(myCbAutoShowFirstError));
- controls.put(Setting.EXTERNAL_BUILD, ContainerUtilRt.<JComponent>newArrayList(myCbUseExternalBuild));
controls.put(Setting.AUTO_MAKE, ContainerUtilRt.<JComponent>newArrayList(myCbEnableAutomake, myEnableAutomakeLegendLabel));
controls.put(Setting.PARALLEL_COMPILATION,
ContainerUtilRt.<JComponent>newArrayList(myCbParallelCompilation, myParallelCompilationLegendLabel));
@@ -166,14 +155,12 @@
myCbAutoShowFirstError.setSelected(workspaceConfiguration.AUTO_SHOW_ERRORS_IN_EDITOR);
myCbClearOutputDirectory.setSelected(workspaceConfiguration.CLEAR_OUTPUT_DIRECTORY);
myCbAssertNotNull.setSelected(configuration.isAddNotNullAssertions());
- myCbUseExternalBuild.setSelected(workspaceConfiguration.USE_COMPILE_SERVER);
myCbEnableAutomake.setSelected(workspaceConfiguration.MAKE_PROJECT_ON_SAVE);
myCbParallelCompilation.setSelected(workspaceConfiguration.PARALLEL_COMPILATION);
myCbRebuildOnDependencyChange.setSelected(workspaceConfiguration.REBUILD_ON_DEPENDENCY_CHANGE);
myHeapSizeField.setText(String.valueOf(workspaceConfiguration.COMPILER_PROCESS_HEAP_SIZE));
final String options = workspaceConfiguration.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS;
myVMOptionsField.setText(options == null ? "" : options.trim());
- updateExternalMakeOptionControls(myCbUseExternalBuild.isSelected());
configuration.convertPatterns();
@@ -201,9 +188,7 @@
if (!myDisabledSettings.contains(Setting.CLEAR_OUTPUT_DIR_ON_REBUILD)) {
workspaceConfiguration.CLEAR_OUTPUT_DIRECTORY = myCbClearOutputDirectory.isSelected();
}
- boolean wasUsingExternalMake = workspaceConfiguration.USE_COMPILE_SERVER;
if (!myDisabledSettings.contains(Setting.EXTERNAL_BUILD)) {
- workspaceConfiguration.USE_COMPILE_SERVER = myCbUseExternalBuild.isSelected();
if (!myDisabledSettings.contains(Setting.AUTO_MAKE)) {
workspaceConfiguration.MAKE_PROJECT_ON_SAVE = myCbEnableAutomake.isSelected();
}
@@ -234,12 +219,8 @@
String extensionString = myResourcePatternsField.getText().trim();
applyResourcePatterns(extensionString, (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject));
}
- if (wasUsingExternalMake != workspaceConfiguration.USE_COMPILE_SERVER) {
- myProject.getMessageBus().syncPublisher(ExternalBuildOptionListener.TOPIC).externalBuildOptionChanged(workspaceConfiguration.USE_COMPILE_SERVER);
- }
- if (workspaceConfiguration.USE_COMPILE_SERVER) {
- BuildManager.getInstance().clearState(myProject);
- }
+
+ BuildManager.getInstance().clearState(myProject);
}
private static void applyResourcePatterns(String extensionString, final CompilerConfigurationImpl configuration)
@@ -277,8 +258,6 @@
final CompilerWorkspaceConfiguration workspaceConfiguration = CompilerWorkspaceConfiguration.getInstance(myProject);
boolean isModified = !myDisabledSettings.contains(Setting.AUTO_SHOW_FIRST_ERROR_IN_EDITOR)
&& ComparingUtils.isModified(myCbAutoShowFirstError, workspaceConfiguration.AUTO_SHOW_ERRORS_IN_EDITOR);
- isModified |= !myDisabledSettings.contains(Setting.EXTERNAL_BUILD)
- && ComparingUtils.isModified(myCbUseExternalBuild, workspaceConfiguration.USE_COMPILE_SERVER);
isModified |= !myDisabledSettings.contains(Setting.AUTO_MAKE)
&& ComparingUtils.isModified(myCbEnableAutomake, workspaceConfiguration.MAKE_PROJECT_ON_SAVE);
isModified |= !myDisabledSettings.contains(Setting.PARALLEL_COMPILATION)
@@ -325,16 +304,6 @@
public void disposeUIResources() {
}
- private void updateExternalMakeOptionControls(boolean enabled) {
- myCbEnableAutomake.setEnabled(enabled);
- myCbParallelCompilation.setEnabled(enabled);
- myCbRebuildOnDependencyChange.setEnabled(enabled);
- myHeapSizeField.setEnabled(enabled);
- myVMOptionsField.setEnabled(enabled);
- myHeapSizeLabel.setEnabled(enabled);
- myVMOptionsLabel.setEnabled(enabled);
- }
-
private void createUIComponents() {
myResourcePatternsField = new RawCommandLineEditor(LINE_PARSER, LINE_JOINER);
myResourcePatternsField.setDialogCaption("Resource patterns");
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/util/InspectionValidatorWrapper.java b/java/compiler/impl/src/com/intellij/openapi/compiler/util/InspectionValidatorWrapper.java
index 88fe95c..cadbc0f 100644
--- a/java/compiler/impl/src/com/intellij/openapi/compiler/util/InspectionValidatorWrapper.java
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/util/InspectionValidatorWrapper.java
@@ -58,6 +58,7 @@
private final InspectionProjectProfileManager myProfileManager;
private final PsiDocumentManager myPsiDocumentManager;
private static final ThreadLocal<Boolean> ourCompilationThreads = new ThreadLocal<Boolean>() {
+ @Override
protected Boolean initialValue() {
return Boolean.FALSE;
}
@@ -95,11 +96,13 @@
myVirtualFile = psiFile.getVirtualFile();
}
+ @Override
@NotNull
public VirtualFile getFile() {
return myVirtualFile;
}
+ @Override
@Nullable
public ValidityState getValidityState() {
if (myValidityState == null) {
@@ -121,6 +124,7 @@
}
}
+ @Override
@NotNull
public ProcessingItem[] getProcessingItems(final CompileContext context) {
final Project project = context.getProject();
@@ -129,6 +133,7 @@
}
final ExcludedEntriesConfiguration excludedEntriesConfiguration = ValidationConfiguration.getExcludedEntriesConfiguration(project);
final List<ProcessingItem> items = new ReadAction<List<ProcessingItem>>() {
+ @Override
protected void run(final Result<List<ProcessingItem>> result) {
final CompileScope compileScope = context.getCompileScope();
if (!myValidator.isAvailableOnScope(compileScope)) return;
@@ -167,6 +172,7 @@
return items.toArray(new ProcessingItem[items.size()]);
}
+ @Override
public ProcessingItem[] process(final CompileContext context, final ProcessingItem[] items) {
context.getProgressIndicator().setText(myValidator.getProgressIndicatorText());
@@ -307,7 +313,13 @@
final List<ExternalAnnotator> annotators = ExternalLanguageAnnotators.allForFile(StdLanguages.XML, xmlFile);
for (ExternalAnnotator annotator : annotators) {
- annotator.annotate(xmlFile, holder);
+ Object initial = annotator.collectInformation(xmlFile);
+ if (initial != null) {
+ Object result = annotator.doAnnotate(initial);
+ if (result != null) {
+ annotator.apply(xmlFile, result, holder);
+ }
+ }
}
if (!holder.hasAnnotations()) return Collections.emptyMap();
@@ -331,15 +343,18 @@
}
+ @Override
@NotNull
public String getDescription() {
return myValidator.getDescription();
}
+ @Override
public boolean validateConfiguration(final CompileScope scope) {
return true;
}
+ @Override
public ValidityState createValidityState(final DataInput in) throws IOException {
return PsiElementsValidityState.load(in);
}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/FacetBasedPackagingElementType.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FacetBasedPackagingElementType.java
index dc0383f..e82f277e 100644
--- a/java/compiler/impl/src/com/intellij/packaging/impl/elements/FacetBasedPackagingElementType.java
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FacetBasedPackagingElementType.java
@@ -28,7 +28,6 @@
import com.intellij.packaging.ui.ArtifactEditorContext;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
@@ -89,11 +88,6 @@
protected abstract String getItemText(F item);
- @Nullable
- protected Icon getIcon(F item) {
- return FacetTypeRegistry.getInstance().findFacetType(myFacetType).getIcon();
- }
-
private class ChooseFacetsDialog extends ChooseElementsDialog<F> {
private ChooseFacetsDialog(Project project, List<? extends F> items, String title, String description) {
super(project, items, title, description, true);
@@ -106,7 +100,7 @@
@Override
protected Icon getItemIcon(F item) {
- return FacetBasedPackagingElementType.this.getIcon(item);
+ return FacetTypeRegistry.getInstance().findFacetType(myFacetType).getIcon();
}
}
}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java b/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java
index 629a488..57ca440 100644
--- a/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java
+++ b/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java
@@ -43,7 +43,7 @@
public boolean AUTO_SHOW_ERRORS_IN_EDITOR = true;
@Deprecated public boolean CLOSE_MESSAGE_VIEW_IF_SUCCESS = true;
public boolean CLEAR_OUTPUT_DIRECTORY = true;
- public boolean USE_COMPILE_SERVER = true;
+ public boolean USE_OUT_OF_PROCESS_BUILD = true;
public boolean MAKE_PROJECT_ON_SAVE = false; // until we fix problems with several open projects (IDEA-104064), daemon slowness (IDEA-104666)
public boolean PARALLEL_COMPILATION = false;
public int COMPILER_PROCESS_HEAP_SIZE = DEFAULT_COMPILE_PROCESS_HEAP_SIZE;
@@ -63,7 +63,7 @@
}
public boolean useOutOfProcessBuild() {
- return USE_COMPILE_SERVER;
+ return USE_OUT_OF_PROCESS_BUILD;
}
public boolean allowAutoMakeWhileRunningApplication() {
diff --git a/java/debugger/impl/src/com/intellij/debugger/DebuggerInvocationUtil.java b/java/debugger/impl/src/com/intellij/debugger/DebuggerInvocationUtil.java
index c0dfbb9..ebb5bef 100644
--- a/java/debugger/impl/src/com/intellij/debugger/DebuggerInvocationUtil.java
+++ b/java/debugger/impl/src/com/intellij/debugger/DebuggerInvocationUtil.java
@@ -22,76 +22,79 @@
import com.intellij.openapi.util.Computable;
import com.intellij.psi.PsiDocumentManager;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public class DebuggerInvocationUtil {
- public static void swingInvokeLater(final Project project, @NotNull final Runnable runnable) {
+ public static void swingInvokeLater(@Nullable final Project project, @NotNull final Runnable runnable) {
+ if (project == null) {
+ return;
+ }
+
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
- if (project != null && !project.isDisposed()) {
- runnable.run();
- }
- }
- });
- }
- public static void invokeLater(final Project project, @NotNull final Runnable runnable) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- public void run() {
- if (project != null && !project.isDisposed()) {
+ if (!project.isDisposed()) {
runnable.run();
}
}
});
}
- public static void invokeLater(final Project project, @NotNull final Runnable runnable, ModalityState state) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- public void run() {
- if(project == null || project.isDisposed()) return;
+ public static void invokeLater(@Nullable Project project, @NotNull Runnable runnable) {
+ if (project != null) {
+ ApplicationManager.getApplication().invokeLater(runnable, project.getDisposed());
+ }
+ }
- runnable.run();
- }
- }, state);
+ public static void invokeLater(@Nullable Project project, @NotNull Runnable runnable, ModalityState state) {
+ if (project != null) {
+ ApplicationManager.getApplication().invokeLater(runnable, state, project.getDisposed());
+ }
}
public static void invokeAndWait(final Project project, @NotNull final Runnable runnable, ModalityState state) {
- ApplicationManager.getApplication().invokeAndWait(new Runnable() {
- public void run() {
- if(project == null || project.isDisposed()) return;
-
- runnable.run();
- }
- }, state);
+ if (project != null) {
+ ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ if (!project.isDisposed()) {
+ runnable.run();
+ }
+ }
+ }, state);
+ }
}
- public static <T> T commitAndRunReadAction(Project project, final EvaluatingComputable<T> computable) throws EvaluateException {
- final Throwable[] ex = new Throwable[] { null };
+ public static <T> T commitAndRunReadAction(Project project, final EvaluatingComputable<T> computable) throws EvaluateException {
+ final Throwable[] ex = new Throwable[]{null};
T result = PsiDocumentManager.getInstance(project).commitAndRunReadAction(new Computable<T>() {
- public T compute() {
- try {
- return computable.compute();
- }
- catch (RuntimeException e) {
- ex[0] = e;
- }
- catch (Exception th) {
- ex[0] = th;
- }
+ @Override
+ public T compute() {
+ try {
+ return computable.compute();
+ }
+ catch (RuntimeException e) {
+ ex[0] = e;
+ }
+ catch (Exception th) {
+ ex[0] = th;
+ }
- return null;
- }
- });
+ return null;
+ }
+ });
- if(ex[0] != null) {
- if(ex[0] instanceof RuntimeException) {
+ if (ex[0] != null) {
+ if (ex[0] instanceof RuntimeException) {
throw (RuntimeException)ex[0];
}
else {
- throw (EvaluateException) ex[0];
+ throw (EvaluateException)ex[0];
}
}
return result;
}
-}
+}
\ No newline at end of file
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JavaEditBreakpointActionHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaEditBreakpointActionHandler.java
index deb5752..54cef88 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/JavaEditBreakpointActionHandler.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaEditBreakpointActionHandler.java
@@ -19,8 +19,8 @@
import com.intellij.debugger.ui.breakpoints.BreakpointPropertiesPanel;
import com.intellij.debugger.ui.breakpoints.BreakpointWithHighlighter;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
@@ -28,7 +28,7 @@
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupListener;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
-import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.util.ui.UIUtil;
@@ -41,48 +41,31 @@
import javax.swing.*;
import java.awt.*;
-/**
- * Created with IntelliJ IDEA.
- * User: zajac
- * Date: 04.05.12
- * Time: 4:10
- * To change this template use File | Settings | File Templates.
- */
public class JavaEditBreakpointActionHandler extends EditBreakpointActionHandler {
@Override
protected void doShowPopup(final Project project, final JComponent component, final Point whereToShow, final Object breakpoint) {
- if (!(breakpoint instanceof BreakpointWithHighlighter)) return;
+ if (!(breakpoint instanceof BreakpointWithHighlighter)) {
+ return;
+ }
final BreakpointWithHighlighter javaBreakpoint = (BreakpointWithHighlighter)breakpoint;
- Key<? extends BreakpointWithHighlighter> category = javaBreakpoint.getCategory();
-
- final BreakpointFactory[] allFactories = ApplicationManager.getApplication().getExtensions(BreakpointFactory.EXTENSION_POINT_NAME);
BreakpointFactory breakpointFactory = null;
- for (BreakpointFactory factory : allFactories) {
- if (factory.getBreakpointCategory().equals(category)) {
+ for (BreakpointFactory factory : BreakpointFactory.EXTENSION_POINT_NAME.getExtensions()) {
+ if (factory.getBreakpointCategory().equals(javaBreakpoint.getCategory())) {
breakpointFactory = factory;
}
}
assert breakpointFactory != null : "can't find factory for breakpoint " + javaBreakpoint;
final BreakpointPropertiesPanel propertiesPanel = breakpointFactory.createBreakpointPropertiesPanel(project, true);
+ assert propertiesPanel != null;
propertiesPanel.initFrom(javaBreakpoint, false);
final JComponent mainPanel = propertiesPanel.getPanel();
- final String displayName = javaBreakpoint.getDisplayName();
-
- final JBPopupListener saveOnClose = new JBPopupListener() {
- @Override
- public void beforeShown(LightweightWindowEvent event) {
- }
-
+ final JBPopupListener saveOnClose = new JBPopupListener.Adapter() {
@Override
public void onClosed(LightweightWindowEvent event) {
- propertiesPanel.saveTo(javaBreakpoint, new Runnable() {
- @Override
- public void run() {
- }
- });
+ propertiesPanel.saveTo(javaBreakpoint, EmptyRunnable.getInstance());
}
};
@@ -93,13 +76,12 @@
@Override
public void run() {
BreakpointsDialogFactory.getInstance(project).showDialog(javaBreakpoint);
-
}
});
}
};
- final Balloon balloon = DebuggerUIUtil.showBreakpointEditor(project, mainPanel, displayName, whereToShow, component, showMoreOptions,
- breakpoint);
+
+ final Balloon balloon = DebuggerUIUtil.showBreakpointEditor(project, mainPanel, whereToShow, component, showMoreOptions, breakpoint);
balloon.addListener(saveOnClose);
propertiesPanel.setDelegate(new BreakpointPropertiesPanel.Delegate() {
@@ -107,9 +89,7 @@
public void showActionsPanel() {
propertiesPanel.setActionsPanelVisible(true);
balloon.hide();
- final Balloon newBalloon =
- DebuggerUIUtil.showBreakpointEditor(project, mainPanel, displayName, whereToShow, component, showMoreOptions, breakpoint);
- newBalloon.addListener(saveOnClose);
+ DebuggerUIUtil.showBreakpointEditor(project, mainPanel, whereToShow, component, showMoreOptions, breakpoint).addListener(saveOnClose);
}
});
@@ -124,7 +104,7 @@
@Override
public boolean isEnabled(@NotNull Project project, AnActionEvent event) {
DataContext dataContext = event.getDataContext();
- Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
+ Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
if (editor == null) {
return false;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java
index 0247790..54d1545 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java
@@ -19,9 +19,9 @@
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.InstanceFilter;
import com.intellij.debugger.SourcePosition;
+import com.intellij.debugger.engine.DebuggerUtils;
import com.intellij.debugger.engine.requests.RequestManagerImpl;
import com.intellij.debugger.impl.DebuggerSession;
-import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.ui.breakpoints.Breakpoint;
import com.intellij.debugger.ui.breakpoints.BreakpointManager;
import com.intellij.debugger.ui.breakpoints.FieldBreakpoint;
@@ -33,7 +33,6 @@
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
@@ -50,8 +49,9 @@
*/
public class ToggleFieldBreakpointAction extends AnAction {
+ @Override
public void actionPerformed(AnActionEvent e) {
- Project project = e.getData(PlatformDataKeys.PROJECT);
+ Project project = e.getData(CommonDataKeys.PROJECT);
if (project == null) {
return;
}
@@ -83,7 +83,7 @@
RequestManagerImpl.createRequests(fieldBreakpoint);
- manager.editBreakpoint(fieldBreakpoint, PlatformDataKeys.EDITOR.getData(e.getDataContext()));
+ manager.editBreakpoint(fieldBreakpoint, CommonDataKeys.EDITOR.getData(e.getDataContext()));
}
}
else {
@@ -93,6 +93,7 @@
}
}
+ @Override
public void update(AnActionEvent event){
SourcePosition place = getPlace(event);
boolean toEnable = place != null;
@@ -105,7 +106,7 @@
}
else if(DebuggerAction.isContextView(event)) {
presentation.setText(DebuggerBundle.message("action.add.field.watchpoint.text"));
- Project project = event.getData(PlatformDataKeys.PROJECT);
+ Project project = event.getData(CommonDataKeys.PROJECT);
if(project != null && place != null) {
Document document = PsiDocumentManager.getInstance(project).getDocument(place.getFile());
if (document != null) {
@@ -125,14 +126,14 @@
@Nullable
public static SourcePosition getPlace(AnActionEvent event) {
final DataContext dataContext = event.getDataContext();
- Project project = event.getData(PlatformDataKeys.PROJECT);
+ Project project = event.getData(CommonDataKeys.PROJECT);
if(project == null) {
return null;
}
if (ActionPlaces.PROJECT_VIEW_POPUP.equals(event.getPlace()) ||
ActionPlaces.STRUCTURE_VIEW_POPUP.equals(event.getPlace()) ||
ActionPlaces.FAVORITES_VIEW_POPUP.equals(event.getPlace())) {
- final PsiElement psiElement = event.getData(LangDataKeys.PSI_ELEMENT);
+ final PsiElement psiElement = event.getData(CommonDataKeys.PSI_ELEMENT);
if(psiElement instanceof PsiField) {
return SourcePosition.createFromElement(psiElement);
}
@@ -152,7 +153,7 @@
if(node != null && node.getDescriptor() instanceof FieldDescriptorImpl) {
Field field = ((FieldDescriptorImpl)node.getDescriptor()).getField();
DebuggerSession session = tree.getDebuggerContext().getDebuggerSession();
- PsiClass psiClass = DebuggerUtilsEx.findClass(field.declaringType().name(), project, (session != null) ? session.getSearchScope(): GlobalSearchScope.allScope(project));
+ PsiClass psiClass = DebuggerUtils.findClass(field.declaringType().name(), project, (session != null) ? session.getSearchScope() : GlobalSearchScope.allScope(project));
if(psiClass != null) {
psiClass = (PsiClass) psiClass.getNavigationElement();
final PsiField psiField = psiClass.findFieldByName(field.name(), true);
@@ -165,7 +166,7 @@
return null;
}
- Editor editor = event.getData(PlatformDataKeys.EDITOR);
+ Editor editor = event.getData(CommonDataKeys.EDITOR);
if(editor == null) {
editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
}
@@ -173,7 +174,6 @@
final Document document = editor.getDocument();
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
if (file != null) {
- FileTypeManager fileTypeManager = FileTypeManager.getInstance();
final VirtualFile virtualFile = file.getVirtualFile();
FileType fileType = virtualFile != null ? virtualFile.getFileType() : null;
if (StdFileTypes.JAVA == fileType || StdFileTypes.CLASS == fileType) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java
index 9d10487..63a2ce8 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java
@@ -142,7 +142,7 @@
}
private void addLocatableRequest(FilteredRequestor requestor, EventRequest request) {
- if(DebuggerSettings.SUSPEND_ALL.equals(requestor.SUSPEND_POLICY)) {
+ if(DebuggerSettings.SUSPEND_ALL.equals(requestor.getSuspendPolicy())) {
request.setSuspendPolicy(EventRequest.SUSPEND_ALL);
}
else {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpointFactory.java
index 79398de..f595c1d 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpointFactory.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpointFactory.java
@@ -15,13 +15,10 @@
*/
package com.intellij.debugger.ui.breakpoints;
-import com.intellij.debugger.ui.breakpoints.actions.BreakpointPanelAction;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Key;
import org.jdom.Element;
-import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -58,19 +55,10 @@
}
@Override
- protected BreakpointPanelAction[] createBreakpointPanelActions(Project project, DialogWrapper parentDialog) {
- return new BreakpointPanelAction[0]; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
public boolean breakpointCanBeRemoved(Breakpoint breakpoint) {
return false;
}
- public @Nullable BreakpointPanel createBreakpointPanel(Project project, DialogWrapper parentDialog) {
- return null;
- }
-
public Key<AnyExceptionBreakpoint> getBreakpointCategory() {
return AnyExceptionBreakpoint.ANY_EXCEPTION_BREAKPOINT;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointFactory.java
index 6389fdd..2077b56 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointFactory.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointFactory.java
@@ -15,11 +15,9 @@
*/
package com.intellij.debugger.ui.breakpoints;
-import com.intellij.debugger.ui.breakpoints.actions.BreakpointPanelAction;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Key;
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointItem;
import org.jdom.Element;
@@ -42,14 +40,6 @@
public abstract Key<? extends Breakpoint> getBreakpointCategory();
- public BreakpointPanel createBreakpointPanel(final Project project, final DialogWrapper parentDialog) {
- BreakpointPanel panel =
- new BreakpointPanel(project, createBreakpointPropertiesPanel(project, false), createBreakpointPanelActions(project, parentDialog),
- getBreakpointCategory(), getDisplayName(), getHelpID());
- configureBreakpointPanel(panel);
- return panel;
- }
-
public abstract Icon getIcon();
public abstract Icon getDisabledIcon();
@@ -75,8 +65,6 @@
@Nullable
public abstract BreakpointPropertiesPanel createBreakpointPropertiesPanel(Project project, boolean compact);
- protected abstract BreakpointPanelAction[] createBreakpointPanelActions(Project project, DialogWrapper parentDialog);
-
@Nullable
public Breakpoint addBreakpoint(Project project) {
return null;
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java
index dd52bcf..686965f 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java
@@ -25,7 +25,6 @@
import com.intellij.debugger.DebuggerInvocationUtil;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.engine.DebugProcessImpl;
-import com.intellij.debugger.engine.DebuggerUtils;
import com.intellij.debugger.engine.evaluation.CodeFragmentKind;
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
import com.intellij.debugger.engine.requests.RequestManagerImpl;
@@ -47,12 +46,12 @@
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.TextEditor;
-import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.*;
+import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiFile;
@@ -73,6 +72,7 @@
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.java.debugger.breakpoints.JavaBreakpointType;
import javax.swing.*;
import java.awt.event.MouseEvent;
@@ -182,14 +182,10 @@
}
final Document document = editor.getDocument();
final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
- if (psiFile == null) {
+ if (!JavaBreakpointType.doCanPutAt(psiFile)) {
return null;
}
- final FileType fileType = psiFile.getFileType();
- boolean isInsideCompiledClass = StdFileTypes.CLASS.equals(fileType);
- if (!isInsideCompiledClass && !(DebuggerUtils.supportsJVMDebugging(fileType) || DebuggerUtils.supportsJVMDebugging(psiFile))) {
- return null;
- }
+
PsiDocumentManager.getInstance(myProject).commitDocument(document);
int offset = editor.getCaretModel().getOffset();
@@ -205,6 +201,7 @@
Breakpoint breakpoint = findBreakpoint(document, offset, null);
if (breakpoint == null) {
+ boolean isInsideCompiledClass = StdFileTypes.CLASS.equals(psiFile.getFileType());
if (mostSuitingBreakpoint || isInsideCompiledClass) {
breakpoint = addFieldBreakpoint(document, offset);
if (breakpoint == null) {
@@ -298,7 +295,8 @@
return;
}
- if (XDebuggerUtil.getInstance().canPutBreakpointAt(myProject, FileDocumentManager.getInstance().getFile(document), line)) {
+ VirtualFile file = FileDocumentManager.getInstance().getFile(document);
+ if (file != null && XDebuggerUtil.getInstance().canPutBreakpointAt(myProject, file, line)) {
return;
}
e.consume();
@@ -346,6 +344,7 @@
@Override
public void documentChanged(@NotNull final DocumentEvent e) {
final Document document = e.getDocument();
+ //noinspection SynchronizeOnThis
synchronized (BreakpointManager.this) {
List<BreakpointWithHighlighter> breakpoints = myDocumentBreakpoints.get(document);
@@ -374,8 +373,7 @@
DebuggerInvocationUtil.swingInvokeLater(myProject, new Runnable() {
@Override
public void run() {
- final GutterIconRenderer renderer =
- (GutterIconRenderer)((BreakpointWithHighlighter)breakpoint).getHighlighter().getGutterIconRenderer();
+ final GutterIconRenderer renderer = ((BreakpointWithHighlighter)breakpoint).getHighlighter().getGutterIconRenderer();
if (renderer != null) {
DebuggerSupport.getDebuggerSupport(JavaDebuggerSupport.class).getEditBreakpointAction()
.editBreakpoint(myProject, editor, breakpoint, renderer);
@@ -539,6 +537,7 @@
for (final Breakpoint breakpoint : getBreakpoints()) {
if (breakpoint instanceof BreakpointWithHighlighter && ((BreakpointWithHighlighter)breakpoint).isAt(document, offset)) {
if (category == null || category.equals(breakpoint.getCategory())) {
+ //noinspection CastConflictsWithInstanceof,unchecked
return (T)breakpoint;
}
}
@@ -662,18 +661,15 @@
public synchronized void addBreakpoint(Breakpoint breakpoint) {
myBreakpoints.add(breakpoint);
myBreakpointsListForIteration = null;
- if(breakpoint instanceof BreakpointWithHighlighter) {
+ if (breakpoint instanceof BreakpointWithHighlighter) {
BreakpointWithHighlighter breakpointWithHighlighter = (BreakpointWithHighlighter)breakpoint;
Document document = breakpointWithHighlighter.getDocument();
- if(document != null) {
- List<BreakpointWithHighlighter> breakpoints = myDocumentBreakpoints.get(document);
-
- if(breakpoints == null) {
- breakpoints = new ArrayList<BreakpointWithHighlighter>();
- myDocumentBreakpoints.put(document, breakpoints);
- }
- breakpoints.add(breakpointWithHighlighter);
+ List<BreakpointWithHighlighter> breakpoints = myDocumentBreakpoints.get(document);
+ if (breakpoints == null) {
+ breakpoints = new ArrayList<BreakpointWithHighlighter>();
+ myDocumentBreakpoints.put(document, breakpoints);
}
+ breakpoints.add(breakpointWithHighlighter);
}
myDispatcher.getMulticaster().breakpointsChanged();
}
@@ -812,7 +808,7 @@
/**
* @return breakpoints of one of the category:
- * LINE_BREAKPOINTS, EXCEPTION_BREKPOINTS, FIELD_BREAKPOINTS, METHOD_BREAKPOINTS
+ * LINE_BREAKPOINTS, EXCEPTION_BREAKPOINTS, FIELD_BREAKPOINTS, METHOD_BREAKPOINTS
*/
public <T extends Breakpoint> Breakpoint[] getBreakpoints(@NotNull final Key<T> category) {
ApplicationManager.getApplication().assertIsDispatchThread();
@@ -977,7 +973,6 @@
public void removeBreakpointManagerListener(@NotNull BreakpointManagerListener listener) {
myDispatcher.removeListener(listener);
}
-
private boolean myAllowMulticasting = true;
private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
index 1217e16..5ed3c10 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
@@ -196,6 +196,7 @@
public MyTextField() {
}
+ @Override
public String getToolTipText(MouseEvent event) {
reloadClassFilters();
updateClassFilterEditor(false);
@@ -205,6 +206,7 @@
return getToolTipText().length() == 0 ? null : toolTipText;
}
+ @Override
public JToolTip createToolTip() {
JToolTip toolTip = new JToolTip(){{
setUI(new MultiLineTooltipUI());
@@ -230,6 +232,7 @@
updateSuspendPolicyRbFont();
final ItemListener suspendPolicyChangeListener = new ItemListener() {
+ @Override
public void itemStateChanged(final ItemEvent e) {
final BreakpointDefaults defaults = getBreakpointManager(myProject).getBreakpointDefaults(breakpointCategory);
myMakeDefaultButton.setEnabled(!defaults.getSuspendPolicy().equals(getSelectedSuspendPolicy()) || defaults.isConditionEnabled() != myConditionCheckbox.isSelected());
@@ -251,6 +254,7 @@
myConditionCheckbox.addItemListener(suspendPolicyChangeListener);
myMakeDefaultButton.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(final ActionEvent e) {
final BreakpointManager breakpointManager = getBreakpointManager(myProject);
final String suspendPolicy = getSelectedSuspendPolicy();
@@ -306,6 +310,7 @@
myInstanceFiltersField = new FieldPanel(new MyTextField(), "", null,
new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
reloadInstanceFilters();
EditInstanceFiltersDialog _dialog = new EditInstanceFiltersDialog(myProject);
@@ -322,6 +327,7 @@
myClassFiltersField = new FieldPanel(new MyTextField(), "", null,
new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
reloadClassFilters();
@@ -365,6 +371,7 @@
DebuggerUIUtil.enableEditorOnCheck(myLogExpressionCheckBox, myLogExpressionCombo);
ActionListener updateListener = new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
updateCheckboxes();
}
@@ -458,6 +465,7 @@
ClassFilter classFilter;
if(myBreakpointPsiClass != null) {
classFilter = new ClassFilter() {
+ @Override
public boolean isAccepted(PsiClass aClass) {
return myBreakpointPsiClass == aClass || aClass.isInheritor(myBreakpointPsiClass, true);
}
@@ -641,7 +649,7 @@
}
}
- private TextWithImportsImpl emptyText() {
+ private static TextWithImportsImpl emptyText() {
return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, "");
}
@@ -653,14 +661,14 @@
saveMasterBreakpoint();
try {
String text = myPassCountField.getText().trim();
- int count = !"".equals(text)? Integer.parseInt(text) : 0;
- breakpoint.COUNT_FILTER = count;
+ breakpoint.COUNT_FILTER = !text.isEmpty() ? Integer.parseInt(text) : 0;
if (breakpoint.COUNT_FILTER < 0) {
breakpoint.COUNT_FILTER = 0;
}
}
- catch (Exception e) {
+ catch (Exception ignored) {
}
+
breakpoint.COUNT_FILTER_ENABLED = breakpoint.COUNT_FILTER > 0 && myPassCountCheckbox.isSelected();
breakpoint.setCondition(myConditionCombo.getText());
breakpoint.CONDITION_ENABLED = myConditionCheckbox.isSelected();
@@ -867,8 +875,10 @@
myDialogTitle = dialogTitle;
}
+ @Override
public void actionPerformed(final ActionEvent e) {
new DialogWrapper(myTargetEditor, true){
+ @Override
public void show() {
setTitle(myDialogTitle);
setModal(true);
@@ -876,10 +886,12 @@
super.show();
}
+ @Override
public JComponent getPreferredFocusedComponent() {
return myEditor;
}
+ @Override
@Nullable
protected JComponent createCenterPanel() {
final JPanel panel = new JPanel(new BorderLayout());
@@ -890,6 +902,7 @@
return panel;
}
+ @Override
protected void doOKAction() {
myTargetEditor.setText(myEditor.getText());
super.doOKAction();
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java
index f1742f0..465a968 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java
@@ -19,12 +19,10 @@
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.HelpID;
import com.intellij.debugger.engine.JVMNameUtil;
-import com.intellij.debugger.ui.breakpoints.actions.*;
import com.intellij.icons.AllIcons;
import com.intellij.ide.util.TreeClassChooser;
import com.intellij.ide.util.TreeClassChooserFactory;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Key;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
@@ -72,51 +70,6 @@
return new ExceptionBreakpointPropertiesPanel(project, compact);
}
- @Override
- protected BreakpointPanelAction[] createBreakpointPanelActions(final Project project, DialogWrapper parentDialog) {
- return new BreakpointPanelAction[]{
- new SwitchViewAction(),
- new AddAction(this, project),
- new RemoveAction(project) {
- public void update() {
- super.update();
- if (getButton().isEnabled()) {
- Breakpoint[] selectedBreakpoints = getPanel().getSelectedBreakpoints();
- for (Breakpoint bp : selectedBreakpoints) {
- if (bp instanceof AnyExceptionBreakpoint) {
- getButton().setEnabled(false);
- }
- }
- }
- }
- }, new ToggleGroupByClassesAction(), new ToggleFlattenPackagesAction(),};
- }
-
- public BreakpointPanel createBreakpointPanel(final Project project, final DialogWrapper parentDialog) {
- BreakpointPanel panel =
- new BreakpointPanel(project, createBreakpointPropertiesPanel(project, false), createBreakpointPanelActions(project, parentDialog),
- getBreakpointCategory(), getDisplayName(), getHelpID()) {
- public void resetBreakpoints() {
- super.resetBreakpoints();
- Breakpoint[] breakpoints = getBreakpointManager().getBreakpoints(getBreakpointCategory());
- final AnyExceptionBreakpoint anyExceptionBreakpoint =
- DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().getAnyExceptionBreakpoint();
- boolean found = false;
- for (Breakpoint breakpoint : breakpoints) {
- if (breakpoint.equals(anyExceptionBreakpoint)) {
- found = true;
- break;
- }
- }
- if (!found) {
- insertBreakpointAt(anyExceptionBreakpoint, 0);
- }
- }
- };
- configureBreakpointPanel(panel);
- return panel;
- }
-
public Key<ExceptionBreakpoint> getBreakpointCategory() {
return ExceptionBreakpoint.CATEGORY;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointFactory.java
index 496e013..18d30f7 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointFactory.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointFactory.java
@@ -19,11 +19,9 @@
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.HelpID;
-import com.intellij.debugger.ui.breakpoints.actions.*;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
@@ -32,7 +30,6 @@
import org.jdom.Element;
import javax.swing.*;
-import java.awt.event.ActionEvent;
/**
* @author Eugene Zhuravlev
@@ -71,24 +68,6 @@
return new FieldBreakpointPropertiesPanel(project, compact);
}
- @Override
- protected BreakpointPanelAction[] createBreakpointPanelActions(final Project project, final DialogWrapper parentDialog) {
- return new BreakpointPanelAction[] {
- new SwitchViewAction(),
- new AddAction(this, project),
- new GotoSourceAction(project) {
- public void actionPerformed(ActionEvent e) {
- super.actionPerformed(e);
- parentDialog.close(DialogWrapper.OK_EXIT_CODE);
- }
- },
- new ViewSourceAction(project),
- new RemoveAction(project),
- new ToggleGroupByClassesAction(),
- new ToggleFlattenPackagesAction(),
- };
- }
-
public Key<FieldBreakpoint> getBreakpointCategory() {
return FieldBreakpoint.CATEGORY;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java
index 052cfd7..65cbf2d 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java
@@ -18,6 +18,7 @@
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.SourcePosition;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.SimpleColoredComponent;
@@ -31,6 +32,7 @@
class JavaBreakpointItem extends BreakpointItem {
private final Breakpoint myBreakpoint;
private BreakpointFactory myBreakpointFactory;
+ private BreakpointPropertiesPanel myBreakpointPropertiesPanel;
public JavaBreakpointItem(@Nullable BreakpointFactory breakpointFactory, Breakpoint breakpoint) {
myBreakpointFactory = breakpointFactory;
@@ -68,17 +70,19 @@
@Override
protected void doUpdateDetailView(DetailView panel, boolean editorOnly) {
- BreakpointPropertiesPanel breakpointPropertiesPanel = null;
+ saveState();
+ myBreakpointPropertiesPanel = null;
+
if (!editorOnly) {
- breakpointPropertiesPanel = myBreakpointFactory != null ? myBreakpointFactory
+ myBreakpointPropertiesPanel = myBreakpointFactory != null ? myBreakpointFactory
.createBreakpointPropertiesPanel(myBreakpoint.getProject(), false) : null;
- if (breakpointPropertiesPanel != null) {
- breakpointPropertiesPanel.initFrom(myBreakpoint, true);
+ if (myBreakpointPropertiesPanel != null) {
+ myBreakpointPropertiesPanel.initFrom(myBreakpoint, true);
- breakpointPropertiesPanel.setSaveOnRemove(true);
+ myBreakpointPropertiesPanel.setSaveOnRemove(true);
- final JPanel mainPanel = breakpointPropertiesPanel.getPanel();
+ final JPanel mainPanel = myBreakpointPropertiesPanel.getPanel();
panel.setPropertiesPanel(mainPanel);
}
else {
@@ -93,8 +97,8 @@
} else {
panel.clearEditor();
}
- if (breakpointPropertiesPanel != null) {
- breakpointPropertiesPanel.setDetailView(panel);
+ if (myBreakpointPropertiesPanel != null) {
+ myBreakpointPropertiesPanel.setDetailView(panel);
}
}
@@ -127,6 +131,11 @@
}
@Override
+ public void saveState() {
+ myBreakpointPropertiesPanel.saveTo(myBreakpoint, EmptyRunnable.INSTANCE);
+ }
+
+ @Override
public Object getBreakpoint() {
return myBreakpoint;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
index ae21b11..beacd19 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
@@ -24,11 +24,11 @@
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.actions.ThreadDumpAction;
+import com.intellij.debugger.engine.ContextUtil;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.impl.DebuggerUtilsEx;
-import com.intellij.debugger.impl.PositionUtil;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.application.ApplicationManager;
@@ -82,6 +82,7 @@
super(project, highlighter);
}
+ @Override
protected Icon getDisabledIcon(boolean isMuted) {
final Breakpoint master = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().findMasterBreakpoint(this);
if (isMuted) {
@@ -92,6 +93,7 @@
}
}
+ @Override
protected Icon getSetIcon(boolean isMuted) {
if (REMOVE_AFTER_HIT) {
return isMuted ? AllIcons.Debugger.Db_muted_temporary_breakpoint : AllIcons.Debugger.Db_temporary_breakpoint;
@@ -99,10 +101,12 @@
return isMuted? AllIcons.Debugger.Db_muted_breakpoint : AllIcons.Debugger.Db_set_breakpoint;
}
+ @Override
protected Icon getInvalidIcon(boolean isMuted) {
return isMuted? AllIcons.Debugger.Db_muted_invalid_breakpoint : AllIcons.Debugger.Db_invalid_breakpoint;
}
+ @Override
protected Icon getVerifiedIcon(boolean isMuted) {
if (REMOVE_AFTER_HIT) {
return isMuted ? AllIcons.Debugger.Db_muted_temporary_breakpoint : AllIcons.Debugger.Db_temporary_breakpoint;
@@ -110,25 +114,30 @@
return isMuted? AllIcons.Debugger.Db_muted_verified_breakpoint : AllIcons.Debugger.Db_verified_breakpoint;
}
+ @Override
protected Icon getVerifiedWarningsIcon(boolean isMuted) {
return isMuted? AllIcons.Debugger.Db_muted_verified_warning_breakpoint : AllIcons.Debugger.Db_verified_warning_breakpoint;
}
+ @Override
public Key<LineBreakpoint> getCategory() {
return CATEGORY;
}
+ @Override
protected void reload(PsiFile file) {
super.reload(file);
myMethodName = findMethodName(file, getHighlighter().getStartOffset());
}
+ @Override
protected void createOrWaitPrepare(DebugProcessImpl debugProcess, String classToBeLoaded) {
if (isInScopeOf(debugProcess, classToBeLoaded)) {
super.createOrWaitPrepare(debugProcess, classToBeLoaded);
}
}
+ @Override
protected void createRequestForPreparedClass(final DebugProcessImpl debugProcess, final ReferenceType classType) {
if (!isInScopeOf(debugProcess, classType.name())) {
if (LOG.isDebugEnabled()) {
@@ -137,13 +146,13 @@
return;
}
try {
- List<Location> locs = debugProcess.getPositionManager().locationsOfLine(classType, getSourcePosition());
- if (!locs.isEmpty()) {
- for (Location loc : locs) {
+ List<Location> locations = debugProcess.getPositionManager().locationsOfLine(classType, getSourcePosition());
+ if (!locations.isEmpty()) {
+ for (Location loc : locations) {
if (LOG.isDebugEnabled()) {
LOG.debug("Found location [codeIndex=" + loc.codeIndex() +"] for reference type " + classType.name() + " at line " + getLineIndex() + "; isObsolete: " + (debugProcess.getVirtualMachineProxy().versionHigher("1.4") && loc.method().isObsolete()));
}
- BreakpointRequest request = debugProcess.getRequestsManager().createBreakpointRequest(LineBreakpoint.this, loc);
+ BreakpointRequest request = debugProcess.getRequestsManager().createBreakpointRequest(this, loc);
debugProcess.getRequestsManager().enableRequest(request);
if (LOG.isDebugEnabled()) {
LOG.debug("Created breakpoint request for reference type " + classType.name() + " at line " + getLineIndex() + "; codeIndex=" + loc.codeIndex());
@@ -152,7 +161,7 @@
}
else {
// there's no executable code in this class
- debugProcess.getRequestsManager().setInvalid(LineBreakpoint.this, DebuggerBundle.message(
+ debugProcess.getRequestsManager().setInvalid(this, DebuggerBundle.message(
"error.invalid.breakpoint.no.executable.code", (getLineIndex() + 1), classType.name())
);
if (LOG.isDebugEnabled()) {
@@ -176,7 +185,7 @@
if (LOG.isDebugEnabled()) {
LOG.debug("InvalidLineNumberException: " + ex.getMessage());
}
- debugProcess.getRequestsManager().setInvalid(LineBreakpoint.this, DebuggerBundle.message("error.invalid.breakpoint.bad.line.number"));
+ debugProcess.getRequestsManager().setInvalid(this, DebuggerBundle.message("error.invalid.breakpoint.bad.line.number"));
}
catch (InternalException ex) {
LOG.info(ex);
@@ -251,6 +260,7 @@
final int dollarIndex = className.indexOf("$");
final String topLevelClassName = dollarIndex >= 0? className.substring(0, dollarIndex) : className;
return ApplicationManager.getApplication().runReadAction(new Computable<Collection<VirtualFile>>() {
+ @Override
@Nullable
public Collection<VirtualFile> compute() {
final PsiClass[] classes = JavaPsiFacade.getInstance(myProject).findClasses(topLevelClassName, scope);
@@ -292,6 +302,7 @@
});
}
+ @Override
public boolean evaluateCondition(EvaluationContextImpl context, LocatableEvent event) throws EvaluateException {
if(CLASS_FILTERS_ENABLED){
String className = null;
@@ -335,6 +346,7 @@
return getDisplayInfoInternal(false, 30);
}
+ @Override
public String getDisplayName() {
return getDisplayInfoInternal(true, -1);
}
@@ -399,6 +411,7 @@
}
if (file instanceof PsiClassOwner) {
return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ @Override
public String compute() {
final PsiMethod method = DebuggerUtilsEx.findPsiMethod(file, offset);
return method != null? method.getName() + "()" : null;
@@ -408,9 +421,10 @@
return null;
}
+ @Override
public String getEventMessage(LocatableEvent event) {
final Location location = event.location();
- String sourceName = "Unknown Source";
+ String sourceName;
try {
sourceName = location.sourceName();
}
@@ -452,8 +466,9 @@
}
}
+ @Override
public PsiElement getEvaluationElement() {
- return PositionUtil.getContextElement(getSourcePosition());
+ return ContextUtil.getContextElement(getSourcePosition());
}
protected static LineBreakpoint create(Project project, Document document, int lineIndex) {
@@ -471,6 +486,7 @@
return (LineBreakpoint)breakpoint.init();
}
+ @Override
public boolean canMoveTo(SourcePosition position) {
if (!super.canMoveTo(position)) {
return false;
@@ -493,6 +509,7 @@
final boolean[] canAdd = new boolean[]{false};
XDebuggerUtil.getInstance().iterateLine(project, document, lineIndex, new Processor<PsiElement>() {
+ @Override
public boolean process(PsiElement element) {
if ((element instanceof PsiWhiteSpace) || (PsiTreeUtil.getParentOfType(element, PsiComment.class, false) != null)) {
return true;
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointFactory.java
index dede7de..0042074 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointFactory.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointFactory.java
@@ -17,29 +17,29 @@
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.HelpID;
-import com.intellij.debugger.ui.breakpoints.actions.*;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Key;
import org.jdom.Element;
import javax.swing.*;
-import java.awt.event.ActionEvent;
/**
* @author Eugene Zhuravlev
* Date: Apr 26, 2005
*/
public class LineBreakpointFactory extends BreakpointFactory {
+ @Override
public Breakpoint createBreakpoint(Project project, final Element element) {
return new LineBreakpoint(project);
}
+ @Override
public Icon getIcon() {
return AllIcons.Debugger.Db_set_breakpoint;
}
+ @Override
public Icon getDisabledIcon() {
return AllIcons.Debugger.Db_disabled_breakpoint;
}
@@ -60,22 +60,6 @@
}
@Override
- protected BreakpointPanelAction[] createBreakpointPanelActions(Project project, final DialogWrapper parentDialog) {
- return new BreakpointPanelAction[]{new SwitchViewAction(),
- new GotoSourceAction(project) {
- public void actionPerformed(ActionEvent e) {
- super.actionPerformed(e);
- parentDialog.close(DialogWrapper.OK_EXIT_CODE);
- }
- },
- new ViewSourceAction(project),
- new RemoveAction(project),
- new ToggleGroupByMethodsAction(),
- new ToggleGroupByClassesAction(),
- new ToggleFlattenPackagesAction(),
- };
- }
-
public Key<LineBreakpoint> getBreakpointCategory() {
return LineBreakpoint.CATEGORY;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointFactory.java
index c2ad3dc..2574e22 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointFactory.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointFactory.java
@@ -18,29 +18,29 @@
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.HelpID;
-import com.intellij.debugger.ui.breakpoints.actions.*;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Key;
import org.jdom.Element;
import javax.swing.*;
-import java.awt.event.ActionEvent;
/**
* @author Eugene Zhuravlev
* Date: Apr 26, 2005
*/
public class MethodBreakpointFactory extends BreakpointFactory{
+ @Override
public Breakpoint createBreakpoint(Project project, final Element element) {
return element.getAttributeValue(WildcardMethodBreakpoint.JDOM_LABEL) != null? new WildcardMethodBreakpoint(project) : new MethodBreakpoint(project);
}
+ @Override
public Icon getIcon() {
return AllIcons.Debugger.Db_method_breakpoint;
}
+ @Override
public Icon getDisabledIcon() {
return AllIcons.Debugger.Db_disabled_method_breakpoint;
}
@@ -61,29 +61,12 @@
}
@Override
- protected BreakpointPanelAction[] createBreakpointPanelActions(Project project, final DialogWrapper parentDialog) {
- return new BreakpointPanelAction[]{
- new SwitchViewAction(),
- new AddAction(this, project),
- new GotoSourceAction(project) {
- public void actionPerformed(ActionEvent e) {
- super.actionPerformed(e);
- parentDialog.close(DialogWrapper.OK_EXIT_CODE);
- }
- },
- new ViewSourceAction(project),
- new RemoveAction(project),
- new ToggleGroupByClassesAction(),
- new ToggleFlattenPackagesAction(),
- };
- }
-
- @Override
protected void configureBreakpointPanel(BreakpointPanel panel) {
super.configureBreakpointPanel(panel);
panel.getTree().setGroupByMethods(false);
}
+ @Override
public Key<MethodBreakpoint> getBreakpointCategory() {
return MethodBreakpoint.CATEGORY;
}
@@ -93,6 +76,7 @@
return true;
}
+ @Override
public WildcardMethodBreakpoint addBreakpoint(Project project) {
AddWildcardBreakpointDialog dialog = new AddWildcardBreakpointDialog(project);
dialog.show();
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java b/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java
new file mode 100644
index 0000000..21cdb36
--- /dev/null
+++ b/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java
@@ -0,0 +1,24 @@
+package org.jetbrains.java.debugger;
+
+import com.intellij.ide.highlighter.JavaFileType;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.JavaCodeFragmentFactory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.xdebugger.evaluation.XDebuggerEditorsProviderBase;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase {
+ @NotNull
+ @Override
+ public FileType getFileType() {
+ return JavaFileType.INSTANCE;
+ }
+
+ @Override
+ protected PsiFile createExpressionCodeFragment(@NotNull Project project, @NotNull String text, @Nullable PsiElement context, boolean isPhysical) {
+ return JavaCodeFragmentFactory.getInstance(project).createExpressionCodeFragment(text, context, null, isPhysical);
+ }
+}
\ No newline at end of file
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointType.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointType.java
new file mode 100644
index 0000000..d3e6545
--- /dev/null
+++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointType.java
@@ -0,0 +1,67 @@
+package org.jetbrains.java.debugger.breakpoints;
+
+import com.intellij.debugger.DebuggerBundle;
+import com.intellij.debugger.engine.DebuggerUtils;
+import com.intellij.facet.FacetManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtilCore;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.util.SystemProperties;
+import com.intellij.xdebugger.XDebuggerUtil;
+import com.intellij.xdebugger.breakpoints.XBreakpointProperties;
+import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
+import com.intellij.xdebugger.breakpoints.XLineBreakpointTypeBase;
+import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.java.debugger.JavaDebuggerEditorsProvider;
+
+import java.util.List;
+
+public class JavaBreakpointType extends XLineBreakpointTypeBase {
+ public JavaBreakpointType() {
+ super("java", DebuggerBundle.message("java.breakpoint.title"), new JavaDebuggerEditorsProvider());
+ }
+
+ @Override
+ public boolean canPutAt(@NotNull final VirtualFile file, final int line, @NotNull Project project) {
+ if (SystemProperties.getBooleanProperty("java.debugger.xBreakpoint", false)) {
+ boolean result = doCanPutAt(PsiManager.getInstance(project).findFile(file));
+
+ // todo now applicable only if modules has facets, remove this check when java xbreakpoint will work
+ if (result && SystemProperties.getBooleanProperty("java.debugger.xBreakpoint.onlyIfHasFacets", false)) {
+ Module module = ModuleUtilCore.findModuleForFile(file, project);
+ return module != null && FacetManager.getInstance(module).getAllFacets().length > 0;
+ }
+
+ return result;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isSuspendThreadSupported() {
+ return true;
+ }
+
+ @Override
+ public List<XBreakpointGroupingRule<XLineBreakpoint<XBreakpointProperties>, ?>> getGroupingRules() {
+ return XDebuggerUtil.getInstance().getGroupingByFileRuleAsList();
+ }
+
+ @Contract("null -> false")
+ public static boolean doCanPutAt(@Nullable PsiFile psiFile) {
+ if (psiFile == null) {
+ return false;
+ }
+
+ FileType fileType = psiFile.getFileType();
+ return StdFileTypes.CLASS.equals(fileType) || DebuggerUtils.supportsJVMDebugging(fileType) || DebuggerUtils.supportsJVMDebugging(psiFile);
+ }
+}
\ No newline at end of file
diff --git a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java
index ae4ea88..74524ca 100644
--- a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java
+++ b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java
@@ -99,6 +99,7 @@
}
public static boolean isTestClass(@NotNull PsiClass psiClass, boolean checkAbstract, boolean checkForTestCaseInheritance) {
+ if (psiClass.getQualifiedName() == null) return false;
if (!PsiClassUtil.isRunnableClass(psiClass, true, checkAbstract)) return false;
if (checkForTestCaseInheritance && isTestCaseInheritor(psiClass)) return true;
final PsiModifierList modifierList = psiClass.getModifierList();
diff --git a/java/execution/impl/src/com/intellij/execution/stacktrace/StackTraceLine.java b/java/execution/impl/src/com/intellij/execution/stacktrace/StackTraceLine.java
index de8cd68..1137273 100644
--- a/java/execution/impl/src/com/intellij/execution/stacktrace/StackTraceLine.java
+++ b/java/execution/impl/src/com/intellij/execution/stacktrace/StackTraceLine.java
@@ -114,10 +114,9 @@
}
}
- private PsiClass findClass(final Project project, final String className, final int lineNumber) {
+ private static PsiClass findClass(final Project project, final String className, final int lineNumber) {
if (project == null) return null;
final PsiManager psiManager = PsiManager.getInstance(project);
- if (psiManager == null) return null;
PsiClass psiClass = JavaPsiFacade.getInstance(psiManager.getProject()).findClass(className, GlobalSearchScope.allScope(project));
if (psiClass == null || (psiClass.getNavigationElement() instanceof PsiCompiledElement)) return null;
psiClass = (PsiClass)psiClass.getNavigationElement();
@@ -132,8 +131,7 @@
if (methods.length == 0) return null;
final PsiFile psiFile = methods[0].getContainingFile();
final int offset = offsetOfLine(psiFile, lineNumber);
- for (int i = 0; i < methods.length; i++) {
- final PsiMethod method = methods[i];
+ for (final PsiMethod method : methods) {
if (method.getTextRange().contains(offset)) return method;
}
//if (!methods.hasNext() || location == null) return null;
@@ -152,7 +150,6 @@
private static int offsetOfLine(final PsiFile psiFile, final int lineNumber) {
final LineTokenizer lineTokenizer = new LineTokenizer(psiFile.getViewProvider().getContents());
for (int i = 0; i < lineNumber; i++) lineTokenizer.advance();
- final int offset = lineTokenizer.getOffset();
- return offset;
+ return lineTokenizer.getOffset();
}
}
diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FrameworkLibraryProvider.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FrameworkLibraryProvider.java
new file mode 100644
index 0000000..fe01427
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FrameworkLibraryProvider.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.facet.impl.ui.libraries;
+
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryKind;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+/**
+ * @author nik
+ */
+public abstract class FrameworkLibraryProvider {
+ @NotNull
+ public abstract String getPresentableName();
+
+ public abstract Set<LibraryKind> getAvailableLibraryKinds();
+
+ @NotNull
+ public abstract Library createLibrary(@NotNull Set<? extends LibraryKind> suitableLibraryKinds);
+}
diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryCompositionSettings.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryCompositionSettings.java
index b9dd0cb..52d5358 100644
--- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryCompositionSettings.java
+++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryCompositionSettings.java
@@ -53,6 +53,7 @@
private LibraryDownloadSettings myDownloadSettings;
private Map<Library, ExistingLibraryEditor> myExistingLibraryEditors =
ContainerUtil.newIdentityTroveMap();
+ private FrameworkLibraryProvider myLibraryProvider;
public LibraryCompositionSettings(final @NotNull CustomLibraryDescription libraryDescription,
final @NotNull String baseDirectoryPath,
@@ -182,16 +183,16 @@
@Nullable
public Library addLibraries(final @NotNull ModifiableRootModel rootModel, final @NotNull List<Library> addedLibraries,
final @Nullable LibrariesContainer librariesContainer) {
- Library library = createLibrary(rootModel, librariesContainer);
+ Library newLibrary = createLibrary(rootModel, librariesContainer);
- if (library != null) {
- addedLibraries.add(library);
- DependencyScope scope = LibraryDependencyScopeSuggester.getDefaultScope(library);
+ if (newLibrary != null) {
+ addedLibraries.add(newLibrary);
+ DependencyScope scope = LibraryDependencyScopeSuggester.getDefaultScope(newLibrary);
if (getLibraryLevel() != LibrariesContainer.LibraryLevel.MODULE) {
- rootModel.addLibraryEntry(library).setScope(scope);
+ rootModel.addLibraryEntry(newLibrary).setScope(scope);
}
else {
- LibraryOrderEntry orderEntry = rootModel.findLibraryOrderEntry(library);
+ LibraryOrderEntry orderEntry = rootModel.findLibraryOrderEntry(newLibrary);
assert orderEntry != null;
orderEntry.setScope(scope);
}
@@ -200,13 +201,22 @@
addedLibraries.add(mySelectedLibrary);
rootModel.addLibraryEntry(mySelectedLibrary).setScope(LibraryDependencyScopeSuggester.getDefaultScope(mySelectedLibrary));
}
- return library;
+ if (myLibraryProvider != null) {
+ Library library = myLibraryProvider.createLibrary(myLibraryDescription.getSuitableLibraryKinds());
+ addedLibraries.add(library);
+ rootModel.addLibraryEntry(library).setScope(LibraryDependencyScopeSuggester.getDefaultScope(library));
+ }
+ return newLibrary;
}
public void setNewLibraryEditor(@Nullable NewLibraryEditor libraryEditor) {
myNewLibraryEditor = libraryEditor;
}
+ public void setLibraryProvider(FrameworkLibraryProvider libraryProvider) {
+ myLibraryProvider = libraryProvider;
+ }
+
@Override
public void dispose() {
}
diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryDownloadSettings.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryDownloadSettings.java
index b358416..e9e86d6 100644
--- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryDownloadSettings.java
+++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryDownloadSettings.java
@@ -42,7 +42,7 @@
* @author nik
*/
public class LibraryDownloadSettings {
- private FrameworkLibraryVersion myVersion;
+ private final FrameworkLibraryVersion myVersion;
private final DownloadableLibraryType myLibraryType;
private String myDirectoryForDownloadedLibrariesPath;
private final String myLibraryName;
@@ -116,10 +116,6 @@
return myLibraryType;
}
- public void setVersion(FrameworkLibraryVersion version) {
- myVersion = version;
- }
-
public void setDirectoryForDownloadedLibrariesPath(String directoryForDownloadedLibrariesPath) {
myDirectoryForDownloadedLibrariesPath = directoryForDownloadedLibrariesPath;
}
diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.form b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.form
index afaac4e..d4a8a2b 100644
--- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.form
+++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.form
@@ -15,7 +15,7 @@
<properties/>
<border type="none"/>
<children>
- <grid id="27dc6" binding="myPanel" 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="myPanel" layout-manager="GridLayoutManager" row-count="6" 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>
<card name="editing"/>
@@ -27,7 +27,7 @@
<children>
<component id="a5b73" class="javax.swing.JRadioButton" binding="myDownloadRadioButton">
<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="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false">
<preferred-size width="207" height="22"/>
</grid>
</constraints>
@@ -38,7 +38,7 @@
</component>
<component id="f63e3" class="javax.swing.JRadioButton" binding="myDoNotCreateRadioButton">
<constraints>
- <grid row="2" 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="3" column="0" 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="Set up library &later"/>
@@ -46,7 +46,7 @@
</component>
<vspacer id="79970">
<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="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<grid id="71da4" layout-manager="GridLayoutManager" row-count="1" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -98,7 +98,7 @@
</grid>
<grid id="7ea1" binding="myConfigurationPanel" layout-manager="CardLayout" hgap="0" vgap="0">
<constraints>
- <grid row="3" 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="4" 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/>
<border type="none"/>
@@ -165,6 +165,14 @@
</grid>
</children>
</grid>
+ <component id="9e8d3" class="javax.swing.JRadioButton" binding="myUseFromProviderRadioButton">
+ <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"/>
+ </constraints>
+ <properties>
+ <text value="Use from provider"/>
+ </properties>
+ </component>
</children>
</grid>
<grid id="b8ccc" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -199,6 +207,7 @@
<member id="4dbad"/>
<member id="a5b73"/>
<member id="f63e3"/>
+ <member id="9e8d3"/>
</group>
</buttonGroups>
</form>
diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java
index e966873..f11e89d 100644
--- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java
+++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java
@@ -39,6 +39,7 @@
import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor;
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -49,6 +50,7 @@
import com.intellij.ui.components.JBLabel;
import com.intellij.util.PathUtil;
import com.intellij.util.PlatformIcons;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.download.DownloadableFileSetVersions;
import com.intellij.util.ui.RadioButtonEnumModel;
import com.intellij.xml.util.XmlStringUtil;
@@ -84,17 +86,21 @@
private JLabel myUseLibraryLabel;
private JLabel myHiddenLabel;
private JPanel myRootPanel;
+ private JRadioButton myUseFromProviderRadioButton;
private ButtonGroup myButtonGroup;
private LibraryCompositionSettings mySettings;
+ private final CustomLibraryDescription myLibraryDescription;
private final LibrariesContainer myLibrariesContainer;
private SortedComboBoxModel<LibraryEditor> myLibraryComboBoxModel;
+ private FrameworkLibraryProvider myLibraryProvider;
private boolean myDisposed;
private enum Choice {
USE_LIBRARY,
DOWNLOAD,
- SETUP_LIBRARY_LATER
+ SETUP_LIBRARY_LATER,
+ USE_FROM_PROVIDER
}
private RadioButtonEnumModel<Choice> myButtonEnumModel;
@@ -104,6 +110,7 @@
@NotNull final FrameworkLibraryVersionFilter versionFilter,
@NotNull final LibrariesContainer librariesContainer,
final boolean showDoNotCreateOption) {
+ myLibraryDescription = libraryDescription;
myLibrariesContainer = librariesContainer;
final DownloadableLibraryDescription description = getDownloadableDescription(libraryDescription);
if (description != null) {
@@ -211,10 +218,22 @@
});
boolean canDownload = mySettings.getDownloadSettings() != null;
+ boolean canUseFromProvider = myLibraryProvider != null;
myDownloadRadioButton.setVisible(canDownload);
- myButtonEnumModel.setSelected(libraries.isEmpty() && canDownload ? Choice.DOWNLOAD : Choice.USE_LIBRARY);
+ myUseFromProviderRadioButton.setVisible(canUseFromProvider);
+ Choice selectedOption;
+ if (canUseFromProvider) {
+ selectedOption = Choice.USE_FROM_PROVIDER;
+ }
+ else if (libraries.isEmpty() && canDownload) {
+ selectedOption = Choice.DOWNLOAD;
+ }
+ else {
+ selectedOption = Choice.USE_LIBRARY;
+ }
+ myButtonEnumModel.setSelected(selectedOption);
- if (!canDownload && !showDoNotCreateOption) {
+ if (!canDownload && !canUseFromProvider && !showDoNotCreateOption) {
myUseLibraryRadioButton.setVisible(false);
myUseLibraryLabel.setVisible(true);
}
@@ -272,12 +291,31 @@
}
break;
+ case USE_FROM_PROVIDER:
case SETUP_LIBRARY_LATER:
break;
}
updateState();
}
+ public void setLibraryProvider(@Nullable FrameworkLibraryProvider provider) {
+ if (provider != null && !ContainerUtil.intersects(provider.getAvailableLibraryKinds(), myLibraryDescription.getSuitableLibraryKinds())) {
+ provider = null;
+ }
+
+ if (!Comparing.equal(myLibraryProvider, provider)) {
+ myLibraryProvider = provider;
+
+ if (mySettings != null) {
+ if (provider != null && !myUseFromProviderRadioButton.isVisible()) {
+ myUseFromProviderRadioButton.setSelected(true);
+ }
+ myUseFromProviderRadioButton.setVisible(provider != null);
+ updateState();
+ }
+ }
+ }
+
public void changeBaseDirectoryPath(@NotNull String directoryForLibrariesPath) {
if (mySettings != null) {
mySettings.changeBaseDirectoryPath(directoryForLibrariesPath);
@@ -293,7 +331,7 @@
}
private void doCreate() {
- final NewLibraryConfiguration libraryConfiguration = mySettings.getLibraryDescription().createNewLibrary(myPanel, getBaseDirectory());
+ final NewLibraryConfiguration libraryConfiguration = myLibraryDescription.createNewLibrary(myPanel, getBaseDirectory());
if (libraryConfiguration != null) {
final NewLibraryEditor libraryEditor = new NewLibraryEditor(libraryConfiguration.getLibraryType(), libraryConfiguration.getProperties());
libraryEditor.setName(myLibrariesContainer.suggestUniqueLibraryName(libraryConfiguration.getDefaultLibraryName()));
@@ -308,12 +346,11 @@
}
private List<Library> calculateSuitableLibraries() {
- final CustomLibraryDescription description = mySettings.getLibraryDescription();
List<Library> suitableLibraries = new ArrayList<Library>();
for (Library library : myLibrariesContainer.getAllLibraries()) {
- if (description instanceof OldCustomLibraryDescription &&
- ((OldCustomLibraryDescription)description).isSuitableLibrary(library, myLibrariesContainer)
- || LibraryPresentationManager.getInstance().isLibraryOfKind(library, myLibrariesContainer, description.getSuitableLibraryKinds())) {
+ if (myLibraryDescription instanceof OldCustomLibraryDescription &&
+ ((OldCustomLibraryDescription)myLibraryDescription).isSuitableLibrary(library, myLibrariesContainer)
+ || LibraryPresentationManager.getInstance().isLibraryOfKind(library, myLibrariesContainer, myLibraryDescription.getSuitableLibraryKinds())) {
suitableLibraries.add(library);
}
}
@@ -335,9 +372,17 @@
myMessageLabel.setIcon(null);
myConfigureButton.setVisible(true);
final LibraryDownloadSettings settings = mySettings.getDownloadSettings();
- myDownloadRadioButton.setEnabled(settings != null);
myDownloadRadioButton.setVisible(settings != null);
- if (!myDownloadRadioButton.isEnabled() && myDownloadRadioButton.isSelected() && myUseLibraryRadioButton.isVisible()) {
+ myUseFromProviderRadioButton.setVisible(myLibraryProvider != null);
+ if (!myUseFromProviderRadioButton.isVisible() && myUseFromProviderRadioButton.isSelected()) {
+ if (myDownloadRadioButton.isVisible()) {
+ myDownloadRadioButton.setSelected(true);
+ }
+ else {
+ myUseLibraryRadioButton.setSelected(true);
+ }
+ }
+ if (!myDownloadRadioButton.isVisible() && myDownloadRadioButton.isSelected() && myUseLibraryRadioButton.isVisible()) {
myUseLibraryRadioButton.setSelected(true);
}
String message = "";
@@ -346,6 +391,12 @@
case DOWNLOAD:
message = getDownloadFilesMessage();
break;
+ case USE_FROM_PROVIDER:
+ if (myLibraryProvider != null) {
+ message = "Library from " + myLibraryProvider.getPresentableName() + " will be used";
+ }
+ myConfigureButton.setVisible(false);
+ break;
case USE_LIBRARY:
final Object item = myExistingLibraryComboBox.getSelectedItem();
if (item == null) {
@@ -366,6 +417,10 @@
showConfigurePanel = false;
}
+ if (myLibraryProvider != null) {
+ myUseFromProviderRadioButton.setText("Use library from " + myLibraryProvider.getPresentableName());
+ }
+
//show the longest message on the hidden card to ensure that dialog won't jump if user selects another option
if (mySettings.getDownloadSettings() != null) {
myHiddenLabel.setText(getDownloadFilesMessage());
@@ -424,6 +479,8 @@
else {
mySettings.setNewLibraryEditor(null);
}
+
+ mySettings.setLibraryProvider(option == Choice.USE_FROM_PROVIDER ? myLibraryProvider : null);
return mySettings;
}
diff --git a/java/idea-ui/src/com/intellij/framework/addSupport/FrameworkSupportInModuleProvider.java b/java/idea-ui/src/com/intellij/framework/addSupport/FrameworkSupportInModuleProvider.java
index 2dafb46..744922c 100644
--- a/java/idea-ui/src/com/intellij/framework/addSupport/FrameworkSupportInModuleProvider.java
+++ b/java/idea-ui/src/com/intellij/framework/addSupport/FrameworkSupportInModuleProvider.java
@@ -23,6 +23,9 @@
import com.intellij.openapi.roots.ui.configuration.FacetsProvider;
import org.jetbrains.annotations.NotNull;
+import java.util.Collections;
+import java.util.List;
+
/**
* @author nik
*/
@@ -60,6 +63,10 @@
return "Version:";
}
+ public List<String> getOptionalDependenciesFrameworkIds() {
+ return Collections.emptyList();
+ }
+
@Override
public String toString() {
return getPresentableName();
diff --git a/java/idea-ui/src/com/intellij/framework/library/DownloadableLibraryTypeBase.java b/java/idea-ui/src/com/intellij/framework/library/DownloadableLibraryTypeBase.java
new file mode 100644
index 0000000..5764efa
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/framework/library/DownloadableLibraryTypeBase.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.framework.library;
+
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.net.URL;
+
+/**
+ * @deprecated use {@link DownloadableLibraryType} instead
+ */
+public abstract class DownloadableLibraryTypeBase extends DownloadableLibraryType {
+ protected DownloadableLibraryTypeBase(@NotNull String libraryCategoryName,
+ @NotNull String libraryTypeId,
+ @NotNull String groupId,
+ @NotNull Icon icon,
+ @NotNull URL... localUrls) {
+ super(libraryCategoryName, libraryTypeId, groupId, icon, localUrls);
+ }
+}
diff --git a/java/idea-ui/src/com/intellij/framework/library/LibraryBasedFrameworkType.java b/java/idea-ui/src/com/intellij/framework/library/LibraryBasedFrameworkType.java
index 56d5c13..ca6c47b 100644
--- a/java/idea-ui/src/com/intellij/framework/library/LibraryBasedFrameworkType.java
+++ b/java/idea-ui/src/com/intellij/framework/library/LibraryBasedFrameworkType.java
@@ -48,8 +48,14 @@
@NotNull
@Override
public Icon getIcon() {
+ DownloadableLibraryType libraryType = getLibraryType();
+ return libraryType.getIcon();
+ }
+
+ @NotNull
+ public DownloadableLibraryType getLibraryType() {
DownloadableLibraryType libraryType = LibraryType.EP_NAME.findExtension(myLibraryTypeClass);
LOG.assertTrue(libraryType != null, myLibraryTypeClass);
- return libraryType.getIcon();
+ return libraryType;
}
}
diff --git a/java/idea-ui/src/com/intellij/framework/library/UnderlyingFrameworkSupportProviderBase.java b/java/idea-ui/src/com/intellij/framework/library/UnderlyingFrameworkSupportProviderBase.java
new file mode 100644
index 0000000..70748d6
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/framework/library/UnderlyingFrameworkSupportProviderBase.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.framework.library;
+
+import com.intellij.framework.FrameworkTypeEx;
+
+/**
+ * @author nik
+ *
+ * @deprecated use {@link #LibraryBasedFrameworkSupportProvider} instead
+ */
+public class UnderlyingFrameworkSupportProviderBase extends LibraryBasedFrameworkSupportProvider {
+ public UnderlyingFrameworkSupportProviderBase(FrameworkTypeEx frameworkType,
+ Class<? extends DownloadableLibraryType> libraryTypeClass) {
+ super(frameworkType, libraryTypeClass);
+ }
+}
diff --git a/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java b/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java
index e7ec1b0..2faa20b 100644
--- a/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java
+++ b/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java
@@ -17,6 +17,7 @@
import com.intellij.ide.impl.NewProjectUtil;
import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;
import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
import com.intellij.ide.util.projectWizard.ProjectBuilder;
import com.intellij.openapi.actionSystem.AnAction;
@@ -68,9 +69,9 @@
return createFromWizard(project, wizard);
}
- public static List<Module> createFromWizard(Project project, AddModuleWizard wizard) {
+ public static List<Module> createFromWizard(Project project, AbstractProjectWizard wizard) {
if (project == null && wizard.getStepCount() > 0) {
- Project newProject = NewProjectUtil.createFromWizard(wizard, project);
+ Project newProject = NewProjectUtil.createFromWizard(wizard, null);
return newProject == null ? Collections.<Module>emptyList() : Arrays.asList(ModuleManager.getInstance(newProject).getModules());
}
diff --git a/java/idea-ui/src/com/intellij/ide/actions/NewProjectAction.java b/java/idea-ui/src/com/intellij/ide/actions/NewProjectAction.java
index 7deeece..048bda9 100644
--- a/java/idea-ui/src/com/intellij/ide/actions/NewProjectAction.java
+++ b/java/idea-ui/src/com/intellij/ide/actions/NewProjectAction.java
@@ -16,13 +16,19 @@
package com.intellij.ide.actions;
import com.intellij.ide.impl.NewProjectUtil;
+import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
+import com.intellij.ide.util.newProjectWizard.AddModuleWizardPro;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.openapi.util.registry.Registry;
public class NewProjectAction extends AnAction implements DumbAware {
public void actionPerformed(AnActionEvent e) {
- NewProjectUtil.createNewProject(PlatformDataKeys.PROJECT.getData(e.getDataContext()), null);
+ NewProjectUtil.createNewProject(CommonDataKeys.PROJECT.getData(e.getDataContext()), Registry.is("new.project.wizard")
+ ? new AddModuleWizardPro(null, ModulesProvider.EMPTY_MODULES_PROVIDER, null)
+ : new AddModuleWizard(null, ModulesProvider.EMPTY_MODULES_PROVIDER, null));
}
}
diff --git a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java
index f5ef7af..4cf1663 100644
--- a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java
+++ b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java
@@ -20,8 +20,7 @@
package com.intellij.ide.impl;
import com.intellij.ide.GeneralSettings;
-import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
-import com.intellij.ide.util.newProjectWizard.AddModuleWizardPro;
+import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;
import com.intellij.ide.util.projectWizard.ProjectBuilder;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
@@ -44,7 +43,6 @@
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.wm.*;
import com.intellij.openapi.wm.ex.IdeFrameEx;
@@ -62,25 +60,22 @@
private NewProjectUtil() {
}
- public static void createNewProject(Project projectToClose, @Nullable final String defaultPath) {
+ public static void createNewProject(Project projectToClose, AbstractProjectWizard wizard) {
final boolean proceed = ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
public void run() {
ProjectManager.getInstance().getDefaultProject(); //warm up components
}
}, ProjectBundle.message("project.new.wizard.progress.title"), true, null);
if (!proceed) return;
- final AddModuleWizard dialog = Registry.is("new.project.wizard")
- ? new AddModuleWizardPro(null, ModulesProvider.EMPTY_MODULES_PROVIDER, defaultPath)
- : new AddModuleWizard(null, ModulesProvider.EMPTY_MODULES_PROVIDER, defaultPath);
- dialog.show();
- if (!dialog.isOK()) {
+ wizard.show();
+ if (!wizard.isOK()) {
return;
}
- createFromWizard(dialog, projectToClose);
+ createFromWizard(wizard, projectToClose);
}
- public static Project createFromWizard(AddModuleWizard dialog, Project projectToClose) {
+ public static Project createFromWizard(AbstractProjectWizard dialog, Project projectToClose) {
try {
return doCreate(dialog, projectToClose);
}
@@ -95,7 +90,7 @@
}
}
- private static Project doCreate(final AddModuleWizard dialog, @Nullable Project projectToClose) throws IOException {
+ private static Project doCreate(final AbstractProjectWizard dialog, @Nullable Project projectToClose) throws IOException {
final ProjectManagerEx projectManager = ProjectManagerEx.getInstanceEx();
final String projectFilePath = dialog.getNewProjectFilePath();
final ProjectBuilder projectBuilder = dialog.getProjectBuilder();
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/BuilderBasedProjectType.java b/java/idea-ui/src/com/intellij/ide/projectWizard/BuilderBasedProjectType.java
new file mode 100644
index 0000000..23379f6
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/BuilderBasedProjectType.java
@@ -0,0 +1,35 @@
+package com.intellij.ide.projectWizard;
+
+import com.intellij.ide.util.projectWizard.ModuleBuilder;
+import com.intellij.openapi.module.JavaModuleType;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Dmitry Avdeev
+ * Date: 20.09.13
+ */
+public class BuilderBasedProjectType extends ProjectCategory {
+
+ private final ModuleBuilder myBuilder;
+
+ public BuilderBasedProjectType(ModuleBuilder builder) {
+ myBuilder = builder;
+ }
+
+ @NotNull
+ @Override
+ public ModuleBuilder createModuleBuilder() {
+ return myBuilder;
+ }
+
+ /**
+ * @author Dmitry Avdeev
+ * Date: 04.09.13
+ */
+ public static class Java extends BuilderBasedProjectType {
+
+ public Java() {
+ super(JavaModuleType.getModuleType().createModuleBuilder());
+ }
+ }
+}
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/CommonJavaProjectCategory.java b/java/idea-ui/src/com/intellij/ide/projectWizard/CommonJavaProjectCategory.java
deleted file mode 100644
index bac30cb..0000000
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/CommonJavaProjectCategory.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.ide.projectWizard;
-
-import com.intellij.ide.util.projectWizard.ModuleBuilder;
-import com.intellij.openapi.module.JavaModuleType;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * @author Dmitry Avdeev
- * Date: 04.09.13
- */
-public class CommonJavaProjectCategory extends ProjectCategory {
-
- @NotNull
- @Override
- public ModuleBuilder createModuleBuilder() {
- return JavaModuleType.getModuleType().createModuleBuilder();
- }
-
- @Override
- public String getId() {
- return "Java";
- }
-
- @Override
- public String getDisplayName() {
- return "Common Java";
- }
-
- @Override
- public String getDescription() {
- return "Common Java Project";
- }
-}
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java b/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java
index f76462b..5ecda30 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java
@@ -15,36 +15,43 @@
*/
package com.intellij.ide.projectWizard;
-import com.intellij.ide.util.projectWizard.WizardContext;
-import com.intellij.ide.wizard.AbstractWizard;
-import com.intellij.ide.wizard.Step;
+import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;
+import com.intellij.ide.util.newProjectWizard.StepSequence;
+import com.intellij.ide.util.projectWizard.ModuleWizardStep;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Dmitry Avdeev
* Date: 04.09.13
*/
-public class NewProjectWizard extends AbstractWizard<Step> {
+public class NewProjectWizard extends AbstractProjectWizard {
- private final WizardContext myContext;
+ private final StepSequence mySequence;
- public NewProjectWizard(String title, @Nullable Project project) {
- super(title, project);
- myContext = new WizardContext(project);
- addStep(new ProjectTypeStep(project, getDisposable()));
+ public NewProjectWizard(@Nullable Project project, @NotNull ModulesProvider modulesProvider, @Nullable String defaultPath) {
+ super("New Project", project, defaultPath);
+// addStep();
+// addStep(new ProjectSummaryStep(myWizardContext));
+ mySequence = new StepSequence();
+ mySequence.addCommonStep(new ProjectTypeStep(myWizardContext, this, modulesProvider));
+ mySequence.addCommonFinishingStep(new ProjectSettingsStep(myWizardContext), null);
+ for (ModuleWizardStep step : mySequence.getAllSteps()) {
+ addStep(step);
+ }
init();
}
@Nullable
@Override
- protected String getHelpID() {
- return null;
- }
-
- @Nullable
- @Override
protected String getDimensionServiceKey() {
return "new project wizard";
}
+
+ @Override
+ public StepSequence getSequence() {
+ return mySequence;
+ }
}
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizardAction.java b/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizardAction.java
index 676c8b1..29226b6 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizardAction.java
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizardAction.java
@@ -15,8 +15,10 @@
*/
package com.intellij.ide.projectWizard;
+import com.intellij.ide.impl.NewProjectUtil;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
/**
* @author Dmitry Avdeev
@@ -25,6 +27,7 @@
public class NewProjectWizardAction extends AnAction {
@Override
public void actionPerformed(AnActionEvent e) {
- new NewProjectWizard("New Project", getEventProject(e)).show();
+ NewProjectWizard wizard = new NewProjectWizard(null, ModulesProvider.EMPTY_MODULES_PROVIDER, null);
+ NewProjectUtil.createNewProject(getEventProject(e), wizard);
}
}
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectCategory.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectCategory.java
index 0553895..2d7f32b 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectCategory.java
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectCategory.java
@@ -24,6 +24,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
import java.util.Arrays;
import java.util.Map;
@@ -46,10 +47,18 @@
return createModuleBuilder().getPresentableName();
}
+ public Icon getIcon() {
+ return createModuleBuilder().getNodeIcon();
+ }
+
public String getDescription() {
return createModuleBuilder().getDescription();
}
+ public String getGroupName() {
+ return createModuleBuilder().getGroupName();
+ }
+
@Nullable
public String getParentId() {
return null;
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSettingsStep.form b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSettingsStep.form
new file mode 100644
index 0000000..625a1ea
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSettingsStep.form
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.ide.projectWizard.ProjectSettingsStep">
+ <grid id="27dc6" binding="myPanel" 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>
+ <xy x="20" y="20" width="608" height="215"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <grid id="e5cc3" layout-manager="GridLayoutManager" row-count="4" 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="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"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <grid id="5d4a2" binding="myExpertPlaceholder" layout-manager="BorderLayout" hgap="0" vgap="0">
+ <constraints>
+ <grid row="3" 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/>
+ <border type="none"/>
+ <children>
+ <grid id="a59bf" binding="myExpertPanel" layout-manager="GridBagLayout">
+ <constraints border-constraint="Center"/>
+ <properties/>
+ <border type="none"/>
+ <children/>
+ </grid>
+ </children>
+ </grid>
+ <grid id="fb50c" binding="myModulePanel" layout-manager="GridBagLayout">
+ <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/>
+ <border type="none"/>
+ <children>
+ <component id="40abf" 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"/>
+ <gridbag weightx="0.0" weighty="1.0"/>
+ </constraints>
+ <properties>
+ <labelFor value="edb8a"/>
+ <text resource-bundle="messages/ProjectBundle" key="project.new.wizard.module.name.title"/>
+ </properties>
+ </component>
+ <component id="edb8a" class="javax.swing.JTextField" binding="myModuleName">
+ <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>
+ <gridbag top="0" left="0" bottom="5" right="0" weightx="1.0" weighty="1.0"/>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="7afef" 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"/>
+ <gridbag weightx="0.0" weighty="1.0"/>
+ </constraints>
+ <properties>
+ <labelFor value="d2d6b"/>
+ <text resource-bundle="messages/ProjectBundle" key="project.new.wizard.module.root.title"/>
+ </properties>
+ </component>
+ <component id="d2d6b" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myModuleContentRoot">
+ <constraints>
+ <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <gridbag top="0" left="0" bottom="5" right="0" weightx="1.0" weighty="1.0"/>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="2ac4e" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <gridbag weightx="0.0" weighty="1.0"/>
+ </constraints>
+ <properties>
+ <labelFor value="9e1b8"/>
+ <text resource-bundle="messages/ProjectBundle" key="project.new.wizard.module.file.title"/>
+ </properties>
+ </component>
+ <component id="9e1b8" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myModuleFileLocation">
+ <constraints>
+ <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <gridbag top="0" left="0" bottom="5" right="0" weightx="1.0" weighty="1.0"/>
+ </constraints>
+ <properties/>
+ </component>
+ </children>
+ </grid>
+ <grid id="caf4" binding="mySettingsPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="empty">
+ <size top="0" left="0" bottom="10" right="0"/>
+ </border>
+ <children/>
+ </grid>
+ <vspacer id="44e0b">
+ <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>
+ </children>
+ </grid>
+</form>
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSettingsStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSettingsStep.java
new file mode 100644
index 0000000..3db63ca
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSettingsStep.java
@@ -0,0 +1,463 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.projectWizard;
+
+import com.intellij.ide.IdeBundle;
+import com.intellij.ide.highlighter.ModuleFileType;
+import com.intellij.ide.util.BrowseFilesListener;
+import com.intellij.ide.util.newProjectWizard.SelectTemplateSettings;
+import com.intellij.ide.util.projectWizard.*;
+import com.intellij.openapi.components.StorageScheme;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectBundle;
+import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.platform.templates.TemplateModuleBuilder;
+import com.intellij.projectImport.ProjectFormatPanel;
+import com.intellij.ui.DocumentAdapter;
+import com.intellij.ui.HideableDecorator;
+import com.intellij.ui.IdeBorderFactory;
+import com.intellij.ui.components.JBLabel;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+
+import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+import java.awt.*;
+import java.io.File;
+
+/**
+ * @author Dmitry Avdeev
+ * Date: 9/26/12
+ */
+public class ProjectSettingsStep extends ModuleWizardStep implements SettingsStep {
+
+ private JPanel mySettingsPanel;
+
+ private JPanel myExpertPlaceholder;
+ private JPanel myExpertPanel;
+ private final HideableDecorator myExpertDecorator;
+
+ private final NamePathComponent myNamePathComponent;
+ private final ProjectFormatPanel myFormatPanel;
+
+ private JTextField myModuleName;
+ private TextFieldWithBrowseButton myModuleContentRoot;
+ private TextFieldWithBrowseButton myModuleFileLocation;
+ private JPanel myModulePanel;
+
+ private JPanel myPanel;
+
+ private boolean myModuleNameChangedByUser = false;
+ private boolean myModuleNameDocListenerEnabled = true;
+
+ private boolean myContentRootChangedByUser = false;
+ private boolean myContentRootDocListenerEnabled = true;
+
+ private boolean myImlLocationChangedByUser = false;
+ private boolean myImlLocationDocListenerEnabled = true;
+
+ private final WizardContext myWizardContext;
+ @Nullable
+ private ModuleWizardStep mySettingsStep;
+
+ public ProjectSettingsStep(WizardContext context) {
+
+ myWizardContext = context;
+
+ myFormatPanel = new ProjectFormatPanel();
+ myNamePathComponent = NamePathComponent.initNamePathComponent(context);
+ if (context.isCreatingNewProject()) {
+ mySettingsPanel.add(myNamePathComponent, BorderLayout.NORTH);
+ addExpertPanel(myModulePanel);
+ }
+ else {
+ mySettingsPanel.add(myModulePanel, BorderLayout.NORTH);
+ }
+ bindModuleSettings();
+
+ myExpertDecorator = new HideableDecorator(myExpertPlaceholder, "Mor&e Settings", false);
+ myExpertPanel.setBorder(IdeBorderFactory.createEmptyBorder(0, IdeBorderFactory.TITLED_BORDER_INDENT, 5, 0));
+ myExpertDecorator.setContentComponent(myExpertPanel);
+
+ if (myWizardContext.isCreatingNewProject()) {
+ addProjectFormat(myModulePanel);
+ }
+ }
+
+ private JTextField getNameComponent() {
+ return myWizardContext.isCreatingNewProject() ? myNamePathComponent.getNameComponent() : myModuleName;
+ }
+
+ private void addProjectFormat(JPanel panel) {
+ addField("Project \u001bformat:", myFormatPanel.getStorageFormatComboBox(), panel);
+ }
+
+ @Override
+ public String getHelpId() {
+ return myWizardContext.isCreatingNewProject() ? "New_Project_Main_Settings" : "Add_Module_Main_Settings";
+ }
+
+ private void setupPanels() {
+
+ ModuleBuilder moduleBuilder = (ModuleBuilder)myWizardContext.getProjectBuilder();
+ restorePanel(myNamePathComponent, 4);
+ restorePanel(myModulePanel, myWizardContext.isCreatingNewProject() ? 8 : 6);
+ restorePanel(myExpertPanel, myWizardContext.isCreatingNewProject() ? 1 : 0);
+ mySettingsStep = moduleBuilder == null ? null : moduleBuilder.modifySettingsStep(this);
+
+ myExpertPlaceholder.setVisible(!(moduleBuilder instanceof TemplateModuleBuilder) && myExpertPanel.getComponentCount() > 0);
+ for (int i = 0; i < 6; i++) {
+ myModulePanel.getComponent(i).setVisible(!(moduleBuilder instanceof EmptyModuleBuilder));
+ }
+ mySettingsPanel.revalidate();
+ mySettingsPanel.repaint();
+ }
+
+ private static int restorePanel(JPanel component, int i) {
+ int removed = 0;
+ while (component.getComponentCount() > i) {
+ component.remove(component.getComponentCount() - 1);
+ removed++;
+ }
+ return removed;
+ }
+
+ @Override
+ public void updateStep() {
+ myExpertDecorator.setOn(SelectTemplateSettings.getInstance().EXPERT_MODE);
+ setupPanels();
+ }
+
+ @Override
+ public void onStepLeaving() {
+ SelectTemplateSettings settings = SelectTemplateSettings.getInstance();
+ settings.EXPERT_MODE = myExpertDecorator.isExpanded();
+ }
+
+ @Override
+ public boolean validate() throws ConfigurationException {
+
+ if (myWizardContext.isCreatingNewProject()) {
+ if (!myNamePathComponent.validateNameAndPath(myWizardContext, myFormatPanel.isDefault())) return false;
+ }
+
+ if (!validateModulePaths()) return false;
+ if (!myWizardContext.isCreatingNewProject()) {
+ validateExistingModuleName();
+ }
+
+ if (mySettingsStep != null) {
+ return mySettingsStep.validate();
+ }
+ return true;
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return myPanel;
+ }
+
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return getNameComponent();
+ }
+
+ @Override
+ public void updateDataModel() {
+
+ myWizardContext.setProjectName(myNamePathComponent.getNameValue());
+ myWizardContext.setProjectFileDirectory(myNamePathComponent.getPath());
+ myFormatPanel.updateData(myWizardContext);
+
+ ModuleBuilder moduleBuilder = (ModuleBuilder)myWizardContext.getProjectBuilder();
+ if (moduleBuilder != null) {
+ final String moduleName = getModuleName();
+ moduleBuilder.setName(moduleName);
+ moduleBuilder.setModuleFilePath(
+ FileUtil.toSystemIndependentName(myModuleFileLocation.getText()) + "/" + moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION);
+ moduleBuilder.setContentEntryPath(FileUtil.toSystemIndependentName(getModuleContentRoot()));
+ if (moduleBuilder instanceof TemplateModuleBuilder) {
+ myWizardContext.setProjectStorageFormat(StorageScheme.DIRECTORY_BASED);
+ }
+ }
+
+ if (mySettingsStep != null) {
+ mySettingsStep.updateDataModel();
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "Project Settings";
+ }
+
+ @Override
+ public WizardContext getContext() {
+ return myWizardContext;
+ }
+
+ @Override
+ public void addSettingsField(@NotNull String label, @NotNull JComponent field) {
+ JPanel panel = myWizardContext.isCreatingNewProject() ? myNamePathComponent : myModulePanel;
+ addField(label, field, panel);
+ }
+
+ private static void addField(String label, JComponent field, JPanel panel) {
+ JLabel jLabel = new JBLabel(label);
+ jLabel.setLabelFor(field);
+ panel.add(jLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.WEST,
+ GridBagConstraints.NONE, new Insets(0, 0, 5, 0), 0, 0));
+ panel.add(field, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0, GridBagConstraints.NORTHWEST,
+ GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0));
+ }
+
+ @Override
+ public void addSettingsComponent(@NotNull JComponent component) {
+ JPanel panel = myWizardContext.isCreatingNewProject() ? myNamePathComponent : myModulePanel;
+ panel.add(component, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0, GridBagConstraints.NORTHWEST,
+ GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
+ }
+
+ @Override
+ public void addExpertPanel(@NotNull JComponent panel) {
+ myExpertPanel.add(panel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0, GridBagConstraints.NORTHWEST,
+ GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
+ }
+
+ @Override
+ public void addExpertField(@NotNull String label, @NotNull JComponent field) {
+ JPanel panel = myWizardContext.isCreatingNewProject() ? myModulePanel : myExpertPanel;
+ addField(label, field, panel);
+ }
+
+ public void bindModuleSettings() {
+
+ myNamePathComponent.getNameComponent().getDocument().addDocumentListener(new DocumentAdapter() {
+ protected void textChanged(final DocumentEvent e) {
+ if (!myModuleNameChangedByUser) {
+ setModuleName(myNamePathComponent.getNameValue());
+ }
+ }
+ });
+
+ myModuleContentRoot.addBrowseFolderListener(ProjectBundle.message("project.new.wizard.module.content.root.chooser.title"), ProjectBundle.message("project.new.wizard.module.content.root.chooser.description"),
+ myWizardContext.getProject(), BrowseFilesListener.SINGLE_DIRECTORY_DESCRIPTOR);
+
+ myNamePathComponent.getPathComponent().getDocument().addDocumentListener(new DocumentAdapter() {
+ protected void textChanged(final DocumentEvent e) {
+ if (!myContentRootChangedByUser) {
+ setModuleContentRoot(myNamePathComponent.getPath());
+ }
+ }
+ });
+ myModuleName.getDocument().addDocumentListener(new DocumentAdapter() {
+ protected void textChanged(final DocumentEvent e) {
+ if (myModuleNameDocListenerEnabled) {
+ myModuleNameChangedByUser = true;
+ }
+ String path = getDefaultBaseDir(myWizardContext);
+ final String moduleName = getModuleName();
+ if (path.length() > 0 && !Comparing.strEqual(moduleName, myNamePathComponent.getNameValue())) {
+ path += "/" + moduleName;
+ }
+ if (!myContentRootChangedByUser) {
+ final boolean f = myModuleNameChangedByUser;
+ myModuleNameChangedByUser = true;
+ setModuleContentRoot(path);
+ myModuleNameChangedByUser = f;
+ }
+ if (!myImlLocationChangedByUser) {
+ setImlFileLocation(path);
+ }
+ }
+ });
+ myModuleContentRoot.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
+ protected void textChanged(final DocumentEvent e) {
+ if (myContentRootDocListenerEnabled) {
+ myContentRootChangedByUser = true;
+ }
+ if (!myImlLocationChangedByUser) {
+ setImlFileLocation(getModuleContentRoot());
+ }
+ if (!myModuleNameChangedByUser) {
+ final String path = FileUtil.toSystemIndependentName(getModuleContentRoot());
+ final int idx = path.lastIndexOf("/");
+
+ boolean f = myContentRootChangedByUser;
+ myContentRootChangedByUser = true;
+
+ boolean i = myImlLocationChangedByUser;
+ myImlLocationChangedByUser = true;
+
+ setModuleName(idx >= 0 ? path.substring(idx + 1) : "");
+
+ myContentRootChangedByUser = f;
+ myImlLocationChangedByUser = i;
+ }
+ }
+ });
+
+ myModuleFileLocation.addBrowseFolderListener(ProjectBundle.message("project.new.wizard.module.file.chooser.title"), ProjectBundle.message("project.new.wizard.module.file.description"),
+ myWizardContext.getProject(), BrowseFilesListener.SINGLE_DIRECTORY_DESCRIPTOR);
+ myModuleFileLocation.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
+ protected void textChanged(final DocumentEvent e) {
+ if (myImlLocationDocListenerEnabled) {
+ myImlLocationChangedByUser = true;
+ }
+ }
+ });
+ myNamePathComponent.getPathComponent().getDocument().addDocumentListener(new DocumentAdapter() {
+ protected void textChanged(final DocumentEvent e) {
+ if (!myImlLocationChangedByUser) {
+ setImlFileLocation(myNamePathComponent.getPath());
+ }
+ }
+ });
+ if (myWizardContext.isCreatingNewProject()) {
+ setModuleName(myNamePathComponent.getNameValue());
+ setModuleContentRoot(myNamePathComponent.getPath());
+ setImlFileLocation(myNamePathComponent.getPath());
+ } else {
+ final Project project = myWizardContext.getProject();
+ assert project != null;
+ VirtualFile baseDir = project.getBaseDir();
+ if (baseDir != null) { //e.g. was deleted
+ final String baseDirPath = baseDir.getPath();
+ String moduleName = ProjectWizardUtil.findNonExistingFileName(baseDirPath, "untitled", "");
+ String contentRoot = baseDirPath + "/" + moduleName;
+ if (!Comparing.strEqual(project.getName(), myWizardContext.getProjectName()) && !myWizardContext.isCreatingNewProject() && myWizardContext.getProjectName() != null) {
+ moduleName = ProjectWizardUtil.findNonExistingFileName(myWizardContext.getProjectFileDirectory(), myWizardContext.getProjectName(), "");
+ contentRoot = myWizardContext.getProjectFileDirectory();
+ }
+ setModuleName(moduleName);
+ setModuleContentRoot(contentRoot);
+ setImlFileLocation(contentRoot);
+ myModuleName.select(0, moduleName.length());
+ }
+ }
+ }
+
+ private void validateExistingModuleName() throws ConfigurationException {
+ final String moduleName = getModuleName();
+ final Module module;
+ final ProjectStructureConfigurable fromConfigurable = ProjectStructureConfigurable.getInstance(myWizardContext.getProject());
+ if (fromConfigurable != null) {
+ module = fromConfigurable.getModulesConfig().getModule(moduleName);
+ }
+ else {
+ module = ModuleManager.getInstance(myWizardContext.getProject()).findModuleByName(moduleName);
+ }
+ if (module != null) {
+ throw new ConfigurationException("Module \'" + moduleName + "\' already exist in project. Please, specify another name.");
+ }
+ }
+
+ private boolean validateModulePaths() throws ConfigurationException {
+ final String moduleName = getModuleName();
+ final String moduleFileDirectory = myModuleFileLocation.getText();
+ if (moduleFileDirectory.length() == 0) {
+ throw new ConfigurationException("Enter module file location");
+ }
+ if (moduleName.length() == 0) {
+ throw new ConfigurationException("Enter a module name");
+ }
+
+ if (!ProjectWizardUtil.createDirectoryIfNotExists(IdeBundle.message("directory.module.file"), moduleFileDirectory,
+ myImlLocationChangedByUser)) {
+ return false;
+ }
+ if (!ProjectWizardUtil.createDirectoryIfNotExists(IdeBundle.message("directory.module.content.root"), myModuleContentRoot.getText(),
+ myContentRootChangedByUser)) {
+ return false;
+ }
+
+ File moduleFile = new File(moduleFileDirectory, moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION);
+ if (moduleFile.exists()) {
+ int answer = Messages.showYesNoDialog(IdeBundle.message("prompt.overwrite.project.file", moduleFile.getAbsolutePath(),
+ IdeBundle.message("project.new.wizard.module.identification")),
+ IdeBundle.message("title.file.already.exists"), Messages.getQuestionIcon());
+ if (answer != 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected String getModuleContentRoot() {
+ return myModuleContentRoot.getText();
+ }
+
+ private String getDefaultBaseDir(WizardContext wizardContext) {
+ if (wizardContext.isCreatingNewProject()) {
+ return myNamePathComponent.getPath();
+ } else {
+ final Project project = wizardContext.getProject();
+ assert project != null;
+ final VirtualFile baseDir = project.getBaseDir();
+ if (baseDir != null) {
+ return baseDir.getPath();
+ }
+ return "";
+ }
+ }
+
+ private void setImlFileLocation(final String path) {
+ myImlLocationDocListenerEnabled = false;
+ myModuleFileLocation.setText(FileUtil.toSystemDependentName(path));
+ myImlLocationDocListenerEnabled = true;
+ }
+
+ private void setModuleContentRoot(final String path) {
+ myContentRootDocListenerEnabled = false;
+ myModuleContentRoot.setText(FileUtil.toSystemDependentName(path));
+ myContentRootDocListenerEnabled = true;
+ }
+
+ public void setModuleName(String moduleName) {
+ myModuleNameDocListenerEnabled = false;
+ myModuleName.setText(moduleName);
+ myModuleNameDocListenerEnabled = true;
+ }
+
+ @NotNull
+ public JTextField getModuleNameField() {
+ return myModuleName;
+ }
+
+ protected String getModuleName() {
+ return myModuleName.getText().trim();
+ }
+
+ @TestOnly
+ @Nullable
+ public ModuleWizardStep getSettingsStep() {
+ return mySettingsStep;
+ }
+
+ @Override
+ public Icon getIcon() {
+ return null;
+ }
+}
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSummaryStep.form b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSummaryStep.form
new file mode 100644
index 0000000..a0f1f25
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSummaryStep.form
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.ide.projectWizard.ProjectSummaryStep">
+ <grid id="27dc6" binding="myRootPanel" 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="500" height="400"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <grid id="15993" binding="myNameAndLocationPanel" layout-manager="BorderLayout" hgap="0" vgap="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"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children/>
+ </grid>
+ <vspacer id="c6894">
+ <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/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSummaryStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSummaryStep.java
new file mode 100644
index 0000000..28e9cec
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectSummaryStep.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.projectWizard;
+
+import com.intellij.ide.util.projectWizard.NamePathComponent;
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.ide.wizard.CommitStepException;
+import com.intellij.ide.wizard.StepAdapter;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author Dmitry Avdeev
+ * Date: 20.09.13
+ */
+public class ProjectSummaryStep extends StepAdapter {
+
+ private final WizardContext myWizardContext;
+ private JPanel myRootPanel;
+ private JPanel myNameAndLocationPanel;
+ private final NamePathComponent myNamePathComponent;
+
+ public ProjectSummaryStep(WizardContext context) {
+ myWizardContext = context;
+ myNamePathComponent = NamePathComponent.initNamePathComponent(myWizardContext);
+ myNameAndLocationPanel.add(myNamePathComponent, BorderLayout.CENTER);
+ }
+
+ @Override
+ public void _commit(boolean finishChosen) throws CommitStepException {
+ myWizardContext.setProjectName(myNamePathComponent.getNameValue());
+ myWizardContext.setProjectFileDirectory(myNamePathComponent.getPath());
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return myRootPanel;
+ }
+
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return myNamePathComponent.getNameComponent();
+ }
+}
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form
index 85e5a75..513c11a 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form
@@ -39,7 +39,7 @@
</scrollpane>
</children>
</grid>
- <grid id="ad16" binding="myOptionsPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
+ <grid id="ad16" binding="myOptionsPanel" layout-manager="CardLayout" hgap="0" vgap="0">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java
index 07a1e2c..fc9b0f9 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java
@@ -18,72 +18,171 @@
import com.intellij.framework.FrameworkGroup;
import com.intellij.framework.FrameworkTypeEx;
import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider;
-import com.intellij.ide.util.frameworkSupport.FrameworkSupportModelImpl;
import com.intellij.ide.util.frameworkSupport.FrameworkSupportUtil;
import com.intellij.ide.util.newProjectWizard.AddSupportForFrameworksPanel;
import com.intellij.ide.util.newProjectWizard.impl.FrameworkSupportModelBase;
-import com.intellij.ide.wizard.StepAdapter;
-import com.intellij.openapi.Disposable;
+import com.intellij.ide.util.projectWizard.ModuleBuilder;
+import com.intellij.ide.util.projectWizard.ModuleWizardStep;
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.ui.CheckedTreeNode;
import com.intellij.ui.CollectionListModel;
+import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.components.JBList;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.FactoryMap;
+import com.intellij.util.containers.MultiMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
+import java.util.*;
import java.util.List;
/**
* @author Dmitry Avdeev
* Date: 04.09.13
*/
-public class ProjectTypeStep extends StepAdapter {
+public class ProjectTypeStep extends ModuleWizardStep {
+ private static final String FRAMEWORKS_CARD = "frameworks card";
+ private final WizardContext myContext;
+ private final NewProjectWizard myWizard;
+ private final ModulesProvider myModulesProvider;
private JPanel myPanel;
private JBList myProjectTypeList;
private JPanel myOptionsPanel;
+ @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
+ private final FactoryMap<ProjectCategory, ModuleBuilder> myBuilders = new FactoryMap<ProjectCategory, ModuleBuilder>() {
+ @Nullable
+ @Override
+ protected ModuleBuilder create(ProjectCategory key) {
+ return key.createModuleBuilder();
+ }
+ };
+ private final Set<String> myCards = new HashSet<String>();
+
private final AddSupportForFrameworksPanel myFrameworksPanel;
- private final FrameworkSupportModelBase myModel;
+ private final ModuleBuilder.ModuleConfigurationUpdater myConfigurationUpdater;
- public ProjectTypeStep(Project project, Disposable disposable) {
-
+ public ProjectTypeStep(WizardContext context, NewProjectWizard wizard, ModulesProvider modulesProvider) {
+ myContext = context;
+ myWizard = wizard;
+ myModulesProvider = modulesProvider;
+ Project project = context.getProject();
final LibrariesContainer container = LibrariesContainerFactory.createContainer(project);
- myModel = new FrameworkSupportModelImpl(project, "", container);
- ProjectCategory[] projectCategories = ProjectCategory.EXTENSION_POINT_NAME.getExtensions();
- myProjectTypeList.setModel(new CollectionListModel<ProjectCategory>(Arrays.asList(projectCategories)));
- myProjectTypeList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+ FrameworkSupportModelBase model = new FrameworkSupportModelBase(project, null, container) {
+ @NotNull
@Override
- public void valueChanged(ListSelectionEvent e) {
- updateFrameworks((ProjectCategory)myProjectTypeList.getSelectedValue());
+ public String getBaseDirectoryForLibrariesPath() {
+ return StringUtil.notNullize(getSelectedBuilder().getContentEntryPath());
+ }
+ };
+ myConfigurationUpdater = new ModuleBuilder.ModuleConfigurationUpdater() {
+ @Override
+ public void update(@NotNull Module module, @NotNull ModifiableRootModel rootModel) {
+ myFrameworksPanel.addSupport(module, rootModel);
+ }
+ };
+
+ myProjectTypeList.setCellRenderer(new ColoredListCellRenderer() {
+ @Override
+ protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
+ ProjectCategory category = (ProjectCategory)value;
+ append(category.getDisplayName());
+ setIcon(category.getIcon());
}
});
- myFrameworksPanel = new AddSupportForFrameworksPanel(Collections.<FrameworkSupportInModuleProvider>emptyList(), myModel, true);
- Disposer.register(disposable, myFrameworksPanel);
+ List<ProjectCategory> categories = new ArrayList<ProjectCategory>();
+ categories.addAll(ContainerUtil.map(ModuleBuilder.getAllBuilders(), new Function<ModuleBuilder, ProjectCategory>() {
+ @Override
+ public ProjectCategory fun(ModuleBuilder builder) {
+ return new BuilderBasedProjectType(builder);
+ }
+ }));
+ categories.addAll(Arrays.asList(ProjectCategory.EXTENSION_POINT_NAME.getExtensions()));
- myOptionsPanel.add(myFrameworksPanel.getMainPanel(), BorderLayout.CENTER);
+ final MultiMap<String, ProjectCategory> map = new MultiMap<String, ProjectCategory>();
+ for (ProjectCategory category : categories) {
+ map.putValue(category.getGroupName(), category);
+ }
+ Collections.sort(categories, new Comparator<ProjectCategory>() {
+ @Override
+ public int compare(ProjectCategory o1, ProjectCategory o2) {
+ return map.get(o2.getGroupName()).size() - map.get(o1.getGroupName()).size();
+ }
+ });
+
+ myProjectTypeList.setModel(new CollectionListModel<ProjectCategory>(categories));
+ myProjectTypeList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+ @Override
+ public void valueChanged(ListSelectionEvent e) {
+ ModuleBuilder builder = getSelectedBuilder();
+ myContext.setProjectBuilder(builder);
+ myWizard.getSequence().setType(builder.getBuilderId());
+ builder.addModuleConfigurationUpdater(myConfigurationUpdater);
+ updateOptionsPanel((ProjectCategory)myProjectTypeList.getSelectedValue());
+ }
+ });
+
+ for (ProjectCategory category : categories) {
+ myWizard.getSequence().addStepsForBuilder(myBuilders.get(category), context, modulesProvider, true);
+ }
+
+ myFrameworksPanel = new AddSupportForFrameworksPanel(Collections.<FrameworkSupportInModuleProvider>emptyList(), model, true);
+ Disposer.register(wizard.getDisposable(), myFrameworksPanel);
+
+ myOptionsPanel.add(myFrameworksPanel.getMainPanel(), FRAMEWORKS_CARD);
myProjectTypeList.setSelectedIndex(0);
}
- private void updateFrameworks(ProjectCategory projectCategory) {
- List<FrameworkSupportInModuleProvider> providers = new ArrayList<FrameworkSupportInModuleProvider>();
- if (projectCategory != null) {
+ private ModuleBuilder getSelectedBuilder() {
+ ProjectCategory projectCategory = (ProjectCategory)myProjectTypeList.getSelectedValue();
+ return myBuilders.get(projectCategory);
+ }
+
+ private void updateOptionsPanel(ProjectCategory projectCategory) {
+ if (projectCategory == null) return;
+ ModuleBuilder builder = myBuilders.get(projectCategory);
+ JComponent panel = builder.getCustomOptionsPanel(this);
+ String card;
+ if (panel != null) {
+ card = builder.getBuilderId();
+ if (myCards.add(card)) {
+ myOptionsPanel.add(panel, card);
+ }
+ }
+ else {
+ card = FRAMEWORKS_CARD;
+ List<FrameworkSupportInModuleProvider> providers = new ArrayList<FrameworkSupportInModuleProvider>();
for (FrameworkSupportInModuleProvider framework : FrameworkSupportUtil.getAllProviders()) {
if (matchFramework(projectCategory, framework)) {
providers.add(framework);
}
}
+ myFrameworksPanel.setProviders(providers);
+ for (FrameworkSupportInModuleProvider provider : providers) {
+ if (ArrayUtil.contains(provider.getFrameworkType().getId(), projectCategory.getAssociatedFrameworkIds())) {
+ CheckedTreeNode treeNode = myFrameworksPanel.findNodeFor(provider);
+ treeNode.setChecked(true);
+ }
+ }
}
- myFrameworksPanel.setProviders(providers);
+ ((CardLayout)myOptionsPanel.getLayout()).show(myOptionsPanel, card);
}
private static boolean matchFramework(ProjectCategory projectCategory, FrameworkSupportInModuleProvider framework) {
@@ -120,6 +219,11 @@
}
@Override
+ public void updateDataModel() {
+ myWizard.getSequence().addStepsForBuilder(getSelectedBuilder(), myContext, myModulesProvider, true);
+ }
+
+ @Override
public JComponent getPreferredFocusedComponent() {
return myProjectTypeList;
}
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/TemplateBasedProjectType.java b/java/idea-ui/src/com/intellij/ide/projectWizard/TemplateBasedProjectType.java
new file mode 100644
index 0000000..b6d8cf7
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/TemplateBasedProjectType.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.projectWizard;
+
+import com.intellij.ide.util.projectWizard.ModuleBuilder;
+import com.intellij.platform.templates.ArchivedTemplatesFactory;
+import com.intellij.platform.templates.LocalArchivedTemplate;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.io.File;
+import java.net.URL;
+
+/**
+ * @author Dmitry Avdeev
+ * Date: 20.09.13
+ */
+public abstract class TemplateBasedProjectType extends ProjectCategory {
+
+ private final LocalArchivedTemplate myTemplate;
+
+ public TemplateBasedProjectType(String templatePath) {
+ ClassLoader loader = getClass().getClassLoader();
+ URL resource = loader.getResource(templatePath);
+ assert resource != null : templatePath;
+ String name = ArchivedTemplatesFactory.getTemplateName(new File(templatePath).getName());
+ myTemplate = new LocalArchivedTemplate(name, resource, loader);
+ }
+
+ @NotNull
+ @Override
+ public ModuleBuilder createModuleBuilder() {
+ return myTemplate.createModuleBuilder();
+ }
+
+ @Override
+ public String getId() {
+ return getDisplayName();
+ }
+
+ @Override
+ public String getDisplayName() {
+ return myTemplate.getName();
+ }
+
+ @Override
+ public String getDescription() {
+ return myTemplate.getDescription();
+ }
+
+ @Override
+ public Icon getIcon() {
+ return myTemplate.getIcon();
+ }
+}
diff --git a/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/FrameworkSupportUtil.java b/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/FrameworkSupportUtil.java
index 78c9c68..b2b81ee 100644
--- a/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/FrameworkSupportUtil.java
+++ b/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/FrameworkSupportUtil.java
@@ -123,6 +123,12 @@
dependencies.add(underlyingProvider);
}
}
+ for (String frameworkId : provider.getOptionalDependenciesFrameworkIds()) {
+ FrameworkSupportInModuleProvider dep = findProvider(frameworkId, myFrameworkSupportProviders);
+ if (dep != null) {
+ dependencies.add(dep);
+ }
+ }
if (provider instanceof OldFrameworkSupportProviderWrapper) {
String[] ids = ((OldFrameworkSupportProviderWrapper)provider).getProvider().getPrecedingFrameworkProviderIds();
for (String id : ids) {
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AbstractProjectWizard.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AbstractProjectWizard.java
new file mode 100644
index 0000000..deca300
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AbstractProjectWizard.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.util.newProjectWizard;
+
+import com.intellij.ide.highlighter.ModuleFileType;
+import com.intellij.ide.highlighter.ProjectFileType;
+import com.intellij.ide.util.projectWizard.ModuleWizardStep;
+import com.intellij.ide.util.projectWizard.ProjectBuilder;
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.ide.wizard.AbstractWizard;
+import com.intellij.ide.wizard.CommitStepException;
+import com.intellij.openapi.components.StorageScheme;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+
+import java.awt.*;
+import java.io.File;
+
+/**
+ * @author Dmitry Avdeev
+ * Date: 19.09.13
+ */
+public abstract class AbstractProjectWizard extends AbstractWizard<ModuleWizardStep> {
+ protected final WizardContext myWizardContext;
+
+ public AbstractProjectWizard(String title, Project project, String defaultPath) {
+ super(title, project);
+ myWizardContext = initContext(project, defaultPath);
+ }
+
+ public AbstractProjectWizard(String title, Project project, Component dialogParent) {
+ super(title, dialogParent);
+ myWizardContext = initContext(project, null);
+ }
+
+ public abstract StepSequence getSequence();
+
+ private static WizardContext initContext(@Nullable Project project, @Nullable String defaultPath) {
+ WizardContext context = new WizardContext(project);
+ if (defaultPath != null) {
+ context.setProjectFileDirectory(defaultPath);
+ context.setProjectName(defaultPath.substring(FileUtil.toSystemIndependentName(defaultPath).lastIndexOf("/") + 1));
+ }
+ return context;
+ }
+
+ @Nullable
+ public static Sdk getNewProjectJdk(WizardContext context) {
+ if (context.getProjectJdk() != null) {
+ return context.getProjectJdk();
+ }
+ return getProjectSdkByDefault(context);
+ }
+
+ public static Sdk getProjectSdkByDefault(WizardContext context) {
+ final Project project = context.getProject() == null ? ProjectManager.getInstance().getDefaultProject() : context.getProject();
+ final Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectSdk();
+ if (projectJdk != null) {
+ return projectJdk;
+ }
+ return null;
+ }
+
+ @NotNull
+ public String getNewProjectFilePath() {
+ if (myWizardContext.getProjectStorageFormat() == StorageScheme.DEFAULT) {
+ return myWizardContext.getProjectFileDirectory() + File.separator + myWizardContext.getProjectName() + ProjectFileType.DOT_DEFAULT_EXTENSION;
+ }
+ else {
+ return myWizardContext.getProjectFileDirectory();
+ }
+ }
+
+ @NotNull
+ public StorageScheme getStorageScheme() {
+ return myWizardContext.getProjectStorageFormat();
+ }
+
+ public ProjectBuilder getProjectBuilder() {
+ return myWizardContext.getProjectBuilder();
+ }
+
+ public String getProjectName() {
+ return myWizardContext.getProjectName();
+ }
+
+ @Nullable
+ public Sdk getNewProjectJdk() {
+ return getNewProjectJdk(myWizardContext);
+ }
+
+ @NotNull
+ public String getNewCompileOutput() {
+ final String projectFilePath = myWizardContext.getProjectFileDirectory();
+ @NonNls String path = myWizardContext.getCompilerOutputDirectory();
+ if (path == null) {
+ path = StringUtil.endsWithChar(projectFilePath, '/') ? projectFilePath + "out" : projectFilePath + "/out";
+ }
+ return path;
+ }
+
+ protected void updateStep() {
+ if (!mySteps.isEmpty()) {
+ getCurrentStepObject().updateStep();
+ }
+ super.updateStep();
+ myIcon.setIcon(null);
+ }
+
+ protected void dispose() {
+ for (ModuleWizardStep step : mySteps) {
+ step.disposeUIResources();
+ }
+ super.dispose();
+ }
+
+ protected final void doOKAction() {
+ int idx = getCurrentStep();
+ try {
+ do {
+ final ModuleWizardStep step = mySteps.get(idx);
+ if (step != getCurrentStepObject()) {
+ step.updateStep();
+ }
+ if (!commitStepData(step)) {
+ return;
+ }
+ step.onStepLeaving();
+ try {
+ step._commit(true);
+ }
+ catch (CommitStepException e) {
+ String message = e.getMessage();
+ if (message != null) {
+ Messages.showErrorDialog(getCurrentStepComponent(), message);
+ }
+ return;
+ }
+ if (!isLastStep(idx)) {
+ idx = getNextStep(idx);
+ } else {
+ break;
+ }
+ } while (true);
+ }
+ finally {
+ myCurrentStep = idx;
+ updateStep();
+ }
+ super.doOKAction();
+ }
+
+ protected boolean commitStepData(final ModuleWizardStep step) {
+ try {
+ if (!step.validate()) {
+ return false;
+ }
+ }
+ catch (ConfigurationException e) {
+ Messages.showErrorDialog(myContentPanel, e.getMessage(), e.getTitle());
+ return false;
+ }
+ step.updateDataModel();
+ return true;
+ }
+
+ public void doNextAction() {
+ final ModuleWizardStep step = getCurrentStepObject();
+ if (!commitStepData(step)) {
+ return;
+ }
+ step.onStepLeaving();
+ super.doNextAction();
+ }
+
+
+ protected String getHelpID() {
+ ModuleWizardStep step = getCurrentStepObject();
+ if (step != null) {
+ return step.getHelpId();
+ }
+ return null;
+ }
+
+ @TestOnly
+ public void doOk() {
+ doOKAction();
+ }
+
+ @TestOnly
+ public boolean isLast() {
+ return isLastStep();
+ }
+
+ @NonNls
+ public String getModuleFilePath() {
+ return myWizardContext.getProjectFileDirectory() + File.separator + myWizardContext.getProjectName() + ModuleFileType.DOT_DEFAULT_EXTENSION;
+ }
+
+ protected void doPreviousAction() {
+ final ModuleWizardStep step = getCurrentStepObject();
+ step.onStepLeaving();
+ super.doPreviousAction();
+ }
+
+ public void doCancelAction() {
+ final ModuleWizardStep step = getCurrentStepObject();
+ step.onStepLeaving();
+ super.doCancelAction();
+ }
+
+ private boolean isLastStep(int step) {
+ return getNextStep(step) == step;
+ }
+
+ protected final int getNextStep(final int step) {
+ ModuleWizardStep nextStep = null;
+ final StepSequence stepSequence = getSequence();
+ if (stepSequence != null) {
+ ModuleWizardStep current = mySteps.get(step);
+ nextStep = stepSequence.getNextStep(current);
+ while (nextStep != null && !nextStep.isStepVisible()) {
+ nextStep = stepSequence.getNextStep(nextStep);
+ }
+ }
+ return nextStep == null ? step : mySteps.indexOf(nextStep);
+ }
+
+ protected final int getPreviousStep(final int step) {
+ ModuleWizardStep previousStep = null;
+ final StepSequence stepSequence = getSequence();
+ if (stepSequence != null) {
+ previousStep = stepSequence.getPreviousStep(mySteps.get(step));
+ while (previousStep != null && !previousStep.isStepVisible()) {
+ previousStep = stepSequence.getPreviousStep(previousStep);
+ }
+ }
+ return previousStep == null ? 0 : mySteps.indexOf(previousStep);
+ }
+}
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddModuleWizard.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddModuleWizard.java
index 2cb74deb..31af15d 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddModuleWizard.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddModuleWizard.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,77 +21,58 @@
package com.intellij.ide.util.newProjectWizard;
import com.intellij.ide.IdeBundle;
-import com.intellij.ide.highlighter.ModuleFileType;
-import com.intellij.ide.highlighter.ProjectFileType;
import com.intellij.ide.util.newProjectWizard.modes.CreateFromTemplateMode;
import com.intellij.ide.util.newProjectWizard.modes.ImportMode;
import com.intellij.ide.util.newProjectWizard.modes.WizardMode;
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
import com.intellij.ide.util.projectWizard.ProjectBuilder;
import com.intellij.ide.util.projectWizard.WizardContext;
-import com.intellij.ide.wizard.AbstractWizard;
-import com.intellij.ide.wizard.CommitStepException;
import com.intellij.ide.wizard.Step;
-import com.intellij.openapi.components.StorageScheme;
-import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
-import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.projectImport.ProjectImportBuilder;
import com.intellij.projectImport.ProjectImportProvider;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.util.Function;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
import java.awt.*;
-import java.io.File;
-public class AddModuleWizard extends AbstractWizard<ModuleWizardStep>
-{
+public class AddModuleWizard extends AbstractProjectWizard {
private static final String ADD_MODULE_TITLE = IdeBundle.message("title.add.module");
private static final String NEW_PROJECT_TITLE = IdeBundle.message("title.new.project");
- private final Project myCurrentProject;
private ProjectImportProvider[] myImportProviders;
private final ModulesProvider myModulesProvider;
- private WizardContext myWizardContext;
private WizardMode myWizardMode;
/**
* @param project if null, the wizard will start creating new project, otherwise will add a new module to the existing project.
*/
public AddModuleWizard(@Nullable final Project project, final @NotNull ModulesProvider modulesProvider, @Nullable String defaultPath) {
- super(project == null ? NEW_PROJECT_TITLE : ADD_MODULE_TITLE, project);
- myCurrentProject = project;
+ super(project == null ? NEW_PROJECT_TITLE : ADD_MODULE_TITLE, project, defaultPath);
myModulesProvider = modulesProvider;
initModuleWizard(project, defaultPath);
}
/**
- * @param project if null, the wizard will start creating new project, otherwise will add a new module to the existing proj.
+ * @param project if null, the wizard will start creating new project, otherwise will add a new module to the existing project.
*/
public AddModuleWizard(Component parent, final Project project, @NotNull ModulesProvider modulesProvider) {
- super(project == null ? NEW_PROJECT_TITLE : ADD_MODULE_TITLE, parent);
- myCurrentProject = project;
+ super(project == null ? NEW_PROJECT_TITLE : ADD_MODULE_TITLE, project, parent);
myModulesProvider = modulesProvider;
initModuleWizard(project, null);
}
/** Import mode */
public AddModuleWizard(@Nullable Project project, String filePath, ProjectImportProvider... importProviders) {
- super(getImportWizardTitle(project, importProviders), project);
- myCurrentProject = project;
+ super(getImportWizardTitle(project, importProviders), project, filePath);
myImportProviders = importProviders;
myModulesProvider = DefaultModulesProvider.createForProject(project);
initModuleWizard(project, filePath);
@@ -99,8 +80,7 @@
/** Import mode */
public AddModuleWizard(Project project, Component dialogParent, String filePath, ProjectImportProvider... importProviders) {
- super(getImportWizardTitle(project, importProviders), dialogParent);
- myCurrentProject = project;
+ super(getImportWizardTitle(project, importProviders), project, dialogParent);
myImportProviders = importProviders;
myModulesProvider = DefaultModulesProvider.createForProject(project);
initModuleWizard(project, filePath);
@@ -116,11 +96,6 @@
}
private void initModuleWizard(@Nullable final Project project, @Nullable final String defaultPath) {
- myWizardContext = new WizardContext(project);
- if (defaultPath != null) {
- myWizardContext.setProjectFileDirectory(defaultPath);
- myWizardContext.setProjectName(defaultPath.substring(FileUtil.toSystemIndependentName(defaultPath).lastIndexOf("/") + 1));
- }
myWizardContext.addContextListener(new WizardContext.Listener() {
public void buttonsUpdateRequested() {
updateButtons();
@@ -167,168 +142,9 @@
return super.addStepComponent(component);
}
- protected void updateStep() {
- if (!mySteps.isEmpty()) {
- getCurrentStepObject().updateStep();
- }
- super.updateStep();
- myIcon.setIcon(null);
- }
-
- protected void dispose() {
- for (ModuleWizardStep step : mySteps) {
- step.disposeUIResources();
- }
- super.dispose();
- }
-
- protected final void doOKAction() {
- int idx = getCurrentStep();
- try {
- do {
- final ModuleWizardStep step = mySteps.get(idx);
- if (step != getCurrentStepObject()) {
- step.updateStep();
- }
- if (!commitStepData(step)) {
- return;
- }
- step.onStepLeaving();
- try {
- step._commit(true);
- }
- catch (CommitStepException e) {
- String message = e.getMessage();
- if (message != null) {
- Messages.showErrorDialog(getCurrentStepComponent(), message);
- }
- return;
- }
- if (!isLastStep(idx)) {
- idx = getNextStep(idx);
- } else {
- break;
- }
- } while (true);
- }
- finally {
- myCurrentStep = idx;
- updateStep();
- }
- super.doOKAction();
- }
-
- protected boolean commitStepData(final ModuleWizardStep step) {
- try {
- if (!step.validate()) {
- return false;
- }
- }
- catch (ConfigurationException e) {
- Messages.showErrorDialog(myCurrentProject, e.getMessage(), e.getTitle());
- return false;
- }
- step.updateDataModel();
- return true;
- }
-
- public void doNextAction() {
- final ModuleWizardStep step = getCurrentStepObject();
- if (!commitStepData(step)) {
- return;
- }
- step.onStepLeaving();
- super.doNextAction();
- }
-
- protected void doPreviousAction() {
- final ModuleWizardStep step = getCurrentStepObject();
- step.onStepLeaving();
- super.doPreviousAction();
- }
-
- public void doCancelAction() {
- final ModuleWizardStep step = getCurrentStepObject();
- step.onStepLeaving();
- super.doCancelAction();
- }
-
- private boolean isLastStep(int step) {
- return getNextStep(step) == step;
- }
-
-
- protected String getHelpID() {
- ModuleWizardStep step = getCurrentStepObject();
- if (step != null) {
- return step.getHelpId();
- }
- return null;
- }
-
- protected final int getNextStep(final int step) {
- ModuleWizardStep nextStep = null;
- final StepSequence stepSequence = getSequence();
- if (stepSequence != null) {
- ModuleWizardStep current = mySteps.get(step);
- nextStep = stepSequence.getNextStep(current);
- while (nextStep != null && !nextStep.isStepVisible()) {
- nextStep = stepSequence.getNextStep(nextStep);
- }
- }
- return nextStep == null ? step : mySteps.indexOf(nextStep);
- }
-
+ @Override
public StepSequence getSequence() {
- return getMode().getSteps(myWizardContext, myModulesProvider);
- }
-
- protected final int getPreviousStep(final int step) {
- ModuleWizardStep previousStep = null;
- final StepSequence stepSequence = getSequence();
- if (stepSequence != null) {
- previousStep = stepSequence.getPreviousStep(mySteps.get(step));
- while (previousStep != null && !previousStep.isStepVisible()) {
- previousStep = stepSequence.getPreviousStep(previousStep);
- }
- }
- return previousStep == null ? 0 : mySteps.indexOf(previousStep);
- }
-
- private WizardMode getMode() {
- return myWizardMode;
- }
-
- @NotNull
- public String getNewProjectFilePath() {
- if (myWizardContext.getProjectStorageFormat() == StorageScheme.DEFAULT) {
- return myWizardContext.getProjectFileDirectory() + File.separator + myWizardContext.getProjectName() + ProjectFileType.DOT_DEFAULT_EXTENSION;
- }
- else {
- return myWizardContext.getProjectFileDirectory();
- }
- }
-
- @NotNull
- public StorageScheme getStorageScheme() {
- return myWizardContext.getProjectStorageFormat();
- }
-
- @Nullable
- public static Sdk getNewProjectJdk(WizardContext context) {
- if (context.getProjectJdk() != null) {
- return context.getProjectJdk();
- }
- return getProjectSdkByDefault(context);
- }
-
- public static Sdk getProjectSdkByDefault(WizardContext context) {
- final Project project = context.getProject() == null ? ProjectManager.getInstance().getDefaultProject() : context.getProject();
- final Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectSdk();
- if (projectJdk != null) {
- return projectJdk;
- }
- return null;
+ return myWizardMode.getSteps(myWizardContext, myModulesProvider);
}
@Nullable
@@ -349,34 +165,6 @@
return myWizardContext;
}
- @Nullable
- public Sdk getNewProjectJdk() {
- return getNewProjectJdk(myWizardContext);
- }
-
- @NotNull
- public String getNewCompileOutput() {
- final String projectFilePath = myWizardContext.getProjectFileDirectory();
- @NonNls String path = myWizardContext.getCompilerOutputDirectory();
- if (path == null) {
- path = StringUtil.endsWithChar(projectFilePath, '/') ? projectFilePath + "out" : projectFilePath + "/out";
- }
- return path;
- }
-
- @NonNls
- public String getModuleFilePath() {
- return myWizardContext.getProjectFileDirectory() + File.separator + myWizardContext.getProjectName() + ModuleFileType.DOT_DEFAULT_EXTENSION;
- }
-
- public ProjectBuilder getProjectBuilder() {
- return myWizardContext.getProjectBuilder();
- }
-
- public String getProjectName() {
- return myWizardContext.getProjectName();
- }
-
@Override
protected String getDimensionServiceKey() {
return "NewModule_or_Project.wizard";
@@ -404,20 +192,6 @@
return false;
}
- public ProjectImportProvider[] getImportProviders() {
- return myImportProviders;
- }
-
- @TestOnly
- public void doOk() {
- doOKAction();
- }
-
- @TestOnly
- public boolean isLast() {
- return isLastStep();
- }
-
@TestOnly
public void commit() {
commitStepData(getCurrentStepObject());
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java
index 6a8fef81..7e324c2 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java
@@ -40,6 +40,7 @@
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
+import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -47,6 +48,7 @@
import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.*;
import java.util.*;
import java.util.List;
@@ -78,7 +80,7 @@
myLibrariesContainer = model.getLibrariesContainer();
myLabel.setVisible(!vertical);
- Splitter splitter = vertical ? new Splitter(true, 0.6f, 0.3f, 0.9f) : new Splitter(false, 0.3f, 0.1f, 0.7f);
+ Splitter splitter = vertical ? new Splitter(true, 0.6f) : new Splitter(false, 0.3f, 0.1f, 0.7f);
myFrameworksTree = new FrameworksTree() {
@Override
protected void onNodeStateChanged(CheckedTreeNode node) {
@@ -109,13 +111,13 @@
splitter.setSecondComponent(myOptionsPanel);
myFrameworksPanel.add(splitter, BorderLayout.CENTER);
- myFrameworksTree.setSelectionRow(0);
}
public void setProviders(List<FrameworkSupportInModuleProvider> providers) {
myProviders = providers;
createNodes();
myFrameworksTree.setRoots(myRoots);
+ myFrameworksTree.setSelectionRow(0);
}
protected void onFrameworkStateChanged() {}
@@ -299,7 +301,7 @@
private static void addChildFrameworks(final List<FrameworkSupportNodeBase> list, final List<FrameworkSupportNode> result,
final boolean selectedOnly) {
for (FrameworkSupportNodeBase node : list) {
- if (!selectedOnly || node.isChecked()) {
+ if (!selectedOnly || node.isChecked() || node instanceof FrameworkGroupNode) {
if (node instanceof FrameworkSupportNode) {
result.add((FrameworkSupportNode)node);
}
@@ -351,4 +353,8 @@
}
});
}
+
+ public CheckedTreeNode findNodeFor(FrameworkSupportInModuleProvider provider) {
+ return (CheckedTreeNode)TreeUtil.findNodeWithObject((DefaultMutableTreeNode)myFrameworksTree.getModel().getRoot(), provider);
+ }
}
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java
index 9239c96..6dabfa4 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java
@@ -96,6 +96,7 @@
if (description != null) {
myLibraryOptionsPanel = new LibraryOptionsPanel(description, myModel.getBaseDirectoryForLibrariesPath(), createLibraryVersionFilter(),
container, !myConfigurable.isOnlyLibraryAdded());
+ myLibraryOptionsPanel.setLibraryProvider(myModel.getLibraryProvider());
Disposer.register(myConfigurable, myLibraryOptionsPanel);
if (addSeparator) {
JComponent separator1 = SeparatorFactory.createSeparator("Libraries", null);
@@ -111,6 +112,7 @@
if (myLibraryOptionsPanel != null) {
myLibraryOptionsPanel.changeBaseDirectoryPath(myModel.getBaseDirectoryForLibrariesPath());
myLibraryOptionsPanel.setVersionFilter(createLibraryVersionFilter());
+ myLibraryOptionsPanel.setLibraryProvider(myModel.getLibraryProvider());
myLibraryOptionsPanelWrapper.setVisible(myConfigurable.isVisible());
}
}
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java
index 13b4fcda..40ec96e 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java
@@ -106,7 +106,7 @@
Messages.installHyperlinkSupport(myDescriptionPane);
myFormatPanel = new ProjectFormatPanel();
- myNamePathComponent = initNamePathComponent(context);
+ myNamePathComponent = NamePathComponent.initNamePathComponent(context);
if (context.isCreatingNewProject()) {
mySettingsPanel.add(myNamePathComponent, BorderLayout.NORTH);
addExpertPanel(myModulePanel);
@@ -168,24 +168,6 @@
return helpId;
}
- private static NamePathComponent initNamePathComponent(WizardContext context) {
- NamePathComponent component = new NamePathComponent(
- IdeBundle.message("label.project.name"),
- IdeBundle.message("label.project.files.location"),
- IdeBundle.message("title.select.project.file.directory", IdeBundle.message("project.new.wizard.project.identification")),
- IdeBundle.message("description.select.project.file.directory", StringUtil
- .capitalize(IdeBundle.message("project.new.wizard.project.identification"))),
- true, false
- );
- final String baseDir = context.getProjectFileDirectory();
- final String projectName = context.getProjectName();
- final String initialProjectName = projectName != null ? projectName : ProjectWizardUtil.findNonExistingFileName(baseDir, "untitled", "");
- component.setPath(projectName == null ? (baseDir + File.separator + initialProjectName) : baseDir);
- component.setNameValue(initialProjectName);
- component.getNameComponent().select(0, initialProjectName.length());
- return component;
- }
-
private void setupPanels(@Nullable ProjectTemplate template) {
restorePanel(myNamePathComponent, 4);
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/StepSequence.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/StepSequence.java
index 3b3acf0..bbc9b21 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/StepSequence.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/StepSequence.java
@@ -49,14 +49,17 @@
myCommonSteps.add(step);
}
- public void addCommonFinishingStep(@NotNull ModuleWizardStep step, @NotNull Set<String> suitableTypes) {
+ public void addCommonFinishingStep(@NotNull ModuleWizardStep step, @Nullable Set<String> suitableTypes) {
myCommonFinishingSteps.add(Pair.create(step, suitableTypes));
}
- public void addStepsForBuilder(@NotNull AbstractModuleBuilder builder, @NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) {
+ public void addStepsForBuilder(@NotNull AbstractModuleBuilder builder,
+ @NotNull WizardContext wizardContext,
+ @NotNull ModulesProvider modulesProvider,
+ boolean forNewWizard) {
String id = builder.getBuilderId();
if (!mySpecificSteps.containsKey(id)) {
- mySpecificSteps.put(id, Arrays.asList(builder.createWizardSteps(wizardContext, modulesProvider)));
+ mySpecificSteps.put(id, Arrays.asList(builder.createWizardSteps(wizardContext, modulesProvider, forNewWizard)));
}
}
@@ -73,7 +76,8 @@
mySelectedSteps.addAll(steps);
}
for (Pair<ModuleWizardStep, Set<String>> pair : myCommonFinishingSteps) {
- if (ContainerUtil.intersects(myTypes, pair.getSecond())) {
+ Set<String> types = pair.getSecond();
+ if (types == null || ContainerUtil.intersects(myTypes, types)) {
mySelectedSteps.add(pair.getFirst());
}
}
@@ -121,8 +125,4 @@
ContainerUtil.removeDuplicates(result);
return result;
}
-
- public ModuleWizardStep getFirstStep() {
- return myCommonSteps.get(0);
- }
}
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SupportForFrameworksStep.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SupportForFrameworksStep.java
index 78f9bb2..08f56ea 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SupportForFrameworksStep.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SupportForFrameworksStep.java
@@ -17,13 +17,10 @@
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
-import javax.swing.tree.TreeNode;
import java.util.List;
/**
@@ -128,23 +125,4 @@
return getBaseDirectory(myBuilder);
}
}
-
- @TestOnly
- public boolean enableSupport(final String frameworkId) {
- return !TreeUtil.traverse((TreeNode)mySupportForFrameworksPanel.getFrameworksTree().getModel().getRoot(), new TreeUtil.Traverse() {
- @Override
- public boolean accept(Object node) {
- if (node instanceof FrameworkSupportNode && frameworkId.equals(
- ((FrameworkSupportNode)node).getProvider().getFrameworkType().getId())) {
- TreeNode parent = ((FrameworkSupportNode)node).getParent();
- if (parent instanceof FrameworkSupportNode) {
- ((FrameworkSupportNode)parent).setChecked(true);
- }
- ((FrameworkSupportNode)node).setChecked(true);
- return false;
- }
- return true;
- }
- });
- }
}
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java
index 48a9d929..8faaa8d 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java
@@ -15,6 +15,7 @@
*/
package com.intellij.ide.util.newProjectWizard.impl;
+import com.intellij.facet.impl.ui.libraries.FrameworkLibraryProvider;
import com.intellij.framework.FrameworkGroup;
import com.intellij.framework.FrameworkGroupVersion;
import com.intellij.framework.FrameworkVersion;
@@ -51,6 +52,7 @@
private final Map<String, FrameworkSupportNode> mySettingsMap = new HashMap<String, FrameworkSupportNode>();
private final Map<String, FrameworkSupportOptionsComponent> myOptionsComponentsMap = new HashMap<String, FrameworkSupportOptionsComponent>();
private final Map<String, FrameworkVersion> mySelectedVersions = new HashMap<String, FrameworkVersion>();
+ private FrameworkLibraryProvider myLibraryProvider;
public FrameworkSupportModelBase(final @Nullable Project project, @Nullable ModuleBuilder builder, @NotNull LibrariesContainer librariesContainer) {
myProject = project;
@@ -159,6 +161,17 @@
return false;
}
+ public FrameworkLibraryProvider getLibraryProvider() {
+ return myLibraryProvider;
+ }
+
+ public void setLibraryProvider(FrameworkLibraryProvider libraryProvider) {
+ myLibraryProvider = libraryProvider;
+ for (FrameworkSupportOptionsComponent optionsComponent : myOptionsComponentsMap.values()) {
+ optionsComponent.updateLibrariesPanel();
+ }
+ }
+
@Nullable
public <V extends FrameworkVersion> V getSelectedVersion(@NotNull String frameworkOrGroupId) {
return (V)mySelectedVersions.get(frameworkOrGroupId);
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java
index bc10c31..bb631ec 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java
@@ -63,7 +63,7 @@
StepSequence sequence = new StepSequence();
for (ModuleBuilder builder : builders) {
- sequence.addStepsForBuilder(builder, context, modulesProvider);
+ sequence.addStepsForBuilder(builder, context, modulesProvider, false);
}
return sequence;
}
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java
index 81aff5b..0d057b6 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java
@@ -106,7 +106,7 @@
MultiMap<TemplatesGroup, ProjectTemplate> map = getTemplatesMap(context);
StepSequence sequence = new StepSequence();
for (ProjectTemplate template : map.values()) {
- sequence.addStepsForBuilder(template.createModuleBuilder(), context, modulesProvider);
+ sequence.addStepsForBuilder(template.createModuleBuilder(), context, modulesProvider, false);
}
mySelectTemplateStep = new SelectTemplateStep(context, sequence, map);
sequence.addCommonStep(mySelectTemplateStep);
diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/NamePathComponent.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/NamePathComponent.java
index 47889b0..2a81296 100644
--- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/NamePathComponent.java
+++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/NamePathComponent.java
@@ -25,6 +25,7 @@
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.FieldPanel;
import com.intellij.util.ui.UIUtil;
@@ -118,6 +119,24 @@
insets, 0, 0));
}
+ public static NamePathComponent initNamePathComponent(WizardContext context) {
+ NamePathComponent component = new NamePathComponent(
+ IdeBundle.message("label.project.name"),
+ IdeBundle.message("label.project.files.location"),
+ IdeBundle.message("title.select.project.file.directory", IdeBundle.message("project.new.wizard.project.identification")),
+ IdeBundle.message("description.select.project.file.directory", StringUtil
+ .capitalize(IdeBundle.message("project.new.wizard.project.identification"))),
+ true, false
+ );
+ final String baseDir = context.getProjectFileDirectory();
+ final String projectName = context.getProjectName();
+ final String initialProjectName = projectName != null ? projectName : ProjectWizardUtil.findNonExistingFileName(baseDir, "untitled", "");
+ component.setPath(projectName == null ? (baseDir + File.separator + initialProjectName) : baseDir);
+ component.setNameValue(initialProjectName);
+ component.getNameComponent().select(0, initialProjectName.length());
+ return component;
+ }
+
private String getProjectFilePath(boolean isDefault) {
if (isDefault) {
return getPath() + "/" + getNameValue() + ProjectFileType.DOT_DEFAULT_EXTENSION;
diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactoryImpl.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactoryImpl.java
index 2674cd6..5397b3d 100644
--- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactoryImpl.java
+++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactoryImpl.java
@@ -16,7 +16,7 @@
package com.intellij.ide.util.projectWizard;
import com.intellij.ide.util.frameworkSupport.FrameworkSupportUtil;
-import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
+import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;
import com.intellij.ide.util.newProjectWizard.SourcePathsStep;
import com.intellij.ide.util.newProjectWizard.SupportForFrameworksStep;
import com.intellij.openapi.projectRoots.Sdk;
@@ -114,7 +114,7 @@
}
projectSdkStep = new ProjectJdkStep(wizardContext) {
public boolean isStepVisible() {
- final Sdk newProjectJdk = AddModuleWizard.getProjectSdkByDefault(wizardContext);
+ final Sdk newProjectJdk = AbstractProjectWizard.getProjectSdkByDefault(wizardContext);
if (newProjectJdk == null) return true;
final ProjectBuilder projectBuilder = wizardContext.getProjectBuilder();
return projectBuilder != null && !projectBuilder.isSuitableSdk(newProjectJdk);
@@ -127,7 +127,7 @@
@Nullable
@Override
public Sdk getNewProjectSdk(WizardContext wizardContext) {
- return AddModuleWizard.getNewProjectJdk(wizardContext);
+ return AbstractProjectWizard.getNewProjectJdk(wizardContext);
}
@Override
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaResourceRootEditHandlerBase.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaResourceRootEditHandlerBase.java
index 806dd60..3c2b3a2 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaResourceRootEditHandlerBase.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaResourceRootEditHandlerBase.java
@@ -16,10 +16,8 @@
package com.intellij.openapi.roots.ui.configuration;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.JpsDummyElement;
-import org.jetbrains.jps.model.JpsElementFactory;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import javax.swing.*;
@@ -49,10 +47,4 @@
public CustomShortcutSet getMarkRootShortcutSet() {
return null;
}
-
- @NotNull
- @Override
- public JpsDummyElement createDefaultProperties() {
- return JpsElementFactory.getInstance().createDummyElement();
- }
}
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java
index 56ef125b..a0a86e1 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.roots.ui.configuration.actions;
+import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;
import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
import com.intellij.ide.util.newProjectWizard.AddModuleWizardPro;
import com.intellij.ide.util.projectWizard.ModuleBuilder;
@@ -68,7 +69,7 @@
}
@Nullable
- public Module createModuleFromWizard(Project project, @Nullable Object dataFromContext, AddModuleWizard wizard) {
+ public Module createModuleFromWizard(Project project, @Nullable Object dataFromContext, AbstractProjectWizard wizard) {
final ProjectBuilder builder = wizard.getProjectBuilder();
if (builder instanceof ModuleBuilder) {
final ModuleBuilder moduleBuilder = (ModuleBuilder)builder;
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java
index 45e6a53..4d0da3e 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java
@@ -91,9 +91,7 @@
if (myErrorLabel.isShowing()) {
myErrorLabel.setText(errorText);
}
- else {
- myErrorText = errorText;
- }
+ myErrorText = errorText;
myMainPanel.setVisible(true);
myCurrentQuickFixes = quickFixes;
myFixButton.setVisible(!quickFixes.isEmpty());
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java
index 0763407..34bd02b 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java
@@ -30,11 +30,15 @@
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileVisitor;
+import com.intellij.util.IconUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
/**
* @author nik
@@ -108,7 +112,7 @@
private static class AttachUrlJavadocDescriptor extends AttachRootButtonDescriptor {
private AttachUrlJavadocDescriptor() {
- super(JavadocOrderRootType.getInstance(), ProjectBundle.message("module.libraries.javadoc.url.button"));
+ super(JavadocOrderRootType.getInstance(), IconUtil.getAddLinkIcon(), ProjectBundle.message("module.libraries.javadoc.url.button"));
}
@Override
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java
index 3afce2d..f4c6db4 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java
@@ -142,7 +142,7 @@
myTreeBuilder = new LibraryTableTreeBuilder(myTree, (DefaultTreeModel)myTree.getModel(), treeStructure);
myTreePanel.setLayout(new BorderLayout());
- ToolbarDecorator toolbarDecorator = ToolbarDecorator.createDecorator(myTree).disableUpDownActions().disableAddAction()
+ ToolbarDecorator toolbarDecorator = ToolbarDecorator.createDecorator(myTree).disableUpDownActions()
.setRemoveActionName(ProjectBundle.message("library.detach.action"))
.setRemoveAction(new AnActionButtonRunnable() {
@Override
@@ -173,29 +173,43 @@
}
});
+ List<String> actionsOrder = new ArrayList<String>();
+ actionsOrder.add("Add");
+ final List<AttachRootButtonDescriptor> popupItems = new ArrayList<AttachRootButtonDescriptor>();
+ for (AttachRootButtonDescriptor descriptor : myDescriptor.createAttachButtons()) {
+ Icon icon = descriptor.getToolbarIcon();
+ if (icon != null) {
+ AttachItemAction action = new AttachItemAction(descriptor, descriptor.getButtonText(), icon);
+ toolbarDecorator.addExtraAction(AnActionButton.fromAction(action));
+ actionsOrder.add(action.getTemplatePresentation().getText());
+ }
+ else {
+ popupItems.add(descriptor);
+ }
+ }
+ actionsOrder.add("Remove");
+
toolbarDecorator.setAddAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
- final AnAction[] children = getActions();
- if (children.length == 0) return;
- final DefaultActionGroup actions = new DefaultActionGroup(children);
- JBPopupFactory.getInstance().createActionGroupPopup(null, actions,
+ if (popupItems.isEmpty()) {
+ new AttachFilesAction(myDescriptor.getAttachFilesActionName()).actionPerformed(null);
+ return;
+ }
+
+ List<AnAction> actions = new ArrayList<AnAction>();
+ actions.add(new AttachFilesAction(myDescriptor.getAttachFilesActionName()));
+ for (AttachRootButtonDescriptor descriptor : popupItems) {
+ actions.add(new AttachItemAction(descriptor, descriptor.getButtonText(), null));
+ }
+ final DefaultActionGroup group = new DefaultActionGroup(actions);
+ JBPopupFactory.getInstance().createActionGroupPopup(null, group,
DataManager.getInstance().getDataContext(button.getContextComponent()),
JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, true)
.show(button.getPreferredPopupPoint());
}
-
- private AnAction[] getActions() {
- List<AnAction> actions = new ArrayList<AnAction>();
- actions.add(new AttachFilesAction(myDescriptor.getAttachFilesActionName()));
- for (AttachRootButtonDescriptor descriptor : myDescriptor.createAttachButtons()) {
- actions.add(new AttachItemAction(descriptor, descriptor.getButtonText()));
- }
- return actions.toArray(new AnAction[actions.size()]);
- }
});
-
-
+ toolbarDecorator.setButtonComparator(ArrayUtil.toStringArray(actionsOrder));
myTreePanel.add(toolbarDecorator.createPanel(), BorderLayout.CENTER);
ToolbarDecorator.findRemoveButton(myTreePanel).addCustomUpdater(new AnActionButtonUpdater() {
@@ -406,8 +420,9 @@
private class AttachItemAction extends AttachItemActionBase {
private final AttachRootButtonDescriptor myDescriptor;
- protected AttachItemAction(AttachRootButtonDescriptor descriptor, String title) {
+ protected AttachItemAction(AttachRootButtonDescriptor descriptor, String title, final Icon icon) {
super(title);
+ getTemplatePresentation().setIcon(icon);
myDescriptor = descriptor;
}
@@ -472,23 +487,4 @@
public void removeListener(Runnable listener) {
myListeners.remove(listener);
}
-
- @Nullable
- private static Class<?> getElementsClass(Object[] elements) {
- if (elements.length == 0) {
- return null;
- }
- Class<?> cls = null;
- for (Object element : elements) {
- if (cls == null) {
- cls = element.getClass();
- }
- else {
- if (!cls.equals(element.getClass())) {
- return null;
- }
- }
- }
- return cls;
- }
}
diff --git a/java/idea-ui/src/com/intellij/platform/templates/ArchivedTemplatesFactory.java b/java/idea-ui/src/com/intellij/platform/templates/ArchivedTemplatesFactory.java
index 919f952..08c673f 100644
--- a/java/idea-ui/src/com/intellij/platform/templates/ArchivedTemplatesFactory.java
+++ b/java/idea-ui/src/com/intellij/platform/templates/ArchivedTemplatesFactory.java
@@ -132,7 +132,7 @@
for (String child : children) {
if (child.endsWith(ZIP)) {
URL templateUrl = new URL(url.first.toExternalForm() + "/" + child);
- String name = child.substring(0, child.length() - ZIP.length()).replace('_', ' ');
+ String name = getTemplateName(child);
templates.add(new LocalArchivedTemplate(name, templateUrl, url.second));
}
}
@@ -144,6 +144,10 @@
return templates.toArray(new ProjectTemplate[templates.size()]);
}
+ public static String getTemplateName(String child) {
+ return child.substring(0, child.length() - ZIP.length()).replace('_', ' ');
+ }
+
@Override
public int getGroupWeight(String group) {
return CUSTOM_GROUP.equals(group) ? -2 : 0;
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
index 0aeb2bb..cb34a20 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
@@ -30,6 +30,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.JavaVersionService;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.java.LanguageLevel;
@@ -37,6 +38,7 @@
import com.intellij.psi.controlFlow.ControlFlowUtil;
import com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef;
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
+import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTagValue;
@@ -311,16 +313,28 @@
myHolder.add(result);
}
else {
- for (int i = 0; i < lambdaParameters.length; i++) {
- PsiParameter lambdaParameter = lambdaParameters[i];
- if (!TypeConversionUtil.isAssignable(lambdaParameter.getType(),
- GenericsUtil.eliminateWildcards(
- LambdaUtil.getSubstitutor(interfaceMethod, resolveResult)
- .substitute(parameters[i].getType())))) {
- HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(lambdaParameter)
- .descriptionAndTooltip(incompatibleTypesMessage).create();
- myHolder.add(result);
- break;
+ final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult);
+ if (expression.hasFormalParameterTypes()) {
+ for (int i = 0; i < lambdaParameters.length; i++) {
+ if (!Comparing.equal(lambdaParameters[i].getType(), substitutor.substitute(parameters[i].getType()))) {
+ HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
+ .range(lambdaParameters[i])
+ .descriptionAndTooltip(incompatibleTypesMessage)
+ .create();
+ myHolder.add(result);
+ break;
+ }
+ }
+ } else {
+ for (int i = 0; i < lambdaParameters.length; i++) {
+ PsiParameter lambdaParameter = lambdaParameters[i];
+ if (!TypeConversionUtil.isAssignable(lambdaParameter.getType(),
+ GenericsUtil.eliminateWildcards(substitutor.substitute(parameters[i].getType())))) {
+ HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(lambdaParameter)
+ .descriptionAndTooltip(incompatibleTypesMessage).create();
+ myHolder.add(result);
+ break;
+ }
}
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
index 7a747834..4554b15 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
@@ -58,14 +58,13 @@
super(factory);
}
- @Override
- protected DfaMemoryStateImpl createNew() {
- return new ExpressionTypeMemoryState(getFactory());
+ private ExpressionTypeMemoryState(DfaMemoryStateImpl toCopy) {
+ super(toCopy);
}
@Override
public DfaMemoryStateImpl createCopy() {
- final ExpressionTypeMemoryState copy = (ExpressionTypeMemoryState)super.createCopy();
+ final ExpressionTypeMemoryState copy = new ExpressionTypeMemoryState(this);
copy.myStates.putAll(myStates);
return copy;
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
index 58bb1fc..fed5b5b 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
@@ -22,7 +22,6 @@
import com.intellij.codeInspection.dataFlow.instructions.*;
import com.intellij.codeInspection.dataFlow.value.*;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
@@ -100,24 +99,7 @@
return JavaPsiFacade.getElementFactory(manager.getProject()).createTypeByFQClassName(fqn, scope);
}
- private boolean myRecursionStopper = false;
-
private <T extends Instruction> T addInstruction(T i) {
- ProgressManager.checkCanceled();
-
- if (!myRecursionStopper) {
- myRecursionStopper = true;
- try {
- // add extra conditional goto in order to handle possible runtime exceptions that could be caught by finally block
- if (i instanceof BranchingInstruction || i instanceof AssignInstruction || i instanceof MethodCallInstruction) {
- addConditionalRuntimeThrow();
- }
- }
- finally {
- myRecursionStopper = false;
- }
- }
-
myCurrentFlow.addInstruction(i);
return i;
}
@@ -137,7 +119,10 @@
private void finishElement(PsiElement element) {
myCurrentFlow.finishElement(element);
- assert element == myElementStack.pop();
+ PsiElement popped = myElementStack.pop();
+ if (element != popped) {
+ throw new AssertionError("Expected " + element + ", popped " + popped);
+ }
}
@Override
@@ -146,64 +131,60 @@
}
@Override public void visitAssignmentExpression(PsiAssignmentExpression expression) {
+ PsiExpression lExpr = expression.getLExpression();
+ PsiExpression rExpr = expression.getRExpression();
+
startElement(expression);
+ if (rExpr == null) {
+ pushUnknown();
+ finishElement(expression);
+ return;
+ }
- try {
- PsiExpression lExpr = expression.getLExpression();
- PsiExpression rExpr = expression.getRExpression();
+ lExpr.accept(this);
- if (rExpr == null) {
- pushUnknown();
- return;
- }
-
- lExpr.accept(this);
-
- IElementType op = expression.getOperationTokenType();
- PsiType type = expression.getType();
- boolean isBoolean = PsiType.BOOLEAN.equals(type);
- if (op == JavaTokenType.EQ) {
- rExpr.accept(this);
- generateBoxingUnboxingInstructionFor(rExpr, type);
- }
- else if (op == JavaTokenType.ANDEQ) {
- if (isBoolean) {
- generateNonLazyExpression(true, lExpr, rExpr, type);
- }
- else {
- generateDefaultBinOp(lExpr, rExpr, type);
- }
- }
- else if (op == JavaTokenType.OREQ) {
- if (isBoolean) {
- generateNonLazyExpression(false, lExpr, rExpr, type);
- }
- else {
- generateDefaultBinOp(lExpr, rExpr, type);
- }
- }
- else if (op == JavaTokenType.XOREQ) {
- if (isBoolean) {
- generateXorExpression(expression, new PsiExpression[]{lExpr, rExpr}, type);
- }
- else {
- generateDefaultBinOp(lExpr, rExpr, type);
- }
- }
- else if (op == JavaTokenType.PLUSEQ && type != null && type.equalsToText(JAVA_LANG_STRING)) {
- lExpr.accept(this);
- rExpr.accept(this);
- addInstruction(new BinopInstruction(JavaTokenType.PLUS, null, lExpr.getProject()));
+ IElementType op = expression.getOperationTokenType();
+ PsiType type = expression.getType();
+ boolean isBoolean = PsiType.BOOLEAN.equals(type);
+ if (op == JavaTokenType.EQ) {
+ rExpr.accept(this);
+ generateBoxingUnboxingInstructionFor(rExpr, type);
+ }
+ else if (op == JavaTokenType.ANDEQ) {
+ if (isBoolean) {
+ generateNonLazyExpression(true, lExpr, rExpr, type);
}
else {
generateDefaultBinOp(lExpr, rExpr, type);
}
+ }
+ else if (op == JavaTokenType.OREQ) {
+ if (isBoolean) {
+ generateNonLazyExpression(false, lExpr, rExpr, type);
+ }
+ else {
+ generateDefaultBinOp(lExpr, rExpr, type);
+ }
+ }
+ else if (op == JavaTokenType.XOREQ) {
+ if (isBoolean) {
+ generateXorExpression(expression, new PsiExpression[]{lExpr, rExpr}, type);
+ }
+ else {
+ generateDefaultBinOp(lExpr, rExpr, type);
+ }
+ }
+ else if (op == JavaTokenType.PLUSEQ && type != null && type.equalsToText(JAVA_LANG_STRING)) {
+ lExpr.accept(this);
+ rExpr.accept(this);
+ addInstruction(new BinopInstruction(JavaTokenType.PLUS, null, lExpr.getProject()));
+ }
+ else {
+ generateDefaultBinOp(lExpr, rExpr, type);
+ }
- addInstruction(new AssignInstruction(rExpr));
- }
- finally {
- finishElement(expression);
- }
+ addInstruction(new AssignInstruction(rExpr));
+ finishElement(expression);
}
private void generateDefaultBinOp(PsiExpression lExpr, PsiExpression rExpr, final PsiType exprType) {
@@ -658,11 +639,13 @@
if (exception != null) {
exception.accept(this);
+ addConditionalRuntimeThrow();
addInstruction(new DupInstruction());
addInstruction(new PushInstruction(myFactory.getConstFactory().getNull(), null));
addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, statement.getProject()));
ConditionalGotoInstruction gotoInstruction = new ConditionalGotoInstruction(null, true, null);
addInstruction(gotoInstruction);
+ addInstruction(new PushInstruction(myFactory.createTypeValue(myNpe, Nullness.NOT_NULL), null));
addThrowCode(myNpe);
gotoInstruction.setOffset(myCurrentFlow.getInstructionCount());
addThrowCode(exception.getType());
@@ -1008,42 +991,40 @@
public void visitPolyadicExpression(PsiPolyadicExpression expression) {
startElement(expression);
- try {
- DfaValue dfaValue = myFactory.createValue(expression);
- if (dfaValue != null) {
- addInstruction(new PushInstruction(dfaValue, expression));
- return;
- }
- IElementType op = expression.getOperationTokenType();
-
- PsiExpression[] operands = expression.getOperands();
- if (operands.length <= 1) {
- pushUnknown();
- return;
- }
- PsiType type = expression.getType();
- if (op == JavaTokenType.ANDAND) {
- generateAndExpression(operands, type, true);
- }
- else if (op == JavaTokenType.OROR) {
- generateOrExpression(operands, type, true);
- }
- else if (op == JavaTokenType.XOR && PsiType.BOOLEAN.equals(type)) {
- generateXorExpression(expression, operands, type);
- }
- else if (op == JavaTokenType.AND && PsiType.BOOLEAN.equals(type)) {
- generateAndExpression(operands, type, false);
- }
- else if (op == JavaTokenType.OR && PsiType.BOOLEAN.equals(type)) {
- generateOrExpression(operands, type, false);
- }
- else {
- generateOther(expression, op, operands, type);
- }
- }
- finally {
+ DfaValue dfaValue = myFactory.createValue(expression);
+ if (dfaValue != null) {
+ addInstruction(new PushInstruction(dfaValue, expression));
finishElement(expression);
+ return;
}
+ IElementType op = expression.getOperationTokenType();
+
+ PsiExpression[] operands = expression.getOperands();
+ if (operands.length <= 1) {
+ pushUnknown();
+ finishElement(expression);
+ return;
+ }
+ PsiType type = expression.getType();
+ if (op == JavaTokenType.ANDAND) {
+ generateAndExpression(operands, type, true);
+ }
+ else if (op == JavaTokenType.OROR) {
+ generateOrExpression(operands, type, true);
+ }
+ else if (op == JavaTokenType.XOR && PsiType.BOOLEAN.equals(type)) {
+ generateXorExpression(expression, operands, type);
+ }
+ else if (op == JavaTokenType.AND && PsiType.BOOLEAN.equals(type)) {
+ generateAndExpression(operands, type, false);
+ }
+ else if (op == JavaTokenType.OR && PsiType.BOOLEAN.equals(type)) {
+ generateOrExpression(operands, type, false);
+ }
+ else {
+ generateOther(expression, op, operands, type);
+ }
+ finishElement(expression);
}
private void generateOther(PsiPolyadicExpression expression, IElementType op, PsiExpression[] operands, PsiType type) {
@@ -1106,6 +1087,7 @@
addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.UNBOXING, expectedType));
}
else if (TypeConversionUtil.isAssignableFromPrimitiveWrapper(expectedType) && TypeConversionUtil.isPrimitiveAndNotNull(exprType)) {
+ addConditionalRuntimeThrow();
addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.BOXING, expectedType));
}
else if (exprType != expectedType &&
@@ -1275,7 +1257,7 @@
if (type instanceof PsiClassType) {
type = ((PsiClassType)type).rawType();
}
- addInstruction(new PushInstruction(myFactory.getTypeFactory().createTypeValue(type), null));
+ addInstruction(new PushInstruction(myFactory.createTypeValue(type, Nullness.UNKNOWN), null));
addInstruction(new InstanceofInstruction(expression, expression.getProject(), operand, type));
}
else {
@@ -1301,58 +1283,56 @@
}
@Override public void visitMethodCallExpression(PsiMethodCallExpression expression) {
- try {
- startElement(expression);
+ startElement(expression);
- if (handleContracts(expression, getCallContracts(expression))) {
- return;
- }
-
- PsiReferenceExpression methodExpression = expression.getMethodExpression();
- PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
-
- if (qualifierExpression != null) {
- qualifierExpression.accept(this);
- }
- else {
- pushUnknown();
- }
-
- PsiExpression[] expressions = expression.getArgumentList().getExpressions();
- PsiElement method = methodExpression.resolve();
- PsiParameter[] parameters = method instanceof PsiMethod ? ((PsiMethod)method).getParameterList().getParameters() : null;
- for (int i = 0; i < expressions.length; i++) {
- PsiExpression paramExpr = expressions[i];
- paramExpr.accept(this);
- if (parameters != null && i < parameters.length) {
- generateBoxingUnboxingInstructionFor(paramExpr, parameters[i].getType());
- }
- }
-
- addInstruction(new MethodCallInstruction(expression, createChainedVariableValue(expression)));
-
- if (!myCatchStack.isEmpty()) {
- addMethodThrows(expression.resolveMethod());
- }
-
- if (expressions.length == 1 && method instanceof PsiMethod &&
- "equals".equals(((PsiMethod)method).getName()) && parameters.length == 1 &&
- parameters[0].getType().equalsToText(JAVA_LANG_OBJECT) &&
- PsiType.BOOLEAN.equals(((PsiMethod)method).getReturnType())) {
- addInstruction(new PushInstruction(myFactory.getConstFactory().getFalse(), null));
- addInstruction(new SwapInstruction());
- addInstruction(new ConditionalGotoInstruction(getEndOffset(expression), true, null));
-
- addInstruction(new PopInstruction());
- addInstruction(new PushInstruction(myFactory.getConstFactory().getTrue(), null));
-
- expressions[0].accept(this);
- addInstruction(new ApplyNotNullInstruction(expression));
- }
- }
- finally {
+ if (handleContracts(expression, getCallContracts(expression))) {
finishElement(expression);
+ return;
}
+
+ PsiReferenceExpression methodExpression = expression.getMethodExpression();
+ PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
+
+ if (qualifierExpression != null) {
+ qualifierExpression.accept(this);
+ }
+ else {
+ pushUnknown();
+ }
+
+ PsiExpression[] expressions = expression.getArgumentList().getExpressions();
+ PsiElement method = methodExpression.resolve();
+ PsiParameter[] parameters = method instanceof PsiMethod ? ((PsiMethod)method).getParameterList().getParameters() : null;
+ for (int i = 0; i < expressions.length; i++) {
+ PsiExpression paramExpr = expressions[i];
+ paramExpr.accept(this);
+ if (parameters != null && i < parameters.length) {
+ generateBoxingUnboxingInstructionFor(paramExpr, parameters[i].getType());
+ }
+ }
+
+ addConditionalRuntimeThrow();
+ addInstruction(new MethodCallInstruction(expression, createChainedVariableValue(expression)));
+
+ if (!myCatchStack.isEmpty()) {
+ addMethodThrows(expression.resolveMethod());
+ }
+
+ if (expressions.length == 1 && method instanceof PsiMethod &&
+ "equals".equals(((PsiMethod)method).getName()) && parameters.length == 1 &&
+ parameters[0].getType().equalsToText(JAVA_LANG_OBJECT) &&
+ PsiType.BOOLEAN.equals(((PsiMethod)method).getReturnType())) {
+ addInstruction(new PushInstruction(myFactory.getConstFactory().getFalse(), null));
+ addInstruction(new SwapInstruction());
+ addInstruction(new ConditionalGotoInstruction(getEndOffset(expression), true, null));
+
+ addInstruction(new PopInstruction());
+ addInstruction(new PushInstruction(myFactory.getConstFactory().getTrue(), null));
+
+ expressions[0].accept(this);
+ addInstruction(new ApplyNotNullInstruction(expression));
+ }
+ finishElement(expression);
}
private boolean handleContracts(PsiMethodCallExpression expression, List<MethodContract> _contracts) {
@@ -1527,9 +1507,9 @@
if (type == ASSERT_IS_NULL_METHOD || type == ASSERT_IS_NOT_NULL_METHOD) {
constraints[checkedParam] = type == ASSERT_IS_NOT_NULL_METHOD ? ValueConstraint.NULL_VALUE : ValueConstraint.NOT_NULL_VALUE;
return Collections.singletonList(new MethodContract(constraints, ValueConstraint.THROW_EXCEPTION));
- } else if (type == IS_NULL_METHOD || type == IS_NOT_NULL_METHOD) {
- constraints[checkedParam] = type == IS_NULL_METHOD ? ValueConstraint.NOT_NULL_VALUE : ValueConstraint.NULL_VALUE;
- return Collections.singletonList(new MethodContract(constraints, ValueConstraint.FALSE_VALUE));
+ } else if (type == IS_NOT_NULL_METHOD || type == IS_NULL_METHOD) {
+ constraints[checkedParam] = ValueConstraint.NULL_VALUE;
+ return Collections.singletonList(new MethodContract(constraints, type == IS_NULL_METHOD ? ValueConstraint.TRUE_VALUE : ValueConstraint.FALSE_VALUE));
} else { //assertTrue or assertFalse
constraints[checkedParam] = type == ASSERT_FALSE_METHOD ? ValueConstraint.TRUE_VALUE : ValueConstraint.FALSE_VALUE;
return Collections.singletonList(new MethodContract(constraints, ValueConstraint.THROW_EXCEPTION));
@@ -1594,7 +1574,7 @@
final DfaValue dfaValue;
if (type instanceof PsiClassType) {
- dfaValue = myFactory.getTypeFactory().createTypeValue(type);
+ dfaValue = myFactory.createTypeValue(type, Nullness.UNKNOWN);
}
else {
dfaValue = null;
@@ -1623,6 +1603,7 @@
addInstruction(new PopInstruction());
}
}
+ addConditionalRuntimeThrow();
addInstruction(new MethodCallInstruction(expression, null));
}
else {
@@ -1640,6 +1621,7 @@
}
}
+ addConditionalRuntimeThrow();
addInstruction(new MethodCallInstruction(expression, null));
if (!myCatchStack.isEmpty()) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java
index bbac522..b462090 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java
@@ -33,8 +33,10 @@
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.dataFlow.instructions.*;
import com.intellij.codeInspection.dataFlow.value.DfaConstValue;
+import com.intellij.codeInspection.dataFlow.value.DfaValue;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
@@ -47,6 +49,7 @@
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -145,7 +148,7 @@
PsiClass containingClass = PsiTreeUtil.getParentOfType(scope, PsiClass.class);
if (containingClass != null && PsiUtil.isLocalOrAnonymousClass(containingClass)) return;
- final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner(SUGGEST_NULLABLE_ANNOTATIONS) {
+ final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner() {
@Override
protected boolean shouldCheckTimeLimit() {
if (!onTheFly) return false;
@@ -159,7 +162,7 @@
ProblemsHolder holder,
StandardDataFlowRunner dfaRunner,
Collection<DfaMemoryState> initialStates) {
- final StandardInstructionVisitor visitor = new DataFlowInstructionVisitor(dfaRunner);
+ final DataFlowInstructionVisitor visitor = new DataFlowInstructionVisitor(dfaRunner);
final RunnerResult rc = dfaRunner.analyzeMethod(scope, visitor, IGNORE_ASSERT_STATEMENTS, initialStates);
if (rc == RunnerResult.OK) {
createDescription(dfaRunner, holder, visitor);
@@ -213,7 +216,7 @@
protected void addSurroundWithIfFix(PsiExpression qualifier, List<LocalQuickFix> fixes) {
}
- private void createDescription(StandardDataFlowRunner runner, ProblemsHolder holder, StandardInstructionVisitor visitor) {
+ private void createDescription(StandardDataFlowRunner runner, ProblemsHolder holder, DataFlowInstructionVisitor visitor) {
Pair<Set<Instruction>, Set<Instruction>> constConditions = runner.getConstConditionalExpressions();
Set<Instruction> trueSet = constConditions.getFirst();
Set<Instruction> falseSet = constConditions.getSecond();
@@ -221,28 +224,25 @@
ArrayList<Instruction> allProblems = new ArrayList<Instruction>();
allProblems.addAll(trueSet);
allProblems.addAll(falseSet);
- allProblems.addAll(runner.getNPEInstructions());
allProblems.addAll(runner.getCCEInstructions());
allProblems.addAll(StandardDataFlowRunner.getRedundantInstanceofs(runner, visitor));
- Collections.sort(allProblems, new Comparator<Instruction>() {
- @Override
- public int compare(Instruction i1, Instruction i2) {
- return i1.getIndex() - i2.getIndex();
- }
- });
-
HashSet<PsiElement> reportedAnchors = new HashSet<PsiElement>();
+ for (PsiElement element : visitor.getProblems(NullabilityProblem.callNPE)) {
+ if (reportedAnchors.add(element)) {
+ reportCallMayProduceNpe(holder, (PsiMethodCallExpression)element);
+ }
+ }
+ for (PsiElement element : visitor.getProblems(NullabilityProblem.fieldAccessNPE)) {
+ if (reportedAnchors.add(element)) {
+ PsiElement parent = element.getParent();
+ PsiElement fieldAccess = parent instanceof PsiArrayAccessExpression || parent instanceof PsiReferenceExpression ? parent : element;
+ reportFieldAccessMayProduceNpe(holder, element, (PsiExpression)fieldAccess);
+ }
+ }
for (Instruction instruction : allProblems) {
- if (instruction instanceof MethodCallInstruction) {
- reportCallMayProduceNpe(holder, (MethodCallInstruction)instruction, reportedAnchors);
- }
- else if (instruction instanceof FieldReferenceInstruction &&
- reportedAnchors.add(((FieldReferenceInstruction)instruction).getElementToAssert())) {
- reportFieldAccessMayProduceNpe(holder, (FieldReferenceInstruction)instruction);
- }
- else if (instruction instanceof TypeCastInstruction &&
+ if (instruction instanceof TypeCastInstruction &&
reportedAnchors.add(((TypeCastInstruction)instruction).getCastExpression().getCastType())) {
reportCastMayFail(holder, (TypeCastInstruction)instruction);
}
@@ -251,11 +251,15 @@
}
}
- reportNullableArguments(runner, holder, reportedAnchors);
- reportNullableAssignments(runner, holder, reportedAnchors);
- reportUnboxedNullables(runner, holder, reportedAnchors);
- reportNullableReturns(runner, holder, reportedAnchors);
- reportNullableArgumentsPassedToNonAnnotated(runner, holder, reportedAnchors);
+ reportNullableArguments(visitor, holder, reportedAnchors);
+ reportNullableAssignments(visitor, holder, reportedAnchors);
+ reportUnboxedNullables(visitor, holder, reportedAnchors);
+ if (!runner.isInNullableMethod() && runner.isInMethod() && (runner.isInNotNullMethod() || SUGGEST_NULLABLE_ANNOTATIONS)) {
+ reportNullableReturns(runner, visitor, holder, reportedAnchors);
+ }
+ if (SUGGEST_NULLABLE_ANNOTATIONS) {
+ reportNullableArgumentsPassedToNonAnnotated(visitor, holder, reportedAnchors);
+ }
if (REPORT_CONSTANT_REFERENCE_VALUES) {
reportConstantReferenceValues(holder, visitor, reportedAnchors);
@@ -317,15 +321,14 @@
return value instanceof String ? "\"" + StringUtil.escapeStringCharacters((String)value) + "\"" : String.valueOf(value);
}
- private void reportNullableArgumentsPassedToNonAnnotated(StandardDataFlowRunner runner, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
- Set<PsiExpression> exprs = runner.getNullableArgumentsPassedToNonAnnotatedParam();
- for (PsiExpression expr : exprs) {
+ private void reportNullableArgumentsPassedToNonAnnotated(DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
+ for (PsiElement expr : visitor.getProblems(NullabilityProblem.passingNullableArgumentToNonAnnotatedParameter)) {
if (reportedAnchors.contains(expr)) continue;
final String text = isNullLiteralExpression(expr)
? "Passing <code>null</code> argument to non annotated parameter"
: "Argument <code>#ref</code> #loc might be null but passed to non annotated parameter";
- LocalQuickFix[] fixes = createNPEFixes(expr, expr);
+ LocalQuickFix[] fixes = createNPEFixes((PsiExpression)expr, (PsiExpression)expr);
final PsiElement parent = expr.getParent();
if (parent instanceof PsiExpressionList) {
final int idx = ArrayUtilRt.find(((PsiExpressionList)parent).getExpressions(), expr);
@@ -349,22 +352,15 @@
}
}
- private void reportCallMayProduceNpe(ProblemsHolder holder, MethodCallInstruction mcInstruction, Set<PsiElement> reportedAnchors) {
- if (mcInstruction.getCallExpression() instanceof PsiMethodCallExpression) {
- PsiMethodCallExpression callExpression = (PsiMethodCallExpression)mcInstruction.getCallExpression();
- if (!reportedAnchors.add(callExpression)) return;
+ private void reportCallMayProduceNpe(ProblemsHolder holder, PsiMethodCallExpression callExpression) {
+ LocalQuickFix[] fix = createNPEFixes(callExpression.getMethodExpression().getQualifierExpression(), callExpression);
- LocalQuickFix[] fix = createNPEFixes(callExpression.getMethodExpression().getQualifierExpression(), callExpression);
-
- holder.registerProblem(callExpression,
- InspectionsBundle.message("dataflow.message.npe.method.invocation"),
- fix);
- }
+ holder.registerProblem(callExpression,
+ InspectionsBundle.message("dataflow.message.npe.method.invocation"),
+ fix);
}
- private void reportFieldAccessMayProduceNpe(ProblemsHolder holder, FieldReferenceInstruction frInstruction) {
- PsiElement elementToAssert = frInstruction.getElementToAssert();
- PsiExpression expression = frInstruction.getExpression();
+ private void reportFieldAccessMayProduceNpe(ProblemsHolder holder, PsiElement elementToAssert, PsiExpression expression) {
if (expression instanceof PsiArrayAccessExpression) {
LocalQuickFix[] fix = createNPEFixes((PsiExpression)elementToAssert, expression);
holder.registerProblem(expression,
@@ -382,8 +378,11 @@
private static void reportCastMayFail(ProblemsHolder holder, TypeCastInstruction instruction) {
PsiTypeCastExpression typeCast = instruction.getCastExpression();
- holder.registerProblem(typeCast.getCastType(),
- InspectionsBundle.message("dataflow.message.cce", typeCast.getOperand().getText()));
+ PsiExpression operand = typeCast.getOperand();
+ PsiTypeElement castType = typeCast.getCastType();
+ assert castType != null;
+ assert operand != null;
+ holder.registerProblem(castType, InspectionsBundle.message("dataflow.message.cce", operand.getText()));
}
private void handleBranchingInstruction(ProblemsHolder holder,
@@ -413,7 +412,7 @@
}
else if (psiAnchor != null && !reportedAnchors.contains(psiAnchor) && !isCompileConstantInIfCondition(psiAnchor)) {
boolean evaluatesToTrue = trueSet.contains(instruction);
- if (onTheLeftSideOfConditionalAssignemnt(psiAnchor)) {
+ if (onTheLeftSideOfConditionalAssignment(psiAnchor)) {
holder.registerProblem(
psiAnchor,
InspectionsBundle.message("dataflow.message.pointless.assignment.expression", Boolean.toString(evaluatesToTrue)),
@@ -436,21 +435,20 @@
visitor.silenceConstantCondition(psiAnchor);
}
- private void reportNullableArguments(StandardDataFlowRunner runner, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
- Set<PsiExpression> exprs = runner.getNullableArguments();
- for (PsiExpression expr : exprs) {
+ private void reportNullableArguments(DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
+ for (PsiElement expr : visitor.getProblems(NullabilityProblem.passingNullableToNotNullParameter)) {
if (!reportedAnchors.add(expr)) continue;
final String text = isNullLiteralExpression(expr)
? InspectionsBundle.message("dataflow.message.passing.null.argument")
: InspectionsBundle.message("dataflow.message.passing.nullable.argument");
- LocalQuickFix[] fixes = createNPEFixes(expr, expr);
+ LocalQuickFix[] fixes = createNPEFixes((PsiExpression)expr, (PsiExpression)expr);
holder.registerProblem(expr, text, fixes);
}
}
- private static void reportNullableAssignments(StandardDataFlowRunner runner, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
- for (PsiExpression expr : runner.getNullableAssignments()) {
+ private static void reportNullableAssignments(DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
+ for (PsiElement expr : visitor.getProblems(NullabilityProblem.assigningToNotNull)) {
if (!reportedAnchors.add(expr)) continue;
final String text = isNullLiteralExpression(expr)
@@ -460,16 +458,16 @@
}
}
- private static void reportUnboxedNullables(StandardDataFlowRunner runner, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
- for (PsiExpression expr : runner.getUnboxedNullables()) {
+ private static void reportUnboxedNullables(DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
+ for (PsiElement expr : visitor.getProblems(NullabilityProblem.unboxingNullable)) {
if (!reportedAnchors.add(expr)) continue;
holder.registerProblem(expr, InspectionsBundle.message("dataflow.message.unboxing"));
}
}
- private static void reportNullableReturns(StandardDataFlowRunner runner, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
- for (PsiReturnStatement statement : runner.getNullableReturns()) {
- final PsiExpression expr = statement.getReturnValue();
+ private static void reportNullableReturns(StandardDataFlowRunner runner, DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
+ for (PsiElement statement : visitor.getProblems(NullabilityProblem.nullableReturn)) {
+ final PsiExpression expr = ((PsiReturnStatement)statement).getReturnValue();
assert expr != null;
if (!reportedAnchors.add(expr)) continue;
@@ -547,7 +545,7 @@
return parent instanceof PsiIfStatement && ((PsiIfStatement)parent).getCondition() == element;
}
- private static boolean isNullLiteralExpression(PsiExpression expr) {
+ private static boolean isNullLiteralExpression(PsiElement expr) {
if (expr instanceof PsiLiteralExpression) {
final PsiLiteralExpression literalExpression = (PsiLiteralExpression)expr;
return PsiType.NULL.equals(literalExpression.getType());
@@ -555,7 +553,7 @@
return false;
}
- private static boolean onTheLeftSideOfConditionalAssignemnt(final PsiElement psiAnchor) {
+ private static boolean onTheLeftSideOfConditionalAssignment(final PsiElement psiAnchor) {
final PsiElement parent = psiAnchor.getParent();
if (parent instanceof PsiAssignmentExpression) {
final PsiAssignmentExpression expression = (PsiAssignmentExpression)parent;
@@ -699,45 +697,55 @@
private static class DataFlowInstructionVisitor extends StandardInstructionVisitor {
private final StandardDataFlowRunner myRunner;
+ private final MultiMap<NullabilityProblem, PsiElement> myProblems = new MultiMap<NullabilityProblem, PsiElement>();
+ private final Map<Pair<NullabilityProblem, PsiElement>, StateInfo> myStateInfos = ContainerUtil.newHashMap();
private DataFlowInstructionVisitor(StandardDataFlowRunner runner) {
myRunner = runner;
}
@Override
- protected void onAssigningToNotNullableVariable(AssignInstruction instruction) {
- myRunner.onAssigningToNotNullableVariable(instruction.getRExpression());
- }
-
- @Override
- protected void onNullableReturn(CheckReturnValueInstruction instruction) {
- myRunner.onNullableReturn(instruction.getReturn());
- }
-
- @Override
protected void onInstructionProducesCCE(TypeCastInstruction instruction) {
myRunner.onInstructionProducesCCE(instruction);
}
-
- @Override
- protected void onInstructionProducesNPE(Instruction instruction) {
- if (instruction instanceof MethodCallInstruction &&
- ((MethodCallInstruction)instruction).getMethodType() == MethodCallInstruction.MethodType.UNBOXING) {
- myRunner.onUnboxingNullable(((MethodCallInstruction)instruction).getContext());
- }
- else {
- myRunner.onInstructionProducesNPE(instruction);
- }
+
+ Collection<PsiElement> getProblems(final NullabilityProblem kind) {
+ return ContainerUtil.filter(myProblems.get(kind), new Condition<PsiElement>() {
+ @Override
+ public boolean value(PsiElement psiElement) {
+ StateInfo info = myStateInfos.get(Pair.create(kind, psiElement));
+ // non-ephemeral NPE should be reported
+ // ephemeral NPE should also be reported if only ephemeral states have reached a particular problematic instruction
+ // (e.g. if it's inside "if (var == null)" check after contract method invocation
+ return info.normalNpe || info.ephemeralNpe && !info.normalOk;
+ }
+ });
}
@Override
- protected void onPassingNullParameter(PsiExpression arg) {
- myRunner.onPassingNullParameter(arg);
+ protected boolean checkNotNullable(DfaMemoryState state, DfaValue value, NullabilityProblem problem, PsiElement anchor) {
+ boolean ok = super.checkNotNullable(state, value, problem, anchor);
+ if (!ok && anchor != null) {
+ myProblems.putValue(problem, anchor);
+ }
+ Pair<NullabilityProblem, PsiElement> key = Pair.create(problem, anchor);
+ StateInfo info = myStateInfos.get(key);
+ if (info == null) {
+ myStateInfos.put(key, info = new StateInfo());
+ }
+ if (state.isEphemeral() && !ok) {
+ info.ephemeralNpe = true;
+ } else if (!state.isEphemeral()) {
+ if (ok) info.normalOk = true;
+ else info.normalNpe = true;
+ }
+ return ok;
}
-
- @Override
- protected void onPassingNullParameterToNonAnnotated(DataFlowRunner runner, PsiExpression arg) {
- myRunner.onPassingNullParameterToNonAnnotated(arg);
+
+ private static class StateInfo {
+ boolean ephemeralNpe;
+ boolean normalNpe;
+ boolean normalOk;
}
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
index 298b51b..38c242bc 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
@@ -24,10 +24,7 @@
*/
package com.intellij.codeInspection.dataFlow;
-import com.intellij.codeInspection.dataFlow.instructions.BranchingInstruction;
-import com.intellij.codeInspection.dataFlow.instructions.EmptyInstruction;
-import com.intellij.codeInspection.dataFlow.instructions.Instruction;
-import com.intellij.codeInspection.dataFlow.instructions.MethodCallInstruction;
+import com.intellij.codeInspection.dataFlow.instructions.*;
import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
import com.intellij.openapi.application.ApplicationManager;
@@ -38,7 +35,9 @@
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
+import com.intellij.util.containers.MultiMapBasedOnSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -108,6 +107,17 @@
myInstructions = flow.getInstructions();
myFields = flow.getFields();
myNestedClosures.clear();
+
+ Set<Instruction> joinInstructions = ContainerUtil.newHashSet();
+ for (Instruction instruction : myInstructions) {
+ if (instruction instanceof GotoInstruction) {
+ joinInstructions.add(myInstructions[((GotoInstruction)instruction).getOffset()]);
+ } else if (instruction instanceof ConditionalGotoInstruction) {
+ joinInstructions.add(myInstructions[((ConditionalGotoInstruction)instruction).getOffset()]);
+ } else if (instruction instanceof GosubInstruction) {
+ joinInstructions.add(myInstructions[((GosubInstruction)instruction).getSubprogramOffset()]);
+ }
+ }
if (LOG.isDebugEnabled()) {
LOG.debug("Analyzing code block: " + psiBlock.getText());
@@ -123,47 +133,61 @@
return RunnerResult.TOO_COMPLEX;
}
- final ArrayList<DfaInstructionState> queue = new ArrayList<DfaInstructionState>();
+ final StateQueue queue = new StateQueue();
for (final DfaMemoryState initialState : initialStates) {
- queue.add(new DfaInstructionState(myInstructions[0], initialState));
+ queue.offer(new DfaInstructionState(myInstructions[0], initialState));
}
+ MultiMapBasedOnSet<BranchingInstruction, DfaMemoryState> processedStates = new MultiMapBasedOnSet<BranchingInstruction, DfaMemoryState>();
+ MultiMapBasedOnSet<BranchingInstruction, DfaMemoryState> incomingStates = new MultiMapBasedOnSet<BranchingInstruction, DfaMemoryState>();
+
WorkingTimeMeasurer measurer = new WorkingTimeMeasurer(shouldCheckTimeLimit() ? ourTimeLimit : ourTimeLimit * 42);
int count = 0;
while (!queue.isEmpty()) {
- if (count % 64 == 0 && measurer.isTimeOver()) {
- LOG.debug("Too complex because the analysis took too long");
- psiBlock.putUserData(TOO_EXPENSIVE_HASH, psiBlock.getText().hashCode());
- return RunnerResult.TOO_COMPLEX;
- }
- ProgressManager.checkCanceled();
+ for (DfaInstructionState instructionState : queue.getNextInstructionStates(joinInstructions)) {
+ if (count++ % 1024 == 0 && measurer.isTimeOver()) {
+ LOG.debug("Too complex because the analysis took too long");
+ psiBlock.putUserData(TOO_EXPENSIVE_HASH, psiBlock.getText().hashCode());
+ return RunnerResult.TOO_COMPLEX;
+ }
+ ProgressManager.checkCanceled();
- DfaInstructionState instructionState = queue.remove(0);
- if (LOG.isDebugEnabled()) {
- LOG.debug(instructionState.toString());
- }
- //System.out.println(instructionState.toString());
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(instructionState.toString());
+ }
+ //System.out.println(instructionState.toString());
- Instruction instruction = instructionState.getInstruction();
- long distance = instructionState.getDistanceFromStart();
+ Instruction instruction = instructionState.getInstruction();
- if (instruction instanceof BranchingInstruction) {
- if (!instruction.setMemoryStateProcessed(instructionState.getMemoryState().createCopy())) {
- LOG.debug("Too complex because too many different possible states");
- return RunnerResult.TOO_COMPLEX; // Too complex :(
+ if (instruction instanceof BranchingInstruction) {
+ BranchingInstruction branching = (BranchingInstruction)instruction;
+ if (processedStates.get(branching).contains(instructionState.getMemoryState())) {
+ continue;
+ }
+ if (processedStates.get(branching).size() > MAX_STATES_PER_BRANCH) {
+ LOG.debug("Too complex because too many different possible states");
+ return RunnerResult.TOO_COMPLEX; // Too complex :(
+ }
+ processedStates.putValue(branching, instructionState.getMemoryState().createCopy());
+ }
+
+ DfaInstructionState[] after = acceptInstruction(visitor, instructionState);
+ for (DfaInstructionState state : after) {
+ Instruction nextInstruction = state.getInstruction();
+ if (nextInstruction.getIndex() >= endOffset) {
+ continue;
+ }
+ if (nextInstruction instanceof BranchingInstruction) {
+ BranchingInstruction branching = (BranchingInstruction)nextInstruction;
+ if (processedStates.get(branching).contains(state.getMemoryState()) ||
+ incomingStates.get(branching).contains(state.getMemoryState())) {
+ continue;
+ }
+ incomingStates.putValue(branching, state.getMemoryState().createCopy());
+ }
+ queue.offer(state);
}
}
-
- DfaInstructionState[] after = acceptInstruction(visitor, instructionState);
- for (DfaInstructionState state : after) {
- Instruction nextInstruction = state.getInstruction();
- if ((!(nextInstruction instanceof BranchingInstruction) || !nextInstruction.isMemoryStateProcessed(state.getMemoryState())) && instruction.getIndex() < endOffset) {
- state.setDistanceFromStart(distance + 1);
- queue.add(state);
- }
- }
-
- count++;
}
psiBlock.putUserData(TOO_EXPENSIVE_HASH, null);
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java
index 87d8b8a..1683807 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java
@@ -25,23 +25,26 @@
package com.intellij.codeInspection.dataFlow;
import com.intellij.codeInspection.dataFlow.instructions.Instruction;
+import com.intellij.openapi.util.Pair;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
-public class DfaInstructionState {
+import java.util.Collections;
+import java.util.List;
+import java.util.PriorityQueue;
+import java.util.Set;
+
+public class DfaInstructionState implements Comparable<DfaInstructionState> {
public static final DfaInstructionState[] EMPTY_ARRAY = new DfaInstructionState[0];
private final DfaMemoryState myBeforeMemoryState;
private final Instruction myInstruction;
- private long myDistanceFromStart = 0;
public DfaInstructionState(@NotNull Instruction myInstruction, @NotNull DfaMemoryState myBeforeMemoryState) {
this.myBeforeMemoryState = myBeforeMemoryState;
this.myInstruction = myInstruction;
}
- public long getDistanceFromStart() { return myDistanceFromStart; }
-
- public void setDistanceFromStart(long distanceFromStart) { myDistanceFromStart = distanceFromStart; }
-
@NotNull
public Instruction getInstruction() {
return myInstruction;
@@ -55,4 +58,58 @@
public String toString() {
return getInstruction().getIndex() + " " + getInstruction() + ": " + getMemoryState().toString();
}
+
+ @Override
+ public int compareTo(@NotNull DfaInstructionState o) {
+ return myInstruction.getIndex() - o.myInstruction.getIndex();
+ }
}
+
+class StateQueue {
+ private final PriorityQueue<DfaInstructionState> myQueue = new PriorityQueue<DfaInstructionState>();
+ private final Set<Pair<Instruction, DfaMemoryState>> mySet = ContainerUtil.newHashSet();
+
+ void offer(DfaInstructionState state) {
+ if (mySet.add(Pair.create(state.getInstruction(), state.getMemoryState()))) {
+ myQueue.offer(state);
+ }
+ }
+
+ boolean isEmpty() {
+ return myQueue.isEmpty();
+ }
+
+ List<DfaInstructionState> getNextInstructionStates(Set<Instruction> joinInstructions) {
+ DfaInstructionState state = myQueue.poll();
+ final Instruction instruction = state.getInstruction();
+ mySet.remove(Pair.create(instruction, state.getMemoryState()));
+
+ DfaInstructionState next = myQueue.peek();
+ if (next == null || next.compareTo(state) != 0) return Collections.singletonList(state);
+
+ List<DfaMemoryStateImpl> memoryStates = ContainerUtil.newArrayList();
+ memoryStates.add((DfaMemoryStateImpl)state.getMemoryState());
+ while (!myQueue.isEmpty() && myQueue.peek().compareTo(state) == 0) {
+ DfaMemoryState anotherState = myQueue.poll().getMemoryState();
+ mySet.remove(Pair.create(instruction, anotherState));
+ memoryStates.add((DfaMemoryStateImpl)anotherState);
+ }
+
+ if (memoryStates.size() > 1 && joinInstructions.contains(instruction)) {
+ while (true) {
+ List<DfaMemoryStateImpl> nextStates = new StateMerger(memoryStates).merge();
+ if (nextStates == null) break;
+ memoryStates = nextStates;
+ }
+ }
+
+ return ContainerUtil.map(memoryStates, new Function<DfaMemoryStateImpl, DfaInstructionState>() {
+ @Override
+ public DfaInstructionState fun(DfaMemoryStateImpl state) {
+ return new DfaInstructionState(instruction, state);
+ }
+ });
+ }
+
+
+}
\ No newline at end of file
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
index 8309670..106267af 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
@@ -59,4 +59,13 @@
@Nullable
DfaConstValue getConstantValue(DfaVariableValue value);
+
+ /**
+ * Ephemeral means a state that was created when considering a method contract and checking if one of its arguments is null.
+ * With explicit null check, that would result in any non-annotated variable being treated as nullable and producing possible NPE warnings later.
+ * With contracts, we don't want this. So the state where this variable is null is marked ephemeral and no NPE warnings are issued for such states.
+ */
+ void markEphemeral();
+
+ boolean isEphemeral();
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
index d77a0f9..f5430d5 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
@@ -26,6 +26,7 @@
import com.intellij.codeInspection.dataFlow.value.*;
import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.util.UnorderedPair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.TypeConversionUtil;
@@ -41,43 +42,50 @@
public class DfaMemoryStateImpl implements DfaMemoryState {
private final DfaValueFactory myFactory;
- private final List<SortedIntSet> myEqClasses = new ArrayList<SortedIntSet>();
- private final Stack<DfaValue> myStack = new Stack<DfaValue>();
- private TIntStack myOffsetStack = new TIntStack(1);
- private final TLongHashSet myDistinctClasses = new TLongHashSet();
- private final THashMap<DfaVariableValue,DfaVariableState> myVariableStates = new THashMap<DfaVariableValue, DfaVariableState>();
- private final THashSet<DfaVariableValue> myUnknownVariables = new THashSet<DfaVariableValue>();
+ private final List<EqClass> myEqClasses;
+ private final Stack<DfaValue> myStack;
+ private TIntStack myOffsetStack;
+ private final TLongHashSet myDistinctClasses;
+ private final Map<DfaVariableValue,DfaVariableState> myVariableStates;
+ private final Map<DfaVariableValue,DfaVariableState> myDefaultVariableStates;
+ private final Set<DfaVariableValue> myUnknownVariables;
+ private boolean myEphemeral;
public DfaMemoryStateImpl(final DfaValueFactory factory) {
myFactory = factory;
+ myDefaultVariableStates = ContainerUtil.newTroveMap();
+ myEqClasses = ContainerUtil.newArrayList();
+ myUnknownVariables = ContainerUtil.newTroveSet();
+ myVariableStates = ContainerUtil.newTroveMap();
+ myDistinctClasses = new TLongHashSet();
+ myOffsetStack = new TIntStack();
+ myStack = new Stack<DfaValue>();
+ }
+
+ protected DfaMemoryStateImpl(DfaMemoryStateImpl toCopy) {
+ myFactory = toCopy.myFactory;
+ myEphemeral = toCopy.myEphemeral;
+ myDefaultVariableStates = toCopy.myDefaultVariableStates; // shared between all states
+
+ myStack = new Stack<DfaValue>(toCopy.myStack);
+ myDistinctClasses = new TLongHashSet(toCopy.myDistinctClasses.toArray());
+ myUnknownVariables = new THashSet<DfaVariableValue>(toCopy.myUnknownVariables);
+ myOffsetStack = toCopy.myOffsetStack;
+
+ myEqClasses = ContainerUtil.newArrayList(toCopy.myEqClasses);
+ myVariableStates = new THashMap<DfaVariableValue, DfaVariableState>(toCopy.myVariableStates);
+
+ myCachedDistinctClassPairs = toCopy.myCachedDistinctClassPairs;
+ myCachedNonTrivialEqClasses = toCopy.myCachedNonTrivialEqClasses;
}
public DfaValueFactory getFactory() {
return myFactory;
}
- protected DfaMemoryStateImpl createNew() {
- return new DfaMemoryStateImpl(myFactory);
- }
-
@Override
public DfaMemoryStateImpl createCopy() {
- DfaMemoryStateImpl newState = createNew();
-
- newState.myStack.addAll(myStack);
- newState.myDistinctClasses.addAll(myDistinctClasses.toArray());
- newState.myUnknownVariables.addAll(myUnknownVariables);
- newState.myOffsetStack = new TIntStack(myOffsetStack);
-
- for (int i = 0; i < myEqClasses.size(); i++) {
- SortedIntSet aClass = myEqClasses.get(i);
- newState.myEqClasses.add(aClass != null ? new SortedIntSet(aClass.toNativeArray()) : null);
- }
-
- for (DfaVariableValue dfaVariableValue : myVariableStates.keySet()) {
- newState.myVariableStates.put(dfaVariableValue, myVariableStates.get(dfaVariableValue).clone());
- }
- return newState;
+ return new DfaMemoryStateImpl(this);
}
public boolean equals(Object obj) {
@@ -85,84 +93,70 @@
if (!(obj instanceof DfaMemoryStateImpl)) return false;
DfaMemoryStateImpl that = (DfaMemoryStateImpl)obj;
- if (myDistinctClasses.size() != that.myDistinctClasses.size()) return false;
- if (myStack.size() != that.myStack.size()) return false;
- if (myOffsetStack.size() != that.myOffsetStack.size()) return false;
- if (myVariableStates.size() != that.myVariableStates.size()) return false;
- if (myUnknownVariables.size() != that.myUnknownVariables.size()) return false;
+ return equalsSuperficially(that) && myUnknownVariables.equals(that.myUnknownVariables) && equalsByRelations(that);
+ }
- if (!myStack.equals(that.myStack)) return false;
- if (!myOffsetStack.equals(that.myOffsetStack)) return false;
- if (!myVariableStates.equals(that.myVariableStates)) return false;
- if (!myUnknownVariables.equals(that.myUnknownVariables)) return false;
-
+ boolean equalsSuperficially(DfaMemoryStateImpl other) {
+ return myEphemeral == other.myEphemeral && myStack.equals(other.myStack) && myOffsetStack.equals(other.myOffsetStack);
+ }
+
+ boolean equalsByRelations(DfaMemoryStateImpl that) {
+ if (myDistinctClasses.size() != that.myDistinctClasses.size()) return false;
if (!getNonTrivialEqClasses().equals(that.getNonTrivialEqClasses())) return false;
if (!getDistinctClassPairs().equals(that.getDistinctClassPairs())) return false;
-
+ if (!myVariableStates.equals(that.myVariableStates)) return false;
return true;
}
- private Set<Set<SortedIntSet>> getDistinctClassPairs() {
- Set<Set<SortedIntSet>> result = ContainerUtil.newHashSet();
+ private Set<UnorderedPair<EqClass>> myCachedDistinctClassPairs;
+ Set<UnorderedPair<EqClass>> getDistinctClassPairs() {
+ if (myCachedDistinctClassPairs != null) return myCachedDistinctClassPairs;
+
+ Set<UnorderedPair<EqClass>> result = ContainerUtil.newHashSet();
for (long encodedPair : myDistinctClasses.toArray()) {
- THashSet<SortedIntSet> pair = new THashSet<SortedIntSet>(2);
- pair.add(myEqClasses.get(low(encodedPair)));
- pair.add(myEqClasses.get(high(encodedPair)));
- result.add(pair);
+ result.add(new UnorderedPair<EqClass>(myEqClasses.get(low(encodedPair)), myEqClasses.get(high(encodedPair))));
}
- return result;
+ return myCachedDistinctClassPairs = result;
}
- private Set<SortedIntSet> getNonTrivialEqClasses() {
- Set<SortedIntSet> result = ContainerUtil.newHashSet();
- for (SortedIntSet eqClass : myEqClasses) {
+ private Set<EqClass> myCachedNonTrivialEqClasses;
+ Set<EqClass> getNonTrivialEqClasses() {
+ if (myCachedNonTrivialEqClasses != null) return myCachedNonTrivialEqClasses;
+
+ Set<EqClass> result = ContainerUtil.newHashSet();
+ for (EqClass eqClass : myEqClasses) {
if (eqClass != null && eqClass.size() > 1) {
result.add(eqClass);
}
}
- return result;
+ return myCachedNonTrivialEqClasses = result;
}
public int hashCode() {
- return 0;
- //return ((myEqClasses.hashCode() * 31 + myStack.hashCode()) * 31 + myVariableStates.hashCode()) * 31 + myUnknownVariables.hashCode();
- }
-
- private void appendClass(StringBuilder buf, @Nullable SortedIntSet aClass) {
- if (aClass == null) return;
-
- buf.append("(");
-
- for (int i = 0; i < aClass.size(); i++) {
- if (i > 0) buf.append(", ");
- int value = aClass.get(i);
- DfaValue dfaValue = myFactory.getValue(value);
- buf.append(dfaValue);
- }
- buf.append(")");
+ return (((getNonTrivialEqClasses().hashCode() * 31 +
+ getDistinctClassPairs().hashCode()) * 31 +
+ myStack.hashCode()) * 31 +
+ myUnknownVariables.hashCode()) * 31 +
+ myVariableStates.hashCode();
}
@SuppressWarnings({"HardCodedStringLiteral"})
public String toString() {
StringBuilder result = new StringBuilder();
result.append('<');
+ if (myEphemeral) {
+ result.append("ephemeral, ");
+ }
- for (SortedIntSet set : getNonTrivialEqClasses()) {
- appendClass(result, set);
+ for (EqClass set : getNonTrivialEqClasses()) {
+ result.append(set);
}
if (!myDistinctClasses.isEmpty()) {
result.append("\n distincts: ");
List<String> distincts = new ArrayList<String>();
- for (Set<SortedIntSet> pair : getDistinctClassPairs()) {
- ArrayList<SortedIntSet> list = new ArrayList<SortedIntSet>(pair);
- StringBuilder one = new StringBuilder();
- one.append("{");
- appendClass(one, list.get(0));
- one.append(", ");
- appendClass(one, list.get(1));
- one.append("}");
- distincts.add(one.toString());
+ for (UnorderedPair<EqClass> pair : getDistinctClassPairs()) {
+ distincts.add("{" + pair.first + ", " + pair.second + "}");
}
Collections.sort(distincts);
result.append(StringUtil.join(distincts, " "));
@@ -174,7 +168,7 @@
if (!myVariableStates.isEmpty()) {
result.append("\n vars: ");
for (Map.Entry<DfaVariableValue, DfaVariableState> entry : myVariableStates.entrySet()) {
- result.append("\n[").append(entry.getKey()).append("->").append(entry.getValue()).append("]");
+ result.append("[").append(entry.getKey()).append("->").append(entry.getValue()).append("] ");
}
}
if (!myUnknownVariables.isEmpty()) {
@@ -201,11 +195,13 @@
@Override
public int popOffset() {
+ myOffsetStack = new TIntStack(myOffsetStack);
return myOffsetStack.pop();
}
@Override
public void pushOffset(int offset) {
+ myOffsetStack = new TIntStack(myOffsetStack);
myOffsetStack.push(offset);
}
@@ -220,13 +216,13 @@
flushVariable(var);
if (value instanceof DfaUnknownValue) {
- getVariableState(var).setNullable(false);
+ setVariableState(var, getVariableState(var).withNullable(false));
return;
}
- getVariableState(var).setValue(value);
+ setVariableState(var, getVariableState(var).withValue(value));
if (value instanceof DfaTypeValue) {
- getVariableState(var).setNullable(((DfaTypeValue)value).isNullable());
+ setVariableState(var, getVariableState(var).withNullable(((DfaTypeValue)value).isNullable()));
DfaRelationValue dfaInstanceof = myFactory.getRelationFactory().createRelation(var, value, JavaTokenType.INSTANCEOF_KEYWORD, false);
if (((DfaTypeValue)value).isNotNull()) {
applyCondition(dfaInstanceof);
@@ -240,10 +236,10 @@
applyCondition(dfaEqual);
if (value instanceof DfaVariableValue) {
- myVariableStates.put(var, getVariableState((DfaVariableValue)value).clone());
+ setVariableState(var, getVariableState((DfaVariableValue)value));
}
else if (value instanceof DfaBoxedValue) {
- getVariableState(var).setNullable(false);
+ setVariableState(var, getVariableState(var).withNullable(false));
applyCondition(compareToNull(var, true));
}
}
@@ -260,7 +256,7 @@
if (!canBeReused(dfaValue) && !(((DfaBoxedValue)dfaValue).getWrappedValue() instanceof DfaConstValue)) {
return null;
}
- SortedIntSet aClass = new SortedIntSet();
+ EqClass aClass = new EqClass(myFactory);
aClass.add(dfaValue.getID());
myEqClasses.add(aClass);
@@ -270,20 +266,11 @@
@NotNull
private List<DfaValue> getEqClassesFor(@NotNull DfaValue dfaValue) {
int index = getEqClassIndex(dfaValue);
- SortedIntSet set = index == -1 ? null : myEqClasses.get(index);
+ EqClass set = index == -1 ? null : myEqClasses.get(index);
if (set == null) {
return Collections.emptyList();
}
- final List<DfaValue> result = new ArrayList<DfaValue>(set.size());
- set.forEach(new TIntProcedure() {
- @Override
- public boolean execute(int c1) {
- DfaValue value = myFactory.getValue(c1);
- result.add(value);
- return true;
- }
- });
- return result;
+ return set.getMemberValues();
}
private boolean canBeNaN(@NotNull DfaValue dfaValue) {
@@ -309,7 +296,7 @@
private int getEqClassIndex(@NotNull DfaValue dfaValue) {
for (int i = 0; i < myEqClasses.size(); i++) {
- SortedIntSet aClass = myEqClasses.get(i);
+ EqClass aClass = myEqClasses.get(i);
if (aClass != null && aClass.contains(dfaValue.getID())) {
if (!canBeReused(dfaValue) && aClass.size() > 1) return -1;
return i;
@@ -368,8 +355,8 @@
}
private boolean uniteClasses(int c1Index, int c2Index) {
- SortedIntSet c1 = myEqClasses.get(c1Index);
- SortedIntSet c2 = myEqClasses.get(c2Index);
+ EqClass c1 = myEqClasses.get(c1Index);
+ EqClass c2 = myEqClasses.get(c2Index);
Set<DfaVariableValue> vars = ContainerUtil.newTroveSet();
Set<DfaVariableValue> negatedVars = ContainerUtil.newTroveSet();
@@ -379,15 +366,14 @@
int nConst = 0;
for (int c : cs) {
- DfaValue dfaValue = myFactory.getValue(c);
- if (dfaValue instanceof DfaBoxedValue) dfaValue = ((DfaBoxedValue)dfaValue).getWrappedValue();
- if (dfaValue instanceof DfaUnboxedValue) dfaValue = ((DfaUnboxedValue)dfaValue).getVariable();
+ DfaValue dfaValue = unwrap(myFactory.getValue(c));
if (dfaValue instanceof DfaConstValue) nConst++;
if (dfaValue instanceof DfaVariableValue) {
DfaVariableValue variableValue = (DfaVariableValue)dfaValue;
if (variableValue.isNegated()) {
negatedVars.add(variableValue.createNegated());
- } else {
+ }
+ else {
vars.add(variableValue);
}
}
@@ -412,6 +398,7 @@
}
}
+ myEqClasses.set(c1Index, c1 = new EqClass(c1));
for (int i = 0; i < c2.size(); i++) {
int c = c2.get(i);
c1.add(c);
@@ -458,7 +445,7 @@
public boolean isNull(DfaValue dfaValue) {
if (dfaValue instanceof DfaTypeValue && ((DfaTypeValue)dfaValue).isNotNull()) return false;
- if (dfaValue instanceof DfaConstValue) return ((DfaConstValue)dfaValue).getConstant() == null;
+ if (dfaValue instanceof DfaConstValue) return ((DfaConstValue)dfaValue).getValue() == null;
if (dfaValue instanceof DfaVariableValue) {
int c1Index = getEqClassIndex(dfaValue);
@@ -495,33 +482,47 @@
@Override
@Nullable
public DfaConstValue getConstantValue(DfaVariableValue value) {
- DfaConstValue result = null;
- for (DfaValue equal : getEqClassesFor(value)) {
- if (equal instanceof DfaVariableValue) continue;
- DfaConstValue constValue = asConstantValue(equal);
- if (constValue == null) return null;
- result = constValue;
- }
- return result;
+ int index = getEqClassIndex(value);
+ EqClass ec = index == -1 ? null : myEqClasses.get(index);
+ return ec == null ? null : ec.findConstant(true);
+ }
+
+ @Override
+ public void markEphemeral() {
+ myEphemeral = true;
+ }
+
+ @Override
+ public boolean isEphemeral() {
+ return myEphemeral;
}
@Override
public boolean applyInstanceofOrNull(DfaRelationValue dfaCond) {
- DfaValue left = dfaCond.getLeftOperand();
- if (left instanceof DfaBoxedValue) {
- left = ((DfaBoxedValue)left).getWrappedValue();
- }
- else if (left instanceof DfaUnboxedValue) {
- left = ((DfaUnboxedValue)left).getVariable();
- }
+ DfaValue left = unwrap(dfaCond.getLeftOperand());
if (!(left instanceof DfaVariableValue)) return true;
DfaVariableValue dfaVar = (DfaVariableValue)left;
DfaTypeValue dfaType = (DfaTypeValue)dfaCond.getRightOperand();
- final DfaVariableState varState = getVariableState(dfaVar);
- return isNull(dfaVar) || varState.setInstanceofValue(dfaType);
+ if (isUnknownState(dfaVar) || isNull(dfaVar)) return true;
+ DfaVariableState newState = getVariableState(dfaVar).withInstanceofValue(dfaType);
+ if (newState != null) {
+ setVariableState(dfaVar, newState);
+ return true;
+ }
+ return false;
+ }
+
+ static DfaValue unwrap(DfaValue value) {
+ if (value instanceof DfaBoxedValue) {
+ return ((DfaBoxedValue)value).getWrappedValue();
+ }
+ else if (value instanceof DfaUnboxedValue) {
+ return ((DfaUnboxedValue)value).getVariable();
+ }
+ return value;
}
@Override
@@ -563,12 +564,25 @@
if (dfaRight instanceof DfaTypeValue) {
if (dfaLeft instanceof DfaVariableValue) {
- DfaVariableState varState = getVariableState((DfaVariableValue)dfaLeft);
DfaVariableValue dfaVar = (DfaVariableValue)dfaLeft;
+ if (isUnknownState(dfaVar)) return true;
+
if (isNegated) {
- return varState.addNotInstanceofValue((DfaTypeValue)dfaRight) || applyCondition(compareToNull(dfaVar, false));
+ DfaVariableState newState = getVariableState(dfaVar).withNotInstanceofValue((DfaTypeValue)dfaRight);
+ if (newState != null) {
+ setVariableState(dfaVar, newState);
+ return true;
+ }
+ return applyCondition(compareToNull(dfaVar, false));
}
- return applyCondition(compareToNull(dfaVar, true)) && varState.setInstanceofValue((DfaTypeValue)dfaRight);
+ if (applyCondition(compareToNull(dfaVar, true))) {
+ DfaVariableState newState = getVariableState(dfaVar).withInstanceofValue((DfaTypeValue)dfaRight);
+ if (newState != null) {
+ setVariableState(dfaVar, newState);
+ return true;
+ }
+ }
+ return false;
}
return true;
}
@@ -595,7 +609,9 @@
if (isNotNull(dfaVar)) {
return true;
}
- getVariableState(dfaVar).setNullable(true);
+ if (!isUnknownState(dfaVar)) {
+ setVariableState(dfaVar, getVariableState(dfaVar).withNullability(Nullness.NULLABLE));
+ }
}
return false;
}
@@ -637,7 +653,7 @@
if (!TypeConversionUtil.isPrimitiveWrapper(type)) {
return true;
}
- if (negated && !isMaybeBoxedConstant(dfaRight)) {
+ if (negated && !(unwrap(dfaRight) instanceof DfaConstValue)) {
// from the fact (wrappers are not the same) does not follow (unboxed values are not equals)
return true;
}
@@ -646,11 +662,6 @@
return applyRelation(boxedFactory.createUnboxed(dfaLeft), boxedFactory.createUnboxed(dfaRight), negated);
}
- private static boolean isMaybeBoxedConstant(DfaValue val) {
- return val instanceof DfaConstValue ||
- val instanceof DfaBoxedValue && ((DfaBoxedValue)val).getWrappedValue() instanceof DfaConstValue;
- }
-
private boolean checkCompareWithBooleanLiteral(DfaValue dfaLeft, DfaValue dfaRight, boolean negated) {
if (dfaRight instanceof DfaConstValue) {
Object constVal = ((DfaConstValue)dfaRight).getValue();
@@ -691,18 +702,28 @@
if (!isNegated) { //Equals
if (c1Index.equals(c2Index)) return true;
if (!uniteClasses(c1Index, c2Index)) return false;
+
+ for (long encodedPair : myDistinctClasses.toArray()) {
+ EqClass c1 = myEqClasses.get(low(encodedPair));
+ EqClass c2 = myEqClasses.get(high(encodedPair));
+ if (c1.findConstant(false) != null && c2.findConstant(false) != null) {
+ myDistinctClasses.remove(encodedPair);
+ }
+ }
+ myCachedDistinctClassPairs = null;
+ myCachedNonTrivialEqClasses = null;
}
else { // Not Equals
if (c1Index.equals(c2Index)) return false;
makeClassesDistinct(c1Index, c2Index);
+ myCachedDistinctClassPairs = null;
}
return true;
}
private boolean isUnknownState(DfaValue val) {
- if (val instanceof DfaBoxedValue) return isUnknownState(((DfaBoxedValue)val).getWrappedValue());
- if (val instanceof DfaUnboxedValue) return isUnknownState(((DfaUnboxedValue)val).getVariable());
+ val = unwrap(val);
if (val instanceof DfaVariableValue) {
if (myUnknownVariables.contains(val)) return true;
DfaVariableValue negatedValue = ((DfaVariableValue)val).getNegatedValue();
@@ -731,17 +752,33 @@
return myFactory.getRelationFactory().createRelation(dfaVar, dfaNull, JavaTokenType.EQEQ, negated);
}
+ void setVariableState(DfaVariableValue dfaVar, DfaVariableState state) {
+ assert !myUnknownVariables.contains(dfaVar);
+ if (state.equals(myDefaultVariableStates.get(dfaVar))) {
+ myVariableStates.remove(dfaVar);
+ } else {
+ myVariableStates.put(dfaVar, state);
+ }
+ }
+
public DfaVariableState getVariableState(DfaVariableValue dfaVar) {
DfaVariableState state = myVariableStates.get(dfaVar);
if (state == null) {
- state = createVariableState(dfaVar);
- if (isUnknownState(dfaVar)) {
- state.setNullable(false);
- return state;
+ state = myDefaultVariableStates.get(dfaVar);
+ if (state == null) {
+ state = createVariableState(dfaVar);
+ DfaTypeValue initialType = dfaVar.getTypeValue();
+ if (initialType != null) {
+ state = state.withInstanceofValue(initialType);
+ assert state != null;
+ }
+ myDefaultVariableStates.put(dfaVar, state);
}
-
- myVariableStates.put(dfaVar, state);
+
+ if (isUnknownState(dfaVar)) {
+ return state.withNullable(false);
+ }
}
return state;
@@ -757,28 +794,25 @@
@Override
public void flushFields(DfaVariableValue[] fields) {
- Set<DfaVariableValue> allVars = new HashSet<DfaVariableValue>(myVariableStates.keySet());
- Collections.addAll(allVars, fields);
-
- Set<DfaVariableValue> dependencies = new HashSet<DfaVariableValue>();
- for (DfaVariableValue variableValue : allVars) {
- dependencies.addAll(myFactory.getVarFactory().getAllQualifiedBy(variableValue));
- }
- allVars.addAll(dependencies);
-
- for (DfaVariableValue value : allVars) {
- if (myVariableStates.containsKey(value) || getEqClassIndex(value) >= 0) {
- if (value.isFlushableByCalls()) {
- doFlush(value);
- myUnknownVariables.add(value);
+ for (EqClass aClass : myEqClasses) {
+ if (aClass != null) {
+ for (DfaVariableValue value : aClass.getVariables()) {
+ if (value.isFlushableByCalls()) {
+ doFlush(value, true);
+ }
}
}
}
+ for (DfaVariableValue value : new ArrayList<DfaVariableValue>(myVariableStates.keySet())) {
+ if (value.isFlushableByCalls()) {
+ doFlush(value, true);
+ }
+ }
}
@Override
public void flushVariable(@NotNull DfaVariableValue variable) {
- doFlush(variable);
+ doFlush(variable, false);
flushDependencies(variable);
myUnknownVariables.remove(variable);
myUnknownVariables.removeAll(myFactory.getVarFactory().getAllQualifiedBy(variable));
@@ -786,11 +820,15 @@
public void flushDependencies(DfaVariableValue variable) {
for (DfaVariableValue dependent : myFactory.getVarFactory().getAllQualifiedBy(variable)) {
- doFlush(dependent);
+ doFlush(dependent, false);
}
}
- private void doFlush(DfaVariableValue varPlain) {
+ Set<DfaVariableValue> getUnknownVariables() {
+ return myUnknownVariables;
+ }
+
+ void doFlush(DfaVariableValue varPlain, boolean markUnknown) {
DfaVariableValue varNegated = varPlain.getNegatedValue();
final int idPlain = varPlain.getID();
@@ -799,7 +837,7 @@
int size = myEqClasses.size();
int interruptCount = 0;
for (int varClassIndex = 0; varClassIndex < size; varClassIndex++) {
- final SortedIntSet varClass = myEqClasses.get(varClassIndex);
+ EqClass varClass = myEqClasses.get(varClassIndex);
if (varClass == null) continue;
for (int i = 0; i < varClass.size(); i++) {
@@ -809,6 +847,7 @@
int cl = varClass.get(i);
DfaValue value = myFactory.getValue(cl);
if (mine(idPlain, value) || idNegated >= 0 && mine(idNegated, value)) {
+ myEqClasses.set(varClassIndex, varClass = new EqClass(varClass));
varClass.remove(i);
break;
}
@@ -823,10 +862,10 @@
}
}
}
- else if (containsConstantsOnly(varClassIndex)) {
+ else if (varClass.containsConstantsOnly()) {
for (long pair : myDistinctClasses.toArray()) {
- if (low(pair) == varClassIndex && containsConstantsOnly(high(pair)) ||
- high(pair) == varClassIndex && containsConstantsOnly(low(pair))) {
+ if (low(pair) == varClassIndex && myEqClasses.get(high(pair)).containsConstantsOnly() ||
+ high(pair) == varClassIndex && myEqClasses.get(low(pair)).containsConstantsOnly()) {
myDistinctClasses.remove(pair);
}
}
@@ -837,28 +876,14 @@
if (varNegated != null) {
myVariableStates.remove(varNegated);
}
- }
-
- @Nullable private static DfaConstValue asConstantValue(DfaValue value) {
- if (value instanceof DfaConstValue) return (DfaConstValue)value;
- if (value instanceof DfaBoxedValue && ((DfaBoxedValue)value).getWrappedValue() instanceof DfaConstValue) return (DfaConstValue)((DfaBoxedValue)value).getWrappedValue();
- return null;
- }
-
- private boolean containsConstantsOnly(int id) {
- SortedIntSet varClass = myEqClasses.get(id);
- for (int i = 0; i < varClass.size(); i++) {
- if (asConstantValue(myFactory.getValue(varClass.get(i))) == null) {
- return false;
- }
+ if (markUnknown) {
+ myUnknownVariables.add(varPlain);
}
-
- return true;
+ myCachedNonTrivialEqClasses = null;
+ myCachedDistinctClassPairs = null;
}
private static boolean mine(int id, DfaValue value) {
- return value != null && id == value.getID() ||
- value instanceof DfaBoxedValue && ((DfaBoxedValue)value).getWrappedValue().getID() == id ||
- value instanceof DfaUnboxedValue && ((DfaUnboxedValue)value).getVariable().getID() == id;
+ return value != null && id == unwrap(value).getID();
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java
index 3b493d4..8ed7836 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java
@@ -37,9 +37,6 @@
import java.util.Set;
public class DfaPsiUtil {
- public static boolean isPlainMutableField(PsiVariable var) {
- return !var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && !var.hasModifierProperty(PsiModifier.VOLATILE) && var instanceof PsiField;
- }
public static boolean isFinalField(PsiVariable var) {
return var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && var instanceof PsiField;
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java
index 8c3cce8..16a2a6d 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java
@@ -163,9 +163,10 @@
}
@Override
- public DfaInstructionState[] visitAssign(AssignInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
+ public DfaInstructionState[] visitAssign(AssignInstruction instruction, DataFlowRunner runner, DfaMemoryState _memState) {
final Instruction nextInstruction = runner.getInstruction(instruction.getIndex() + 1);
+ ValuableDataFlowRunner.MyDfaMemoryState memState = (ValuableDataFlowRunner.MyDfaMemoryState)_memState;
final DfaValue dfaSource = memState.pop();
final DfaValue dfaDest = memState.pop();
@@ -176,10 +177,10 @@
final IElementType type = parent instanceof PsiAssignmentExpression
? ((PsiAssignmentExpression)parent).getOperationTokenType() : JavaTokenType.EQ;
// store current value - to use in case of '+='
- final PsiExpression prevValue = ((ValuableDataFlowRunner.ValuableDfaVariableState)((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableState(var)).myExpression;
+ final PsiExpression prevValue = ((ValuableDataFlowRunner.ValuableDfaVariableState)memState.getVariableState(var)).myExpression;
memState.setVarValue(var, dfaSource);
// state may have been changed so re-retrieve it
- final ValuableDataFlowRunner.ValuableDfaVariableState curState = (ValuableDataFlowRunner.ValuableDfaVariableState)((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableState(var);
+ final ValuableDataFlowRunner.ValuableDfaVariableState curState = (ValuableDataFlowRunner.ValuableDfaVariableState)memState.getVariableState(var);
final PsiExpression curValue = curState.myExpression;
final PsiExpression nextValue;
if (type == JavaTokenType.PLUSEQ && prevValue != null) {
@@ -196,7 +197,7 @@
else {
nextValue = curValue == null ? rightValue : curValue;
}
- curState.myExpression = nextValue;
+ memState.setVariableState(var, curState.withExpression(nextValue));
}
memState.push(dfaDest);
return new DfaInstructionState[]{new DfaInstructionState(nextInstruction, memState)};
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java
index 8173822..61d61c2 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java
@@ -24,138 +24,134 @@
*/
package com.intellij.codeInspection.dataFlow;
+import com.intellij.codeInspection.dataFlow.value.DfaPsiType;
import com.intellij.codeInspection.dataFlow.value.DfaTypeValue;
import com.intellij.codeInspection.dataFlow.value.DfaValue;
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
-import com.intellij.psi.*;
-import gnu.trove.THashSet;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiPrimitiveType;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.Collections;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.Set;
-public class DfaVariableState implements Cloneable {
- private final Set<DfaTypeValue> myInstanceofValues;
- private final Set<DfaTypeValue> myNotInstanceofValues;
- private Nullness myNullability;
+public class DfaVariableState {
+ protected final Set<DfaPsiType> myInstanceofValues;
+ protected final Set<DfaPsiType> myNotInstanceofValues;
+ protected final Nullness myNullability;
public DfaVariableState(@NotNull DfaVariableValue dfaVar) {
- myInstanceofValues = new HashSet<DfaTypeValue>();
- myNotInstanceofValues = new HashSet<DfaTypeValue>();
-
- myNullability = dfaVar.getInherentNullability();
- DfaTypeValue initialType = dfaVar.getTypeValue();
- if (initialType != null) {
- setInstanceofValue(initialType);
- }
+ this(Collections.<DfaPsiType>emptySet(), Collections.<DfaPsiType>emptySet(), dfaVar.getInherentNullability());
}
- protected DfaVariableState(final DfaVariableState toClone) {
- myInstanceofValues = new THashSet<DfaTypeValue>(toClone.myInstanceofValues);
- myNotInstanceofValues = new THashSet<DfaTypeValue>(toClone.myNotInstanceofValues);
- myNullability = toClone.myNullability;
+ protected DfaVariableState(Set<DfaPsiType> instanceofValues,
+ Set<DfaPsiType> notInstanceofValues, Nullness nullability) {
+ myInstanceofValues = instanceofValues;
+ myNotInstanceofValues = notInstanceofValues;
+ myNullability = nullability;
}
public boolean isNullable() {
return myNullability == Nullness.NULLABLE;
}
- private boolean checkInstanceofValue(DfaTypeValue dfaType) {
+ private boolean checkInstanceofValue(DfaPsiType dfaType) {
if (myInstanceofValues.contains(dfaType)) return true;
- for (DfaTypeValue dfaTypeValue : myNotInstanceofValues) {
+ for (DfaPsiType dfaTypeValue : myNotInstanceofValues) {
if (dfaTypeValue.isAssignableFrom(dfaType)) return false;
}
- for (DfaTypeValue dfaTypeValue : myInstanceofValues) {
+ for (DfaPsiType dfaTypeValue : myInstanceofValues) {
if (!dfaType.isConvertibleFrom(dfaTypeValue)) return false;
}
return true;
}
- public boolean setInstanceofValue(DfaTypeValue dfaType) {
- if (dfaType.isNullable()) {
- myNullability = Nullness.NULLABLE;
+ @Nullable
+ public DfaVariableState withInstanceofValue(DfaTypeValue dfaType) {
+ if (dfaType.getDfaType().getPsiType() instanceof PsiPrimitiveType) return this;
+
+ if (checkInstanceofValue(dfaType.getDfaType())) {
+ DfaVariableState result = dfaType.isNullable() ? withNullability(Nullness.NULLABLE) : this;
+ if (!myInstanceofValues.contains(dfaType.getDfaType())) {
+ HashSet<DfaPsiType> newInstanceof = ContainerUtil.newHashSet(myInstanceofValues);
+ newInstanceof.add(dfaType.getDfaType());
+ result = createCopy(newInstanceof, myNotInstanceofValues, result.myNullability);
+ }
+ return result;
}
- if (dfaType.getType() instanceof PsiPrimitiveType) return true;
-
- if (checkInstanceofValue(dfaType)) {
- myInstanceofValues.add(dfaType);
- return true;
- }
-
- return false;
+ return null;
}
- public boolean addNotInstanceofValue(DfaTypeValue dfaType) {
- if (myNotInstanceofValues.contains(dfaType)) return true;
+ @Nullable
+ public DfaVariableState withNotInstanceofValue(DfaTypeValue dfaType) {
+ if (myNotInstanceofValues.contains(dfaType.getDfaType())) return this;
- for (DfaTypeValue dfaTypeValue : myInstanceofValues) {
- if (dfaType.isAssignableFrom(dfaTypeValue)) return false;
+ for (DfaPsiType dfaTypeValue : myInstanceofValues) {
+ if (dfaType.getDfaType().isAssignableFrom(dfaTypeValue)) return null;
}
- myNotInstanceofValues.add(dfaType);
- return true;
+ HashSet<DfaPsiType> newNotInstanceof = ContainerUtil.newHashSet(myNotInstanceofValues);
+ newNotInstanceof.add(dfaType.getDfaType());
+ return createCopy(myInstanceofValues, newNotInstanceof, myNullability);
}
public int hashCode() {
- return myInstanceofValues.hashCode() + myNotInstanceofValues.hashCode();
+ return (myInstanceofValues.hashCode() * 31 + myNotInstanceofValues.hashCode()) * 31 + myNullability.hashCode();
}
public boolean equals(Object obj) {
if (obj == this) return true;
if (!(obj instanceof DfaVariableState)) return false;
DfaVariableState aState = (DfaVariableState) obj;
- return myInstanceofValues.equals(aState.myInstanceofValues) &&
- myNotInstanceofValues.equals(aState.myNotInstanceofValues) &&
- myNullability == aState.myNullability;
+ return myNullability == aState.myNullability &&
+ myInstanceofValues.equals(aState.myInstanceofValues) &&
+ myNotInstanceofValues.equals(aState.myNotInstanceofValues);
}
- @Override
- protected DfaVariableState clone() {
- return new DfaVariableState(this);
+ protected DfaVariableState createCopy(Set<DfaPsiType> instanceofValues, Set<DfaPsiType> notInstanceofValues, Nullness nullability) {
+ return new DfaVariableState(instanceofValues, notInstanceofValues, nullability);
}
public String toString() {
@NonNls StringBuilder buf = new StringBuilder();
+ buf.append(myNullability);
if (!myInstanceofValues.isEmpty()) {
- buf.append("instanceof ");
- for (Iterator<DfaTypeValue> iterator = myInstanceofValues.iterator(); iterator.hasNext();) {
- DfaTypeValue dfaTypeValue = iterator.next();
- buf.append("{").append(dfaTypeValue).append("}");
- if (iterator.hasNext()) buf.append(", ");
- }
+ buf.append(" instanceof ").append(StringUtil.join(myInstanceofValues, ","));
}
if (!myNotInstanceofValues.isEmpty()) {
- buf.append("not instanceof ");
- for (Iterator<DfaTypeValue> iterator = myNotInstanceofValues.iterator(); iterator.hasNext();) {
- DfaTypeValue dfaTypeValue = iterator.next();
- buf.append("{").append(dfaTypeValue).append("}");
- if (iterator.hasNext()) buf.append(", ");
- }
+ buf.append(" not instanceof ").append(StringUtil.join(myNotInstanceofValues, ","));
}
- buf.append(myNullability);
return buf.toString();
}
+ public Nullness getNullability() {
+ return myNullability;
+ }
+
public boolean isNotNull() {
return myNullability == Nullness.NOT_NULL;
}
- public void setNullable(final boolean nullable) {
- if (myNullability != Nullness.NOT_NULL) {
- myNullability = nullable ? Nullness.NULLABLE : Nullness.UNKNOWN;
- }
+ DfaVariableState withNullability(@NotNull Nullness nullness) {
+ return myNullability == nullness ? this : createCopy(myInstanceofValues, myNotInstanceofValues, nullness);
}
- public void setValue(DfaValue value) {
+ public DfaVariableState withNullable(final boolean nullable) {
+ return myNullability != Nullness.NOT_NULL ? withNullability(nullable ? Nullness.NULLABLE : Nullness.UNKNOWN) : this;
+ }
+
+ public DfaVariableState withValue(DfaValue value) {
+ return this;
}
@Nullable
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/EqClass.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/EqClass.java
new file mode 100644
index 0000000..c6fc621
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/EqClass.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.dataFlow;
+
+import com.intellij.codeInspection.dataFlow.value.DfaConstValue;
+import com.intellij.codeInspection.dataFlow.value.DfaValue;
+import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
+import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
+import com.intellij.util.containers.ContainerUtil;
+import gnu.trove.TIntProcedure;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author peter
+ */
+class EqClass extends SortedIntSet {
+ private final DfaValueFactory myFactory;
+
+ EqClass(DfaValueFactory factory) {
+ myFactory = factory;
+ }
+
+ EqClass(EqClass toCopy) {
+ super(toCopy.toNativeArray());
+ myFactory = toCopy.myFactory;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ buf.append("(");
+ for (int i = 0; i < size(); i++) {
+ if (i > 0) buf.append(", ");
+ int value = get(i);
+ DfaValue dfaValue = myFactory.getValue(value);
+ buf.append(dfaValue);
+ }
+ buf.append(")");
+ return buf.toString();
+ }
+
+ List<DfaVariableValue> getVariables() {
+ List<DfaVariableValue> vars = ContainerUtil.newArrayList();
+ for (DfaValue value : getMemberValues()) {
+ value = DfaMemoryStateImpl.unwrap(value);
+ if (value instanceof DfaVariableValue) {
+ vars.add((DfaVariableValue)value);
+ }
+ }
+ return vars;
+ }
+
+ List<DfaValue> getMemberValues() {
+ final List<DfaValue> result = new ArrayList<DfaValue>(size());
+ forEach(new TIntProcedure() {
+ @Override
+ public boolean execute(int c1) {
+ DfaValue value = myFactory.getValue(c1);
+ result.add(value);
+ return true;
+ }
+ });
+ return result;
+ }
+
+ @Nullable
+ DfaConstValue findConstant(boolean wrapped) {
+ for (DfaValue value : getMemberValues()) {
+ if (wrapped) {
+ value = DfaMemoryStateImpl.unwrap(value);
+ }
+ if (value instanceof DfaConstValue) {
+ return (DfaConstValue)value;
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ private static DfaConstValue asConstantValue(DfaValue value) {
+ value = DfaMemoryStateImpl.unwrap(value);
+ return value instanceof DfaConstValue ? (DfaConstValue)value : null;
+ }
+
+ boolean containsConstantsOnly() {
+ for (int i = 0; i < size(); i++) {
+ if (asConstantValue(myFactory.getValue(get(i))) == null) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullabilityProblem.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullabilityProblem.java
new file mode 100644
index 0000000..8155149
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullabilityProblem.java
@@ -0,0 +1,14 @@
+package com.intellij.codeInspection.dataFlow;
+
+/**
+ * @author peter
+ */
+public enum NullabilityProblem {
+ callNPE,
+ fieldAccessNPE,
+ unboxingNullable,
+ assigningToNotNull,
+ nullableReturn,
+ passingNullableToNotNullParameter,
+ passingNullableArgumentToNonAnnotatedParameter,
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java
index b7fc6c7..2d6ee1b 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java
@@ -27,36 +27,23 @@
import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.codeInspection.dataFlow.instructions.InstanceofInstruction;
import com.intellij.codeInspection.dataFlow.instructions.Instruction;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
-import com.intellij.psi.*;
-import gnu.trove.THashSet;
+import com.intellij.psi.CommonClassNames;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
public class StandardDataFlowRunner extends DataFlowRunner {
- private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.DataFlowRunner");
-
- private final Set<Instruction> myNPEInstructions = new HashSet<Instruction>();
private final Set<Instruction> myCCEInstructions = new HashSet<Instruction>();
- private final Set<PsiExpression> myNullableArguments = new HashSet<PsiExpression>();
- private final Set<PsiExpression> myNullableArgumentsPassedToNonAnnotatedParam = new HashSet<PsiExpression>();
- private final Set<PsiExpression> myNullableAssignments = new HashSet<PsiExpression>();
- private final Set<PsiReturnStatement> myNullableReturns = new HashSet<PsiReturnStatement>();
- private final boolean mySuggestNullableAnnotations;
private boolean myInNullableMethod = false;
private boolean myInNotNullMethod = false;
private boolean myIsInMethod = false;
- private final Set<PsiExpression> myUnboxedNullables = new THashSet<PsiExpression>();
-
- public StandardDataFlowRunner(boolean suggestNullableAnnotations) {
- mySuggestNullableAnnotations = suggestNullableAnnotations;
- }
-
@Override
protected void prepareAnalysis(@NotNull PsiElement psiBlock, Iterable<DfaMemoryState> initialStates) {
myIsInMethod = psiBlock.getParent() instanceof PsiMethod;
@@ -68,17 +55,7 @@
myInNotNullMethod = NullableNotNullManager.isNotNull(method);
}
- myNPEInstructions.clear();
myCCEInstructions.clear();
- myNullableArguments.clear();
- myNullableArgumentsPassedToNonAnnotatedParam.clear();
- myNullableAssignments.clear();
- myNullableReturns.clear();
- myUnboxedNullables.clear();
- }
-
- public void onInstructionProducesNPE(Instruction instruction) {
- myNPEInstructions.add(instruction);
}
public void onInstructionProducesCCE(Instruction instruction) {
@@ -89,74 +66,24 @@
return myCCEInstructions;
}
- @NotNull public Set<Instruction> getNPEInstructions() {
- return myNPEInstructions;
- }
-
- @NotNull public Set<PsiReturnStatement> getNullableReturns() {
- return myNullableReturns;
- }
-
public boolean isInNotNullMethod() {
return myInNotNullMethod;
}
- @NotNull public Set<PsiExpression> getNullableArguments() {
- return myNullableArguments;
+ public boolean isInNullableMethod() {
+ return myInNullableMethod;
}
- public Set<PsiExpression> getNullableArgumentsPassedToNonAnnotatedParam() {
- return myNullableArgumentsPassedToNonAnnotatedParam;
- }
-
- @NotNull public Set<PsiExpression> getNullableAssignments() {
- return myNullableAssignments;
- }
-
- @NotNull public Set<PsiExpression> getUnboxedNullables() {
- return myUnboxedNullables;
- }
-
- public void onUnboxingNullable(@NotNull PsiExpression expression) {
- LOG.assertTrue(expression.isValid());
- if (expression.isPhysical()) {
- myUnboxedNullables.add(expression);
- }
- }
-
- public void onPassingNullParameter(PsiExpression expr) {
- myNullableArguments.add(expr);
- }
-
- public void onPassingNullParameterToNonAnnotated(PsiExpression expr) {
- if (mySuggestNullableAnnotations) {
- myNullableArgumentsPassedToNonAnnotatedParam.add(expr);
- }
- }
-
- public void onAssigningToNotNullableVariable(final PsiExpression expr) {
- myNullableAssignments.add(expr);
- }
-
- public void onNullableReturn(final PsiReturnStatement statement) {
- if (myInNullableMethod || !myIsInMethod) return;
- if (myInNotNullMethod || mySuggestNullableAnnotations) {
- myNullableReturns.add(statement);
- }
+ public boolean isInMethod() {
+ return myIsInMethod;
}
public boolean problemsDetected(StandardInstructionVisitor visitor) {
final Pair<Set<Instruction>, Set<Instruction>> constConditions = getConstConditionalExpressions();
return !constConditions.getFirst().isEmpty()
|| !constConditions.getSecond().isEmpty()
- || !myNPEInstructions.isEmpty()
|| !myCCEInstructions.isEmpty()
- || !getRedundantInstanceofs(this, visitor).isEmpty()
- || !myNullableArguments.isEmpty()
- || !myNullableArgumentsPassedToNonAnnotatedParam.isEmpty()
- || !myNullableAssignments.isEmpty()
- || !myNullableReturns.isEmpty()
- || !myUnboxedNullables.isEmpty();
+ || !getRedundantInstanceofs(this, visitor).isEmpty();
}
@NotNull public static Set<Instruction> getRedundantInstanceofs(final DataFlowRunner runner, StandardInstructionVisitor visitor) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
index 3770e49..90a6490 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
@@ -115,17 +115,15 @@
if (dfaDest instanceof DfaVariableValue) {
DfaVariableValue var = (DfaVariableValue) dfaDest;
- final PsiModifierListOwner psiVariable = var.getPsiVariable();
- if (DfaPsiUtil.getElementNullability(var.getVariableType(), psiVariable) == Nullness.NOT_NULL) {
- if (!memState.checkNotNullable(dfaSource)) {
- onAssigningToNotNullableVariable(instruction);
- }
+ if (var.getInherentNullability() == Nullness.NOT_NULL) {
+ checkNotNullable(memState, dfaSource, NullabilityProblem.assigningToNotNull, instruction.getRExpression());
}
- if (!(psiVariable instanceof PsiField) || !psiVariable.hasModifierProperty(PsiModifier.VOLATILE)) {
+ final PsiModifierListOwner psi = var.getPsiVariable();
+ if (!(psi instanceof PsiField) || !psi.hasModifierProperty(PsiModifier.VOLATILE)) {
memState.setVarValue(var, dfaSource);
}
- } else if (dfaDest instanceof DfaTypeValue && ((DfaTypeValue)dfaDest).isNotNull() && !memState.checkNotNullable(dfaSource)) {
- onAssigningToNotNullableVariable(instruction);
+ } else if (dfaDest instanceof DfaTypeValue && ((DfaTypeValue)dfaDest).isNotNull()) {
+ checkNotNullable(memState, dfaSource, NullabilityProblem.assigningToNotNull, instruction.getRExpression());
}
memState.push(dfaDest);
@@ -133,27 +131,19 @@
return nextInstruction(instruction, runner, memState);
}
- protected void onAssigningToNotNullableVariable(AssignInstruction instruction) {}
-
@Override
public DfaInstructionState[] visitCheckReturnValue(CheckReturnValueInstruction instruction,
DataFlowRunner runner,
DfaMemoryState memState) {
final DfaValue retValue = memState.pop();
- if (!memState.checkNotNullable(retValue)) {
- onNullableReturn(instruction);
- }
+ checkNotNullable(memState, retValue, NullabilityProblem.nullableReturn, instruction.getReturn());
return nextInstruction(instruction, runner, memState);
}
- protected void onNullableReturn(CheckReturnValueInstruction instruction) {}
-
@Override
public DfaInstructionState[] visitFieldReference(FieldReferenceInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
final DfaValue qualifier = memState.pop();
- if (!memState.checkNotNullable(qualifier)) {
- onInstructionProducesNPE(instruction);
-
+ if (!checkNotNullable(memState, qualifier, NullabilityProblem.fieldAccessNPE, instruction.getElementToAssert())) {
if (qualifier instanceof DfaVariableValue) {
memState.setVarValue((DfaVariableValue)qualifier, runner.getFactory()
.createTypeValue(((DfaVariableValue)qualifier).getVariableType(), Nullness.NOT_NULL));
@@ -194,7 +184,7 @@
final DfaValueFactory factory = runner.getFactory();
DfaValue dfaExpr = factory.createValue(instruction.getCasted());
if (dfaExpr != null) {
- DfaTypeValue dfaType = factory.getTypeFactory().createTypeValue(instruction.getCastTo());
+ DfaTypeValue dfaType = (DfaTypeValue)factory.createTypeValue(instruction.getCastTo(), Nullness.UNKNOWN);
DfaRelationValue dfaInstanceof = factory.getRelationFactory().createRelation(dfaExpr, dfaType, JavaTokenType.INSTANCEOF_KEYWORD, false);
if (dfaInstanceof != null && !memState.applyInstanceofOrNull(dfaInstanceof)) {
onInstructionProducesCCE(instruction);
@@ -218,23 +208,24 @@
final DfaValue arg = memState.pop();
PsiExpression expr = args[(args.length - i - 1)];
if (map.get(expr) == Nullness.NOT_NULL) {
- if (!memState.checkNotNullable(arg)) {
- onPassingNullParameter(expr);
+ if (!checkNotNullable(memState, arg, NullabilityProblem.passingNullableToNotNullParameter, expr)) {
if (arg instanceof DfaVariableValue) {
memState.setVarValue((DfaVariableValue)arg, runner.getFactory()
.createTypeValue(((DfaVariableValue)arg).getVariableType(), Nullness.NOT_NULL));
}
}
}
- else if (map.get(expr) == Nullness.UNKNOWN && !memState.checkNotNullable(arg)) {
- onPassingNullParameterToNonAnnotated(runner, expr);
+ else if (map.get(expr) == Nullness.UNKNOWN) {
+ checkNotNullable(memState, arg, NullabilityProblem.passingNullableArgumentToNonAnnotatedParameter, expr);
}
}
@NotNull final DfaValue qualifier = memState.pop();
try {
- if (!memState.checkNotNullable(qualifier)) {
- onInstructionProducesNPE(instruction);
+ boolean unboxing = instruction.getMethodType() == MethodCallInstruction.MethodType.UNBOXING;
+ NullabilityProblem problem = unboxing ? NullabilityProblem.unboxingNullable : NullabilityProblem.callNPE;
+ PsiExpression anchor = unboxing ? instruction.getContext() : instruction.getCallExpression();
+ if (!checkNotNullable(memState, qualifier, problem, anchor)) {
if (qualifier instanceof DfaVariableValue) {
memState.setVarValue((DfaVariableValue)qualifier, runner.getFactory().createTypeValue(
((DfaVariableValue)qualifier).getVariableType(), Nullness.NOT_NULL));
@@ -296,11 +287,11 @@
return TypeConversionUtil.computeCastTo(o, PsiType.LONG);
}
-
- protected void onInstructionProducesNPE(Instruction instruction) {}
-
- protected void onPassingNullParameter(PsiExpression arg) {}
- protected void onPassingNullParameterToNonAnnotated(DataFlowRunner runner, PsiExpression arg) {}
+ protected boolean checkNotNullable(DfaMemoryState state,
+ DfaValue value, NullabilityProblem problem,
+ PsiElement anchor) {
+ return state.checkNotNullable(value);
+ }
@Override
public DfaInstructionState[] visitBinop(BinopInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
@@ -351,11 +342,10 @@
return null;
}
- if (isViaMethods(dfaLeft) || isViaMethods(dfaRight)) {
- skipConstantConditionReporting(instruction.getPsiAnchor());
- }
myCanBeNullInInstanceof.add(instruction);
+ boolean specialContractTreatment = isUnknownComparisonWithNullInContract(instruction, dfaLeft, dfaRight, factory, memState);
+
ArrayList<DfaInstructionState> states = new ArrayList<DfaInstructionState>();
final DfaMemoryState trueCopy = memState.createCopy();
@@ -363,6 +353,9 @@
if (!dfaRelation.isNegated()) {
checkOneOperandNotNull(dfaRight, dfaLeft, factory, trueCopy);
}
+ if (specialContractTreatment && !dfaRelation.isNegated()) {
+ trueCopy.markEphemeral();
+ }
trueCopy.push(factory.getConstFactory().getTrue());
instruction.setTrueReachable();
states.add(new DfaInstructionState(next, trueCopy));
@@ -374,6 +367,9 @@
if (dfaRelation.isNegated()) {
checkOneOperandNotNull(dfaRight, dfaLeft, factory, falseCopy);
}
+ if (specialContractTreatment && dfaRelation.isNegated()) {
+ falseCopy.markEphemeral();
+ }
falseCopy.push(factory.getConstFactory().getFalse());
instruction.setFalseReachable();
states.add(new DfaInstructionState(next, falseCopy));
@@ -385,12 +381,25 @@
return states.toArray(new DfaInstructionState[states.size()]);
}
- public void skipConstantConditionReporting(@Nullable PsiElement anchor) {
- ContainerUtil.addIfNotNull(myNotToReportReachability, anchor);
+ private static boolean isUnknownComparisonWithNullInContract(BinopInstruction instruction,
+ DfaValue dfaLeft,
+ DfaValue dfaRight,
+ DfaValueFactory factory,
+ DfaMemoryState memoryState) {
+ if (instruction.getPsiAnchor() != null || dfaRight != factory.getConstFactory().getNull()) {
+ return false;
+ }
+ if (dfaLeft instanceof DfaVariableValue) {
+ return ((DfaMemoryStateImpl)memoryState).getVariableState((DfaVariableValue)dfaLeft).getNullability() == Nullness.UNKNOWN;
+ }
+ if (dfaLeft instanceof DfaTypeValue) {
+ return ((DfaTypeValue)dfaLeft).getNullness() == Nullness.UNKNOWN;
+ }
+ return false;
}
- private static boolean isViaMethods(DfaValue dfa) {
- return dfa instanceof DfaVariableValue && ((DfaVariableValue)dfa).isViaMethods();
+ public void skipConstantConditionReporting(@Nullable PsiElement anchor) {
+ ContainerUtil.addIfNotNull(myNotToReportReachability, anchor);
}
private void handleInstanceof(InstanceofInstruction instruction, DfaValue dfaRight, DfaValue dfaLeft) {
@@ -399,7 +408,7 @@
myCanBeNullInInstanceof.add(instruction);
}
- if (((DfaTypeValue)dfaRight).getType().isAssignableFrom(((DfaTypeValue)dfaLeft).getType())) {
+ if (((DfaTypeValue)dfaRight).getDfaType().isAssignableFrom(((DfaTypeValue)dfaLeft).getDfaType())) {
return;
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java
new file mode 100644
index 0000000..e886dde
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.dataFlow;
+
+import com.intellij.codeInspection.dataFlow.value.DfaConstValue;
+import com.intellij.codeInspection.dataFlow.value.DfaValue;
+import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.UnorderedPair;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.MultiMap;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author peter
+ */
+class StateMerger {
+ private final List<DfaMemoryStateImpl> myStates;
+ private final MultiMap<UnorderedPair<DfaValue>,DfaMemoryStateImpl> myStatesByEq = new MultiMap<UnorderedPair<DfaValue>, DfaMemoryStateImpl>();
+ private final Map<DfaMemoryStateImpl, Map<DfaVariableValue, DfaConstValue>> myVarValues = ContainerUtil.newIdentityHashMap();
+
+ public StateMerger(List<DfaMemoryStateImpl> states) {
+ myStates = states;
+ for (DfaMemoryStateImpl state : myStates) {
+ ProgressManager.checkCanceled();
+
+ Map<DfaVariableValue,DfaConstValue> varValues = ContainerUtil.newHashMap();
+ for (UnorderedPair<DfaValue> pair : getEqPairs(state)) {
+ myStatesByEq.putValue(pair, state);
+ if (pair.first instanceof DfaVariableValue && pair.second instanceof DfaConstValue) {
+ varValues.put((DfaVariableValue)pair.first, (DfaConstValue)pair.second);
+ }
+ }
+ myVarValues.put(state, varValues);
+ }
+ }
+
+ @Nullable
+ public List<DfaMemoryStateImpl> merge() {
+ for (final DfaMemoryStateImpl state : myStates) {
+ ProgressManager.checkCanceled();
+ MultiMap<DfaVariableValue, DfaValue> distincts = getDistinctsMap(state);
+ for (DfaVariableValue var : distincts.keySet()) {
+ Map<DfaValue, Collection<DfaMemoryStateImpl>> statesByValue = getCompatibleStatesByValue(state, var, distincts);
+ if (statesByValue == null) {
+ continue;
+ }
+
+ DfaMemoryStateImpl copy = copyWithoutVar(state, var);
+
+ final Set<DfaMemoryStateImpl> complementaryStates = findComplementaryStates(var, statesByValue, copy);
+ if (complementaryStates == null) {
+ continue;
+ }
+
+ complementaryStates.add(state);
+ copy = copy.createCopy();
+ for (DfaMemoryStateImpl removedState : complementaryStates) {
+ for (DfaVariableValue unknownVar : removedState.getUnknownVariables()) {
+ copy.doFlush(unknownVar, true);
+ }
+ if (removedState.isNull(var)) {
+ copy.setVariableState(var, copy.getVariableState(var).withNullability(Nullness.NULLABLE));
+ }
+ }
+
+ List<DfaMemoryStateImpl> result = ContainerUtil.newArrayList();
+ result.add(copy);
+ result.addAll(ContainerUtil.filter(myStates, new Condition<DfaMemoryStateImpl>() {
+ @Override
+ public boolean value(DfaMemoryStateImpl state) {
+ return !complementaryStates.contains(state);
+ }
+ }));
+ return result;
+ }
+
+ }
+ return null;
+ }
+
+ private Map<Pair<DfaMemoryStateImpl, DfaVariableValue>, DfaMemoryStateImpl> myCopyCache = ContainerUtil.newHashMap();
+ private DfaMemoryStateImpl copyWithoutVar(DfaMemoryStateImpl state, DfaVariableValue var) {
+ Pair<DfaMemoryStateImpl, DfaVariableValue> key = Pair.create(state, var);
+ DfaMemoryStateImpl copy = myCopyCache.get(key);
+ if (copy == null) {
+ copy = state.createCopy();
+ copy.flushVariable(var);
+ myCopyCache.put(key, copy);
+ }
+ return copy;
+ }
+
+ @Nullable
+ private Set<DfaMemoryStateImpl> findComplementaryStates(DfaVariableValue var,
+ Map<DfaValue, Collection<DfaMemoryStateImpl>> statesByValue,
+ DfaMemoryStateImpl mainCopy) {
+ Set<DfaMemoryStateImpl> removedStates = ContainerUtil.newTroveSet(ContainerUtil.<DfaMemoryStateImpl>identityStrategy());
+
+ eachValue:
+ for (DfaValue value : statesByValue.keySet()) {
+ for (DfaMemoryStateImpl originalState : statesByValue.get(value)) {
+ if (mainCopy.equalsByRelations(copyWithoutVar(originalState, var))) {
+ removedStates.add(originalState);
+ continue eachValue;
+ }
+ }
+ return null;
+ }
+ return removedStates;
+ }
+
+ @Nullable
+ private Map<DfaValue, Collection<DfaMemoryStateImpl>> getCompatibleStatesByValue(final DfaMemoryStateImpl state,
+ final DfaVariableValue var,
+ MultiMap<DfaVariableValue, DfaValue> distincts) {
+ Map<DfaValue, Collection<DfaMemoryStateImpl>> statesByValue = ContainerUtil.newHashMap();
+ for (DfaValue value : distincts.get(var)) {
+ List<DfaMemoryStateImpl> compatible = ContainerUtil.filter(myStatesByEq.get(createPair(var, value)), new Condition<DfaMemoryStateImpl>() {
+ @Override
+ public boolean value(DfaMemoryStateImpl state2) {
+ return areCompatible(state, state2, var);
+ }
+ });
+ if (compatible.isEmpty()) {
+ return null;
+ }
+ statesByValue.put(value, compatible);
+ }
+ return statesByValue;
+ }
+
+ private boolean areCompatible(DfaMemoryStateImpl state1, DfaMemoryStateImpl state2, DfaVariableValue differentVar) {
+ if (!state1.equalsSuperficially(state2)) {
+ return false;
+ }
+ Map<DfaVariableValue, DfaConstValue> varValues1 = myVarValues.get(state1);
+ Map<DfaVariableValue, DfaConstValue> varValues2 = myVarValues.get(state2);
+
+ for (DfaVariableValue var : varValues1.keySet()) {
+ if (var != differentVar && varValues1.get(var) != varValues2.get(var)) {
+ return false;
+ }
+ }
+ for (DfaVariableValue var : varValues2.keySet()) {
+ if (var != differentVar && !varValues1.containsKey(var)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static MultiMap<DfaVariableValue, DfaValue> getDistinctsMap(DfaMemoryStateImpl state) {
+ MultiMap<DfaVariableValue, DfaValue> distincts = new MultiMap<DfaVariableValue, DfaValue>();
+ for (UnorderedPair<EqClass> classPair : state.getDistinctClassPairs()) {
+ for (DfaValue value1 : classPair.first.getMemberValues()) {
+ value1 = DfaMemoryStateImpl.unwrap(value1);
+ for (DfaValue value2 : classPair.second.getMemberValues()) {
+ value2 = DfaMemoryStateImpl.unwrap(value2);
+ if (value1 instanceof DfaVariableValue) {
+ if (value2 instanceof DfaVariableValue || value2 instanceof DfaConstValue) {
+ distincts.putValue((DfaVariableValue)value1, value2);
+ }
+ }
+ if (value2 instanceof DfaVariableValue) {
+ if (value1 instanceof DfaVariableValue || value1 instanceof DfaConstValue) {
+ distincts.putValue((DfaVariableValue)value2, value1);
+ }
+ }
+ }
+ }
+ }
+ return distincts;
+ }
+
+ private static List<UnorderedPair<DfaValue>> getEqPairs(DfaMemoryStateImpl state) {
+ Set<UnorderedPair<DfaValue>> eqPairs = ContainerUtil.newHashSet();
+ for (EqClass eqClass : state.getNonTrivialEqClasses()) {
+ DfaConstValue constant = eqClass.findConstant(true);
+ List<DfaVariableValue> vars = eqClass.getVariables();
+ for (int i = 0; i < vars.size(); i++) {
+ DfaVariableValue var = vars.get(i);
+ if (constant != null) {
+ eqPairs.add(createPair(var, constant));
+ }
+ for (int j = i + 1; j < vars.size(); j++) {
+ eqPairs.add(createPair(var, vars.get(j)));
+ }
+ }
+ }
+ return ContainerUtil.newArrayList(eqPairs);
+ }
+
+ private static UnorderedPair<DfaValue> createPair(DfaVariableValue var, DfaValue val) {
+ return new UnorderedPair<DfaValue>(var, val);
+ }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java
index e4631d66..87aa897 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java
@@ -16,10 +16,14 @@
package com.intellij.codeInspection.dataFlow;
+import com.intellij.codeInspection.dataFlow.value.DfaPsiType;
import com.intellij.codeInspection.dataFlow.value.DfaValue;
import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
import com.intellij.psi.PsiExpression;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Set;
/**
* @author Gregory.Shrago
@@ -36,9 +40,13 @@
super(factory);
}
+ MyDfaMemoryState(DfaMemoryStateImpl toCopy) {
+ super(toCopy);
+ }
+
@Override
- protected DfaMemoryStateImpl createNew() {
- return new MyDfaMemoryState(getFactory());
+ public DfaMemoryStateImpl createCopy() {
+ return new MyDfaMemoryState(this);
}
@Override
@@ -49,21 +57,37 @@
}
static class ValuableDfaVariableState extends DfaVariableState {
- DfaValue myValue;
- PsiExpression myExpression;
+ final DfaValue myValue;
+ final PsiExpression myExpression;
private ValuableDfaVariableState(final DfaVariableValue psiVariable) {
super(psiVariable);
+ myValue = null;
+ myExpression = null;
}
- protected ValuableDfaVariableState(final ValuableDfaVariableState state) {
- super(state);
- myExpression = state.myExpression;
+ private ValuableDfaVariableState(Set<DfaPsiType> instanceofValues,
+ Set<DfaPsiType> notInstanceofValues,
+ Nullness nullability, DfaValue value, PsiExpression expression) {
+ super(instanceofValues, notInstanceofValues, nullability);
+ myValue = value;
+ myExpression = expression;
}
@Override
- public void setValue(final DfaValue value) {
- myValue = value;
+ protected DfaVariableState createCopy(Set<DfaPsiType> instanceofValues, Set<DfaPsiType> notInstanceofValues, Nullness nullability) {
+ return new ValuableDfaVariableState(instanceofValues, notInstanceofValues, nullability, myValue, myExpression);
+ }
+
+ @Override
+ public DfaVariableState withValue(@Nullable final DfaValue value) {
+ if (value == myValue) return this;
+ return new ValuableDfaVariableState(myInstanceofValues, myNotInstanceofValues, myNullability, value, myExpression);
+ }
+
+ public ValuableDfaVariableState withExpression(@Nullable final PsiExpression expression) {
+ if (expression == myExpression) return this;
+ return new ValuableDfaVariableState(myInstanceofValues, myNotInstanceofValues, myNullability, myValue, expression);
}
@Override
@@ -72,8 +96,25 @@
}
@Override
- protected ValuableDfaVariableState clone() {
- return new ValuableDfaVariableState(this);
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ValuableDfaVariableState)) return false;
+ if (!super.equals(o)) return false;
+
+ ValuableDfaVariableState state = (ValuableDfaVariableState)o;
+
+ if (myExpression != null ? !myExpression.equals(state.myExpression) : state.myExpression != null) return false;
+ if (myValue != null ? !myValue.equals(state.myValue) : state.myValue != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (myValue != null ? myValue.hashCode() : 0);
+ result = 31 * result + (myExpression != null ? myExpression.hashCode() : 0);
+ return result;
}
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java
index dd2514c4..6e64a6b 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java
@@ -33,6 +33,7 @@
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import static com.intellij.psi.JavaTokenType.*;
@@ -41,11 +42,10 @@
private final IElementType myOperationSign;
private final Project myProject;
- public BinopInstruction(IElementType opSign, PsiElement psiAnchor, @NotNull Project project) {
+ public BinopInstruction(IElementType opSign, @Nullable PsiElement psiAnchor, @NotNull Project project) {
+ super(psiAnchor);
myProject = project;
myOperationSign = ourSignificantOperations.contains(opSign) ? opSign : null;
-
- setPsiAnchor(psiAnchor);
}
@Override
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java
index d1524fc..0f83d84 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java
@@ -27,17 +27,19 @@
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiLiteralExpression;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
public abstract class BranchingInstruction extends Instruction {
private boolean myIsTrueReachable;
private boolean myIsFalseReachable;
- private boolean isConstTrue;
- private PsiElement myExpression;
+ private final boolean isConstTrue;
+ private final PsiElement myExpression;
- protected BranchingInstruction() {
+ protected BranchingInstruction(@Nullable PsiElement psiAnchor) {
myIsTrueReachable = false;
myIsFalseReachable = false;
- setPsiAnchor(null);
+ myExpression = psiAnchor;
+ isConstTrue = psiAnchor != null && isBoolConst(psiAnchor);
}
public boolean isTrueReachable() {
@@ -70,8 +72,4 @@
return "true".equals(text) || "false".equals(text);
}
- protected void setPsiAnchor(PsiElement psiAnchor) {
- myExpression = psiAnchor;
- isConstTrue = psiAnchor != null && isBoolConst(psiAnchor);
- }
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java
index 2b93e95..212a02f 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java
@@ -33,9 +33,9 @@
private final boolean myIsNegated;
public ConditionalGotoInstruction(ControlFlow.ControlFlowOffset myOffset, boolean isNegated, PsiElement psiAnchor) {
+ super(psiAnchor);
this.myOffset = myOffset;
myIsNegated = isNegated;
- setPsiAnchor(psiAnchor);
}
public boolean isNegated() {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java
index 9d2a594..dc1fd6f 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java
@@ -27,15 +27,19 @@
mySubprogramOffset = subprogramOffset;
}
+ public int getSubprogramOffset() {
+ return mySubprogramOffset.getInstructionOffset();
+ }
+
@Override
public DfaInstructionState[] accept(DataFlowRunner runner, DfaMemoryState stateBefore, InstructionVisitor visitor) {
final int returnIndex = getIndex() + 1;
stateBefore.pushOffset(returnIndex);
- Instruction nextInstruction = runner.getInstruction(mySubprogramOffset.getInstructionOffset());
+ Instruction nextInstruction = runner.getInstruction(getSubprogramOffset());
return new DfaInstructionState[] {new DfaInstructionState(nextInstruction, stateBefore)};
}
public String toString() {
- return "GOSUB: " + mySubprogramOffset.getInstructionOffset();
+ return "GOSUB: " + getSubprogramOffset();
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java
index 3286090..c4400f7 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java
@@ -34,14 +34,18 @@
this.myOffset = myOffset;
}
+ public int getOffset() {
+ return myOffset.getInstructionOffset();
+ }
+
@Override
public DfaInstructionState[] accept(DataFlowRunner runner, DfaMemoryState stateBefore, InstructionVisitor visitor) {
- Instruction nextInstruction = runner.getInstruction(myOffset.getInstructionOffset());
+ Instruction nextInstruction = runner.getInstruction(getOffset());
return new DfaInstructionState[]{new DfaInstructionState(nextInstruction, stateBefore)};
}
public String toString() {
- return "GOTO: " + myOffset.getInstructionOffset();
+ return "GOTO: " + getOffset();
}
public void setOffset(final int offset) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
index 5514268..096188e 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
@@ -28,18 +28,9 @@
import com.intellij.codeInspection.dataFlow.DfaInstructionState;
import com.intellij.codeInspection.dataFlow.DfaMemoryState;
import com.intellij.codeInspection.dataFlow.InstructionVisitor;
-import com.intellij.openapi.progress.ProgressManager;
-
-import java.util.ArrayList;
-import java.util.List;
public abstract class Instruction {
private int myIndex;
- private final List<DfaMemoryState> myProcessedStates;
-
- protected Instruction() {
- myProcessedStates = new ArrayList<DfaMemoryState>();
- }
protected final DfaInstructionState[] nextInstruction(DataFlowRunner runner, DfaMemoryState stateBefore) {
return new DfaInstructionState[] {new DfaInstructionState(runner.getInstruction(getIndex() + 1), stateBefore)};
@@ -47,23 +38,6 @@
public abstract DfaInstructionState[] accept(DataFlowRunner runner, DfaMemoryState stateBefore, InstructionVisitor visitor);
- public boolean isMemoryStateProcessed(DfaMemoryState dfaMemState) {
- for (DfaMemoryState state : myProcessedStates) {
- ProgressManager.checkCanceled();
- if (dfaMemState.equals(state)) {
- return true;
- }
- }
-
- return false;
- }
-
- public boolean setMemoryStateProcessed(DfaMemoryState dfaMemState) {
- if (myProcessedStates.size() > DataFlowRunner.MAX_STATES_PER_BRANCH) return false;
- myProcessedStates.add(dfaMemState);
- return true;
- }
-
public void setIndex(int index) {
myIndex = index;
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaPsiType.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaPsiType.java
new file mode 100644
index 0000000..f58e44f
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaPsiType.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.dataFlow.value;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.PsiType;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Map;
+
+/**
+ * @author peter
+ */
+public class DfaPsiType {
+ private final PsiType myPsiType;
+ private final Map<Pair<DfaPsiType, DfaPsiType>, Boolean> myAssignableCache;
+ private final Map<Pair<DfaPsiType, DfaPsiType>, Boolean> myConvertibleCache;
+
+ DfaPsiType(@NotNull PsiType psiType, Map<Pair<DfaPsiType, DfaPsiType>, Boolean> assignableCache, Map<Pair<DfaPsiType, DfaPsiType>, Boolean> convertibleCache) {
+ myPsiType = psiType;
+ myAssignableCache = assignableCache;
+ myConvertibleCache = convertibleCache;
+ }
+
+ @NotNull
+ public PsiType getPsiType() {
+ return myPsiType;
+ }
+
+ public boolean isAssignableFrom(DfaPsiType other) {
+ if (other == this) return true;
+ Pair<DfaPsiType, DfaPsiType> key = Pair.create(this, other);
+ Boolean result = myAssignableCache.get(key);
+ if (result == null) {
+ myAssignableCache.put(key, result = myPsiType.isAssignableFrom(other.myPsiType));
+ }
+ return result;
+ }
+
+ public boolean isConvertibleFrom(DfaPsiType other) {
+ if (other == this) return true;
+ Pair<DfaPsiType, DfaPsiType> key = Pair.create(this, other);
+ Boolean result = myConvertibleCache.get(key);
+ if (result == null) {
+ myConvertibleCache.put(key, result = myPsiType.isConvertibleFrom(other.myPsiType));
+ }
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return myPsiType.getPresentableText();
+ }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java
index f7b6487..193d342 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java
@@ -25,72 +25,51 @@
package com.intellij.codeInspection.dataFlow.value;
import com.intellij.codeInspection.dataFlow.Nullness;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.PsiKeyword;
-import com.intellij.psi.PsiType;
-import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.util.containers.HashMap;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
+import java.util.Map;
public class DfaTypeValue extends DfaValue {
public static class Factory {
- private final DfaTypeValue mySharedInstance;
- private final HashMap<String,ArrayList<DfaTypeValue>> myStringToObject;
+ private final Map<DfaPsiType,ArrayList<DfaTypeValue>> myCache = ContainerUtil.newHashMap();
private final DfaValueFactory myFactory;
Factory(DfaValueFactory factory) {
myFactory = factory;
- mySharedInstance = new DfaTypeValue(factory);
- myStringToObject = new HashMap<String, ArrayList<DfaTypeValue>>();
}
@NotNull
- public DfaTypeValue createTypeValue(@NotNull PsiType type, @NotNull Nullness nullable) {
- type = TypeConversionUtil.erasure(type);
- mySharedInstance.myType = type;
- mySharedInstance.myCanonicalText = StringUtil.notNullize(type.getCanonicalText(), PsiKeyword.NULL);
- mySharedInstance.myNullness = nullable;
-
- String id = mySharedInstance.toString();
- ArrayList<DfaTypeValue> conditions = myStringToObject.get(id);
+ public DfaTypeValue createTypeValue(@NotNull DfaPsiType type, @NotNull Nullness nullness) {
+ ArrayList<DfaTypeValue> conditions = myCache.get(type);
if (conditions == null) {
conditions = new ArrayList<DfaTypeValue>();
- myStringToObject.put(id, conditions);
+ myCache.put(type, conditions);
} else {
for (DfaTypeValue aType : conditions) {
- if (aType.hardEquals(mySharedInstance)) return aType;
+ if (aType.myNullness == nullness) return aType;
}
}
- DfaTypeValue result = new DfaTypeValue(type, nullable, myFactory, mySharedInstance.myCanonicalText);
+ DfaTypeValue result = new DfaTypeValue(type, nullness, myFactory);
conditions.add(result);
- return result;
+ return new DfaTypeValue(type, nullness, myFactory);
}
- public DfaTypeValue createTypeValue(@NotNull PsiType type) {
- return createTypeValue(type, Nullness.UNKNOWN);
- }
}
- private PsiType myType;
- private String myCanonicalText;
+ private DfaPsiType myType;
private Nullness myNullness;
- private DfaTypeValue(DfaValueFactory factory) {
- super(factory);
- }
-
- private DfaTypeValue(PsiType type, Nullness nullness, DfaValueFactory factory, String canonicalText) {
+ private DfaTypeValue(DfaPsiType type, Nullness nullness, DfaValueFactory factory) {
super(factory);
myType = type;
myNullness = nullness;
- myCanonicalText = canonicalText;
}
- public PsiType getType() {
+ public DfaPsiType getDfaType() {
return myType;
}
@@ -102,23 +81,13 @@
return myNullness == Nullness.NOT_NULL;
}
+ public Nullness getNullness() {
+ return myNullness;
+ }
+
@NonNls
public String toString() {
- return myCanonicalText + ", nullable=" + myNullness;
+ return myType + ", nullable=" + myNullness;
}
- private boolean hardEquals(DfaTypeValue aType) {
- return myCanonicalText.equals(aType.myCanonicalText) && myNullness == aType.myNullness && myType.equals(aType.myType);
- }
-
- public boolean isAssignableFrom(DfaTypeValue dfaType) {
- return dfaType != null && myType.isAssignableFrom(dfaType.myType);
- }
-
- public boolean isConvertibleFrom(DfaTypeValue dfaType) {
- if (dfaType == null) return false;
- assert myType.isValid() : "my type invalid";
- assert dfaType.myType.isValid() : " their type invalid";
- return myType.isConvertibleFrom(dfaType.myType);
- }
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java
index e19b3ce..c78bfb1 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java
@@ -21,13 +21,7 @@
protected DfaValue(final DfaValueFactory factory) {
myFactory = factory;
- if (factory == null) {
- myID = 0;
- }
- else {
- myID = factory.createID();
- factory.registerValue(this);
- }
+ myID = factory == null ? 0 : factory.registerValue(this);
}
public int getID() {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java
index f6b900f..70cb578 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java
@@ -25,24 +25,26 @@
package com.intellij.codeInspection.dataFlow.value;
import com.intellij.codeInspection.dataFlow.Nullness;
-import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
import com.intellij.psi.util.PsiTreeUtil;
-import gnu.trove.TIntObjectHashMap;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public class DfaValueFactory {
- private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.value.DfaValueFactory");
+import java.util.List;
+import java.util.Map;
- private int myLastID;
- private final TIntObjectHashMap<DfaValue> myValues;
+public class DfaValueFactory {
+ private final List<DfaValue> myValues = ContainerUtil.newArrayList();
+ private final Map<Pair<DfaPsiType, DfaPsiType>, Boolean> myAssignableCache = ContainerUtil.newHashMap();
+ private final Map<Pair<DfaPsiType, DfaPsiType>, Boolean> myConvertibleCache = ContainerUtil.newHashMap();
+ private final Map<PsiType, DfaPsiType> myDfaTypes = ContainerUtil.newHashMap();
public DfaValueFactory() {
- myValues = new TIntObjectHashMap<DfaValue>();
- myLastID = 0;
-
+ myValues.add(null);
myVarFactory = new DfaVariableValue.Factory(this);
myConstFactory = new DfaConstValue.Factory(this);
myBoxedFactory = new DfaBoxedValue.Factory(this);
@@ -52,17 +54,20 @@
public DfaValue createTypeValue(@Nullable PsiType type, Nullness nullability) {
if (type == null) return DfaUnknownValue.getInstance();
- return getTypeFactory().createTypeValue(type, nullability);
+ return getTypeFactory().createTypeValue(internType(type), nullability);
}
- int createID() {
- myLastID++;
- LOG.assertTrue(myLastID >= 0, "Overflow");
- return myLastID;
+ private DfaPsiType internType(@NotNull PsiType psiType) {
+ DfaPsiType dfaType = myDfaTypes.get(psiType);
+ if (dfaType == null) {
+ myDfaTypes.put(psiType, dfaType = new DfaPsiType(TypeConversionUtil.erasure(psiType), myAssignableCache, myConvertibleCache));
+ }
+ return dfaType;
}
- void registerValue(DfaValue value) {
- myValues.put(value.getID(), value);
+ int registerValue(DfaValue value) {
+ myValues.add(value);
+ return myValues.size() - 1;
}
public DfaValue getValue(int id) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
index e522b8f..fa2217a 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
@@ -30,6 +30,7 @@
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Trinity;
import com.intellij.psi.*;
+import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
@@ -90,7 +91,7 @@
myIsNegated = isNegated;
myQualifier = qualifier;
myVarType = varType;
- myTypeValue = varType == null ? null : myFactory.getTypeFactory().createTypeValue(varType, Nullness.UNKNOWN);
+ myTypeValue = varType == null ? null : (DfaTypeValue)myFactory.createTypeValue(varType, Nullness.UNKNOWN);
}
@Nullable
@@ -132,7 +133,7 @@
private boolean hardEquals(PsiModifierListOwner psiVar, PsiType varType, boolean negated, DfaVariableValue qualifier) {
return psiVar == myVariable &&
- Comparing.equal(varType, myVarType) &&
+ Comparing.equal(TypeConversionUtil.erasure(varType), TypeConversionUtil.erasure(myVarType)) &&
negated == myIsNegated &&
(myQualifier == null ? qualifier == null : myQualifier.hardEquals(qualifier.getPsiVariable(), qualifier.getVariableType(),
qualifier.isNegated(), qualifier.getQualifier()));
@@ -143,10 +144,6 @@
return myQualifier;
}
- public boolean isViaMethods() {
- return myVariable instanceof PsiMethod || myQualifier != null && myQualifier.isViaMethods();
- }
-
public Nullness getInherentNullability() {
if (myInherentNullability != null) {
return myInherentNullability;
@@ -190,14 +187,12 @@
return Nullness.UNKNOWN;
}
- public boolean isLocalVariable() {
- return myVariable instanceof PsiLocalVariable || myVariable instanceof PsiParameter;
- }
-
public boolean isFlushableByCalls() {
- if (isLocalVariable()) return false;
- if (!myVariable.hasModifierProperty(PsiModifier.FINAL)) return true;
- return myQualifier != null && myQualifier.isFlushableByCalls();
+ if (myVariable instanceof PsiLocalVariable || myVariable instanceof PsiParameter) return false;
+ if (myVariable instanceof PsiVariable && myVariable.hasModifierProperty(PsiModifier.FINAL)) {
+ return myQualifier != null && myQualifier.isFlushableByCalls();
+ }
+ return true;
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaUtilImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaUtilImpl.java
index 71fa80a..c46bfb6 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaUtilImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaUtilImpl.java
@@ -223,7 +223,7 @@
refParent = refParent.getOwner();
}
- return (RefClass)refElement;
+ return refElement instanceof RefClass ? (RefClass)refElement : null;
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
index f33c6e4..15e6d5a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
@@ -255,7 +255,7 @@
for (OverrideImplementsAnnotationsHandler each : Extensions.getExtensions(OverrideImplementsAnnotationsHandler.EP_NAME)) {
for (String annotation : each.getAnnotations(project)) {
if (moduleScope != null && facade.findClass(annotation, moduleScope) == null) continue;
- if (AnnotationUtil.isAnnotated(overridden, annotation, false, false)) {
+ if (AnnotationUtil.isAnnotated(overridden, annotation, false, false) && !AnnotationUtil.isAnnotated(method, annotation, false, false)) {
AddAnnotationPsiFix.removePhysicalAnnotations(method, each.annotationsToRemove(project, annotation));
AddAnnotationPsiFix.addPhysicalAnnotation(annotation, PsiNameValuePair.EMPTY_ARRAY, method.getModifierList());
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java
index b3434ac..9646ef9 100644
--- a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java
@@ -21,6 +21,7 @@
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.text.CharArrayUtil;
+import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -110,14 +111,18 @@
@Override
public void updateUI(final PsiAnnotationMethod p, final ParameterInfoUIContext context) {
- @NonNls StringBuffer buffer = new StringBuffer();
+ updateUIText(p, context);
+ }
+
+ public static String updateUIText(PsiAnnotationMethod p, ParameterInfoUIContext context) {
+ @NonNls StringBuilder buffer = new StringBuilder();
int highlightStartOffset;
int highlightEndOffset;
buffer.append(p.getReturnType().getPresentableText());
buffer.append(" ");
- highlightStartOffset = buffer.length();
+ highlightStartOffset = XmlStringUtil.escapeString(buffer.toString()).length();
buffer.append(p.getName());
- highlightEndOffset = buffer.length();
+ highlightEndOffset = XmlStringUtil.escapeString(buffer.toString()).length();
buffer.append("()");
if (p.getDefaultValue() != null) {
@@ -125,8 +130,8 @@
buffer.append(p.getDefaultValue().getText());
}
- context.setupUIComponentPresentation(buffer.toString(), highlightStartOffset, highlightEndOffset, false, p.isDeprecated(),
- false, context.getDefaultParameterColor());
+ return context.setupUIComponentPresentation(buffer.toString(), highlightStartOffset, highlightEndOffset, false, p.isDeprecated(),
+ false, context.getDefaultParameterColor());
}
private static PsiAnnotationMethod findAnnotationMethod(PsiFile file, int offset) {
diff --git a/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicConstantInspection.java b/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicConstantInspection.java
index 7193cc9..6fb2bc7 100644
--- a/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicConstantInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicConstantInspection.java
@@ -623,7 +623,7 @@
params.dataFlowToThis = true;
params.scope = new AnalysisScope(new LocalSearchScope(scope), manager.getProject());
- SliceRootNode rootNode = new SliceRootNode(manager.getProject(), new DuplicateMap(), SliceManager.createRootUsage(argument, params));
+ SliceRootNode rootNode = new SliceRootNode(manager.getProject(), new DuplicateMap(), SliceUsage.createRootUsage(argument, params));
Collection<? extends AbstractTreeNode> children = rootNode.getChildren().iterator().next().getChildren();
for (AbstractTreeNode child : children) {
diff --git a/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java b/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java
index fd624b1..d6be007 100644
--- a/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java
+++ b/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java
@@ -107,11 +107,13 @@
myLanguageLevel = languageLevel;
}
+ @Override
@NotNull
public Lexer getHighlightingLexer() {
return new JavaHighlightingLexer(myLanguageLevel);
}
+ @Override
@NotNull
public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
return pack(ourMap1.get(tokenType), ourMap2.get(tokenType));
diff --git a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java
index 402e7f5..f93464e 100644
--- a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java
+++ b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java
@@ -16,7 +16,7 @@
package com.intellij.ide.util.gotoByName;
import com.intellij.ide.util.DefaultPsiElementCellRenderer;
-import com.intellij.navigation.ChooseByNameContributor;
+import com.intellij.navigation.ChooseByNameContributorEx;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -26,7 +26,9 @@
import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.Processor;
import com.intellij.util.containers.HashSet;
+import com.intellij.util.indexing.IdFilter;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -34,7 +36,7 @@
import java.util.Comparator;
import java.util.List;
-public class DefaultSymbolNavigationContributor implements ChooseByNameContributor {
+public class DefaultSymbolNavigationContributor implements ChooseByNameContributorEx {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.gotoByName.DefaultSymbolNavigationContributor");
@Override
@@ -91,6 +93,13 @@
return false;
}
+ public void processNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+ PsiShortNamesCache cache = PsiShortNamesCache.getInstance(scope.getProject());
+ cache.processAllClassNames(processor, scope, filter);
+ cache.processAllFieldNames(processor, scope, filter);
+ cache.processAllMethodNames(processor, scope, filter);
+ }
+
private static class MyComparator implements Comparator<PsiModifierListOwner>{
public static final MyComparator INSTANCE = new MyComparator();
diff --git a/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java b/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java
index 918b8ff..7ee3d7b 100644
--- a/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java
+++ b/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java
@@ -45,7 +45,7 @@
*/
@Nullable
@Override
- public SyntaxHighlighter create(FileType fileType, @Nullable Project project, @Nullable VirtualFile file) {
+ public SyntaxHighlighter create(@NotNull FileType fileType, @Nullable Project project, @Nullable VirtualFile file) {
if (project != null && file != null) {
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
if (psiFile instanceof ClsFileImpl) {
diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java
index 7baff14..d392d7a 100644
--- a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java
+++ b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java
@@ -263,6 +263,9 @@
final Indent defaultChildIndent = getChildIndent(parent, indentOptions);
if (defaultChildIndent != null) return defaultChildIndent;
}
+ if (child.getTreeParent() instanceof PsiLambdaExpression && child instanceof PsiCodeBlock) {
+ return Indent.getNoneIndent();
+ }
return null;
}
diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java
index 1376f44..8f090b0 100644
--- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java
+++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java
@@ -795,6 +795,12 @@
{
minSpaces = 1;
minLineFeeds = 0;
+ if (myChild1 != null) {
+ ASTNode lastElement = myChild1;
+ while (lastElement.getLastChildNode() != null) lastElement = lastElement.getLastChildNode();
+ //Not to place second statement on the same line with first one, if last ends with single line comment
+ if (lastElement instanceof PsiComment && lastElement.getElementType() == JavaTokenType.END_OF_LINE_COMMENT) minLineFeeds = 1;
+ }
}
myResult = Spacing.createSpacing(minSpaces, 0, minLineFeeds, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE);
}
@@ -1086,7 +1092,7 @@
createParenthSpace(mySettings.METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE, mySettings.SPACE_WITHIN_METHOD_PARENTHESES);
}
else if (myRole1 == ChildRole.COMMA) {
- createSpaceInCode(true);
+ createSpaceInCode(mySettings.SPACE_AFTER_COMMA);
}
}
diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/wrap/impl/JavaChildBlockWrapFactory.java b/java/java-impl/src/com/intellij/psi/formatter/java/wrap/impl/JavaChildBlockWrapFactory.java
index eeeae0e..ad4d8c0 100644
--- a/java/java-impl/src/com/intellij/psi/formatter/java/wrap/impl/JavaChildBlockWrapFactory.java
+++ b/java/java-impl/src/com/intellij/psi/formatter/java/wrap/impl/JavaChildBlockWrapFactory.java
@@ -19,6 +19,7 @@
import com.intellij.formatting.Wrap;
import com.intellij.formatting.WrapType;
import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiPolyadicExpression;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.formatter.java.JavaFormatterUtil;
@@ -83,7 +84,10 @@
return Wrap.createWrap(settings.THROWS_LIST_WRAP, true);
}
else if (nodeType == JavaElementType.CODE_BLOCK) {
- return Wrap.createWrap(Wrap.NORMAL, false);
+ if (settings.KEEP_SIMPLE_METHODS_IN_ONE_LINE && node.getPsi().getParent() instanceof PsiMethod && !node.textContains('\n')) {
+ return null;
+ }
+ return Wrap.createWrap(WrapType.NORMAL, false);
}
else if (JavaFormatterUtil.isAssignment(node)) {
return Wrap.createWrap(settings.ASSIGNMENT_WRAP, true);
diff --git a/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java b/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java
index 7971d2f..e92396e 100644
--- a/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java
+++ b/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.impl.file;
+import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -23,6 +24,7 @@
import com.intellij.psi.impl.PsiManagerImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
/**
* @author yole
@@ -34,6 +36,7 @@
myManager = manager;
}
+ @NotNull
@Override
public PsiDirectory createDirectory(@NotNull final VirtualFile file) {
return new PsiJavaDirectoryImpl(myManager, file);
@@ -61,8 +64,10 @@
}
@Override
- public boolean isPackage(PsiDirectory directory) {
- return ProjectRootManager.getInstance(myManager.getProject()).getFileIndex().getPackageNameByDirectory(directory.getVirtualFile()) != null;
+ public boolean isPackage(@NotNull PsiDirectory directory) {
+ ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myManager.getProject()).getFileIndex();
+ VirtualFile virtualFile = directory.getVirtualFile();
+ return fileIndex.isUnderSourceRootOfType(virtualFile, JavaModuleSourceRootTypes.SOURCES) && fileIndex.getPackageNameByDirectory(virtualFile) != null;
}
@Override
diff --git a/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java b/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java
index 3794863..f404c40 100644
--- a/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java
+++ b/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java
@@ -24,6 +24,7 @@
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.xml.XmlElementType;
import com.intellij.psi.xml.XmlTokenType;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -35,7 +36,7 @@
@Override
@Nullable
- public Lexer getIndexingLexer(final PsiFile file) {
+ public Lexer getIndexingLexer(@NotNull final PsiFile file) {
if (file instanceof PsiJavaFile && !(file instanceof JspFile)) {
return JavaParserDefinition.createLexer(((PsiJavaFile)file).getLanguageLevel());
}
@@ -44,7 +45,7 @@
@Override
@Nullable
- public TokenSet getCommentTokenSet(final PsiFile file) {
+ public TokenSet getCommentTokenSet(@NotNull final PsiFile file) {
if (file instanceof PsiJavaFile && !(file instanceof ServerPageFile)) {
return TokenSet.orSet(StdTokenSets.COMMENT_BIT_SET, XML_COMMENT_BIT_SET, JavaDocTokenType.ALL_JAVADOC_TOKENS, XML_DATA_CHARS);
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java b/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java
index 6011081..57539ae 100644
--- a/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java
+++ b/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,13 +32,14 @@
import com.intellij.psi.jsp.JspTokenType;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
/**
* @author yole
*/
public class JspIndexPatternBuilder implements IndexPatternBuilder {
@Override
- public Lexer getIndexingLexer(final PsiFile file) {
+ public Lexer getIndexingLexer(@NotNull final PsiFile file) {
if (JspPsiUtil.isInJspFile(file)) {
EditorHighlighter highlighter = null;
@@ -67,7 +68,7 @@
}
@Override
- public TokenSet getCommentTokenSet(final PsiFile file) {
+ public TokenSet getCommentTokenSet(@NotNull final PsiFile file) {
final JspFile jspFile = JspPsiUtil.getJspFile(file);
TokenSet commentTokens = TokenSet.orSet(JavaIndexPatternBuilder.XML_COMMENT_BIT_SET, StdTokenSets.COMMENT_BIT_SET);
final ParserDefinition parserDefinition =
diff --git a/java/java-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java b/java/java-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java
index 92068c2..894b88b 100644
--- a/java/java-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java
+++ b/java/java-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.text.CharSequenceSubSequence;
+import org.jetbrains.annotations.NotNull;
/**
* @author Sergey Evdokimov
@@ -38,7 +39,7 @@
}
@Override
- public void start(CharSequence buffer, int startOffset, int endOffset, int state) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int state) {
if (myAlreadyInitializedHighlighter) {
this.buffer = buffer;
start = startOffset;
@@ -75,6 +76,7 @@
iterator.advance();
}
+ @NotNull
@Override
public CharSequence getBufferSequence() {
return buffer;
diff --git a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java
index 8c4f926..11c77dd 100644
--- a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java
@@ -87,6 +87,8 @@
private final JRadioButton myRbAccessorPackageLocal = new JRadioButton();
private DocCommentPanel myJavadocPolicy;
+ private boolean myCbUseAccessorWhenAccessibleValue;
+
{
myRbAccessorPackageLocal.setFocusable(false);
myRbAccessorPrivate.setFocusable(false);
@@ -270,13 +272,23 @@
myCbEncapsulateSet.addActionListener(checkboxListener);
myRbFieldAsIs.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
- myCbUseAccessorsWhenAccessible.setEnabled(!myRbFieldAsIs.isSelected());
+ if (myRbFieldAsIs.isSelected()) {
+ myCbUseAccessorWhenAccessibleValue = myCbUseAccessorsWhenAccessible.isSelected();
+
+ myCbUseAccessorsWhenAccessible.setSelected(true);
+ myCbUseAccessorsWhenAccessible.setEnabled(false);
+ }
+ else {
+ myCbUseAccessorsWhenAccessible.setEnabled(true);
+ myCbUseAccessorsWhenAccessible.setSelected(myCbUseAccessorWhenAccessibleValue);
+ }
}
}
);
myCbUseAccessorsWhenAccessible.setSelected(
JavaRefactoringSettings.getInstance().ENCAPSULATE_FIELDS_USE_ACCESSORS_WHEN_ACCESSIBLE
);
+ myCbUseAccessorWhenAccessibleValue = myCbUseAccessorsWhenAccessible.isSelected();
myRbFieldPrivate.setSelected(true);
myRbAccessorPublic.setSelected(true);
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
index eee40ea..c8007a3 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
@@ -330,7 +330,7 @@
}
private boolean isNotNull(PsiVariable outputVariable) {
- final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner(false);
+ final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner();
final PsiCodeBlock block = myElementFactory.createCodeBlock();
for (PsiElement element : myElements) {
block.add(element);
diff --git a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java
index 24dd3cf..ca324a0 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -261,40 +261,34 @@
protected JComponent createCenterPanel() {
final JPanel panel = new JPanel(new BorderLayout());
- final MemberSelectionPanel memberSelectionPanel =
- new MemberSelectionPanel(RefactorJBundle.message("members.to.extract.label"), memberInfo, "As enum") {
- @Override
- protected MemberSelectionTable createMemberSelectionTable(final List<MemberInfo> memberInfo, String abstractColumnHeader) {
- return new MemberSelectionTable(memberInfo, abstractColumnHeader) {
- @Nullable
- @Override
- protected Object getAbstractColumnValue(MemberInfo memberInfo) {
- if (isExtractAsEnum()) {
- final PsiMember member = memberInfo.getMember();
- if (isConstantField(member)) {
- return Boolean.valueOf(enumConstants.contains(memberInfo));
- }
- }
- return null;
- }
-
- @Override
- protected boolean isAbstractColumnEditable(int rowIndex) {
- final MemberInfo info = memberInfo.get(rowIndex);
- if (info.isChecked()) {
- final PsiMember member = info.getMember();
- if (isConstantField(member)) {
- if (enumConstants.isEmpty()) return true;
- final MemberInfo currentEnumConstant = enumConstants.get(0);
- if (((PsiField)currentEnumConstant.getMember()).getType().equals(((PsiField)member).getType())) return true;
- }
- }
- return false;
- }
- };
+ final MemberSelectionTable table = new MemberSelectionTable(memberInfo, "As enum") {
+ @Nullable
+ @Override
+ protected Object getAbstractColumnValue(MemberInfo memberInfo) {
+ if (isExtractAsEnum()) {
+ final PsiMember member = memberInfo.getMember();
+ if (isConstantField(member)) {
+ return Boolean.valueOf(enumConstants.contains(memberInfo));
+ }
}
- };
- final MemberSelectionTable table = memberSelectionPanel.getTable();
+ return null;
+ }
+
+ @Override
+ protected boolean isAbstractColumnEditable(int rowIndex) {
+ final MemberInfo info = memberInfo.get(rowIndex);
+ if (info.isChecked()) {
+ final PsiMember member = info.getMember();
+ if (isConstantField(member)) {
+ if (enumConstants.isEmpty()) return true;
+ final MemberInfo currentEnumConstant = enumConstants.get(0);
+ if (((PsiField)currentEnumConstant.getMember()).getType().equals(((PsiField)member).getType())) return true;
+ }
+ }
+ return false;
+ }
+ };
+
table.setMemberInfoModel(new DelegatingMemberInfoModel<PsiMember, MemberInfo>(table.getMemberInfoModel()) {
@Override
@@ -342,6 +336,10 @@
return cause;
}
});
+
+ final MemberSelectionPanelBase<PsiMember, MemberInfo, MemberSelectionTable> memberSelectionPanel =
+ new MemberSelectionPanelBase<PsiMember, MemberInfo, MemberSelectionTable>(RefactorJBundle.message("members.to.extract.label"), table);
+
panel.add(memberSelectionPanel, BorderLayout.CENTER);
table.addMemberInfoChangeListener(this);
extractAsEnum.addActionListener(new ActionListener() {
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java
index 223a180..dac214d 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java
@@ -158,6 +158,9 @@
}
if (parent instanceof PsiExpression) {
expression = (PsiExpression)parent;
+ if (expression.getText().equals(exprText)) {
+ return expression;
+ }
} else {
return null;
}
diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java
index 3cca01e..d0c10ba 100644
--- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -153,16 +153,17 @@
public boolean checkConflicts(final PullUpDialog dialog) {
- final MemberInfo[] infos = dialog.getSelectedMemberInfos();
+ final List<MemberInfo> infos = dialog.getSelectedMemberInfos();
+ final MemberInfo[] memberInfos = infos.toArray(new MemberInfo[infos.size()]);
final PsiClass superClass = dialog.getSuperClass();
- if (!checkWritable(superClass, infos)) return false;
+ if (!checkWritable(superClass, memberInfos)) return false;
final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
public void run() {
final PsiDirectory targetDirectory = superClass.getContainingFile().getContainingDirectory();
final PsiPackage targetPackage = targetDirectory != null ? JavaDirectoryService.getInstance().getPackage(targetDirectory) : null;
conflicts
- .putAllValues(PullUpConflictsUtil.checkConflicts(infos, mySubclass, superClass, targetPackage, targetDirectory, dialog.getContainmentVerifier()));
+ .putAllValues(PullUpConflictsUtil.checkConflicts(memberInfos, mySubclass, superClass, targetPackage, targetDirectory, dialog.getContainmentVerifier()));
}
}, RefactoringBundle.message("detecting.possible.conflicts"), true, myProject)) return false;
if (!conflicts.isEmpty()) {
diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java
index 4d5d8b5b..801612a 100644
--- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,15 +30,16 @@
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.util.*;
import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.RefactoringConflictsUtil;
import com.intellij.refactoring.util.RefactoringHierarchyUtil;
import com.intellij.refactoring.util.RefactoringUIUtil;
import com.intellij.refactoring.util.classMembers.ClassMemberReferencesVisitor;
import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier;
-import com.intellij.refactoring.util.classMembers.MemberInfo;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.VisibilityUtil;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -51,16 +52,16 @@
public class PullUpConflictsUtil {
private PullUpConflictsUtil() {}
- public static MultiMap<PsiElement, String> checkConflicts(final MemberInfo[] infos,
- PsiClass subclass,
- @Nullable PsiClass superClass,
- @NotNull PsiPackage targetPackage,
- @NotNull PsiDirectory targetDirectory,
- final InterfaceContainmentVerifier interfaceContainmentVerifier) {
+ public static MultiMap<PsiElement, String> checkConflicts(MemberInfoBase<? extends PsiMember>[] infos,
+ PsiClass subclass,
+ @Nullable PsiClass superClass,
+ @NotNull PsiPackage targetPackage,
+ @NotNull PsiDirectory targetDirectory,
+ final InterfaceContainmentVerifier interfaceContainmentVerifier) {
return checkConflicts(infos, subclass, superClass, targetPackage, targetDirectory, interfaceContainmentVerifier, true);
}
- public static MultiMap<PsiElement, String> checkConflicts(final MemberInfo[] infos,
+ public static MultiMap<PsiElement, String> checkConflicts(final MemberInfoBase<? extends PsiMember>[] infos,
@NotNull final PsiClass subclass,
@Nullable PsiClass superClass,
@NotNull final PsiPackage targetPackage,
@@ -79,7 +80,7 @@
isInterfaceTarget = false;
targetRepresentativeElement = targetDirectory;
}
- for (MemberInfo info : infos) {
+ for (MemberInfoBase<? extends PsiMember> info : infos) {
PsiMember member = info.getMember();
if (member instanceof PsiMethod) {
if (!info.isToAbstract() && !isInterfaceTarget) {
@@ -129,15 +130,15 @@
movedMembers2Super? new ConflictingUsagesOfSubClassMembers(member, movedMembers, abstractMethods, subclass, superClass,
superClass != null ? null : targetPackage, conflicts,
interfaceContainmentVerifier)
- : new ConflictingUsagesOfSuperClassMemebers(member, subclass, targetPackage, movedMembers, conflicts);
+ : new ConflictingUsagesOfSuperClassMembers(member, subclass, targetPackage, movedMembers, conflicts);
member.accept(visitor);
}
checkModuleConflictsList.add(member);
}
for (final PsiMethod method : abstractMethods) {
- checkModuleConflictsList.add(method.getParameterList());
- checkModuleConflictsList.add(method.getReturnTypeElement());
- checkModuleConflictsList.add(method.getTypeParameterList());
+ ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getParameterList());
+ ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getReturnTypeElement());
+ ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getTypeParameterList());
}
RefactoringConflictsUtil.analyzeModuleConflicts(subclass.getProject(), checkModuleConflictsList,
new UsageInfo[0], targetRepresentativeElement, conflicts);
@@ -190,8 +191,8 @@
return conflicts;
}
- private static void checkInterfaceTarget(MemberInfo[] infos, MultiMap<PsiElement, String> conflictsList) {
- for (MemberInfo info : infos) {
+ private static void checkInterfaceTarget(MemberInfoBase<? extends PsiMember>[] infos, MultiMap<PsiElement, String> conflictsList) {
+ for (MemberInfoBase<? extends PsiMember> info : infos) {
PsiElement member = info.getMember();
if (member instanceof PsiField || member instanceof PsiClass) {
@@ -214,9 +215,9 @@
}
private static void checkSuperclassMembers(PsiClass superClass,
- MemberInfo[] infos,
+ MemberInfoBase<? extends PsiMember>[] infos,
MultiMap<PsiElement, String> conflictsList) {
- for (MemberInfo info : infos) {
+ for (MemberInfoBase<? extends PsiMember> info : infos) {
PsiMember member = info.getMember();
boolean isConflict = false;
if (member instanceof PsiField) {
@@ -268,7 +269,7 @@
return false;
}
- private static class ConflictingUsagesOfSuperClassMemebers extends ClassMemberReferencesVisitor {
+ private static class ConflictingUsagesOfSuperClassMembers extends ClassMemberReferencesVisitor {
private PsiMember myMember;
private PsiClass mySubClass;
@@ -276,10 +277,10 @@
private Set<PsiMember> myMovedMembers;
private MultiMap<PsiElement, String> myConflicts;
- public ConflictingUsagesOfSuperClassMemebers(PsiMember member, PsiClass aClass,
- PsiPackage targetPackage,
- Set<PsiMember> movedMembers,
- MultiMap<PsiElement, String> conflicts) {
+ public ConflictingUsagesOfSuperClassMembers(PsiMember member, PsiClass aClass,
+ PsiPackage targetPackage,
+ Set<PsiMember> movedMembers,
+ MultiMap<PsiElement, String> conflicts) {
super(aClass);
myMember = member;
mySubClass = aClass;
diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java
index 526262e..6af5d47 100644
--- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java
@@ -28,43 +28,40 @@
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.refactoring.RefactoringBundle;
-import com.intellij.refactoring.classMembers.MemberInfoChange;
+import com.intellij.refactoring.classMembers.MemberInfoModel;
+import com.intellij.refactoring.ui.AbstractMemberSelectionTable;
import com.intellij.refactoring.ui.ClassCellRenderer;
import com.intellij.refactoring.ui.DocCommentPanel;
-import com.intellij.refactoring.ui.MemberSelectionPanel;
-import com.intellij.refactoring.ui.RefactoringDialog;
+import com.intellij.refactoring.ui.MemberSelectionTable;
import com.intellij.refactoring.util.DocCommentPolicy;
import com.intellij.refactoring.util.RefactoringHierarchyUtil;
import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier;
import com.intellij.refactoring.util.classMembers.MemberInfo;
import com.intellij.refactoring.util.classMembers.MemberInfoStorage;
import com.intellij.refactoring.util.classMembers.UsesAndInterfacesDependencyMemberInfoModel;
-import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
-import java.util.ArrayList;
import java.util.List;
/**
* @author dsl
* Date: 18.06.2002
*/
-public class PullUpDialog extends RefactoringDialog {
+public class PullUpDialog extends PullUpDialogBase<MemberInfoStorage, MemberInfo, PsiMember, PsiClass> {
private final Callback myCallback;
- private MemberSelectionPanel myMemberSelectionPanel;
- private MyMemberInfoModel myMemberInfoModel;
- private final PsiClass myClass;
- private final List<PsiClass> mySuperClasses;
- private final MemberInfoStorage myMemberInfoStorage;
- private List<MemberInfo> myMemberInfos;
private DocCommentPanel myJavaDocPanel;
- private JComboBox myClassCombo;
+
+ private final InterfaceContainmentVerifier myInterfaceContainmentVerifier = new InterfaceContainmentVerifier() {
+ public boolean checkedInterfacesContain(PsiMethod psiMethod) {
+ return PullUpHelper.checkedInterfacesContain(myMemberInfos, psiMethod);
+ }
+ };
+
private static final String PULL_UP_STATISTICS_KEY = "pull.up##";
public interface Callback {
@@ -72,42 +69,16 @@
}
public PullUpDialog(Project project, PsiClass aClass, List<PsiClass> superClasses, MemberInfoStorage memberInfoStorage, Callback callback) {
- super(project, true);
- myClass = aClass;
- mySuperClasses = superClasses;
- myMemberInfoStorage = memberInfoStorage;
- myMemberInfos = myMemberInfoStorage.getClassMemberInfos(aClass);
+ super(project, aClass, superClasses, memberInfoStorage, JavaPullUpHandler.REFACTORING_NAME);
myCallback = callback;
- setTitle(JavaPullUpHandler.REFACTORING_NAME);
-
init();
}
- @Nullable
- public PsiClass getSuperClass() {
- if (myClassCombo != null) {
- return (PsiClass) myClassCombo.getSelectedItem();
- }
- else {
- return null;
- }
- }
-
public int getJavaDocPolicy() {
return myJavaDocPanel.getPolicy();
}
- public MemberInfo[] getSelectedMemberInfos() {
- ArrayList<MemberInfo> list = new ArrayList<MemberInfo>(myMemberInfos.size());
- for (MemberInfo info : myMemberInfos) {
- if (info.isChecked() && myMemberInfoModel.isMemberEnabled(info)) {
- list.add(info);
- }
- }
- return list.toArray(new MemberInfo[list.size()]);
- }
-
protected String getDimensionServiceKey() {
return "#com.intellij.refactoring.memberPullUp.PullUpDialog";
}
@@ -116,51 +87,23 @@
return myInterfaceContainmentVerifier;
}
- protected JComponent createNorthPanel() {
- JPanel panel = new JPanel();
-
- panel.setLayout(new GridBagLayout());
- GridBagConstraints gbConstraints = new GridBagConstraints();
-
- gbConstraints.insets = new Insets(4, 0, 4, 8);
- gbConstraints.weighty = 1;
- gbConstraints.weightx = 1;
- gbConstraints.gridy = 0;
- gbConstraints.gridwidth = GridBagConstraints.REMAINDER;
- gbConstraints.fill = GridBagConstraints.BOTH;
- gbConstraints.anchor = GridBagConstraints.WEST;
- final JLabel classComboLabel = new JLabel();
- panel.add(classComboLabel, gbConstraints);
-
- myClassCombo = new JComboBox(mySuperClasses.toArray());
- myClassCombo.setRenderer(new ClassCellRenderer(myClassCombo.getRenderer()));
- classComboLabel.setText(RefactoringBundle.message("pull.up.members.to", UsageViewUtil.getLongName(myClass)));
- classComboLabel.setLabelFor(myClassCombo);
- final PsiClass preselection = getPreselection();
- int indexToSelect = 0;
- if (preselection != null) {
- indexToSelect = mySuperClasses.indexOf(preselection);
- }
- myClassCombo.setSelectedIndex(indexToSelect);
- myClassCombo.addItemListener(new ItemListener() {
+ @Override
+ protected void initClassCombo(JComboBox classCombo) {
+ classCombo.setRenderer(new ClassCellRenderer(classCombo.getRenderer()));
+ classCombo.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
- updateMemberInfo();
if (myMemberSelectionPanel != null) {
- myMemberInfoModel.setSuperClass(getSuperClass());
+ ((MyMemberInfoModel)myMemberInfoModel).setSuperClass(getSuperClass());
myMemberSelectionPanel.getTable().setMemberInfos(myMemberInfos);
myMemberSelectionPanel.getTable().fireExternalDataChange();
}
}
}
});
- gbConstraints.gridy++;
- panel.add(myClassCombo, gbConstraints);
-
- return panel;
}
- private PsiClass getPreselection() {
+ protected PsiClass getPreselection() {
PsiClass preselection = RefactoringHierarchyUtil.getNearestBaseClass(myClass, false);
final String statKey = PULL_UP_STATISTICS_KEY + myClass.getQualifiedName();
@@ -185,15 +128,6 @@
HelpManager.getInstance().invokeHelp(HelpID.MEMBERS_PULL_UP);
}
- private void updateMemberInfo() {
- final PsiClass targetClass = (PsiClass) myClassCombo.getSelectedItem();
- myMemberInfos = myMemberInfoStorage.getIntermediateMemberInfosList(targetClass);
- /*Set duplicate = myMemberInfoStorage.getDuplicatedMemberInfos(targetClass);
- for (Iterator iterator = duplicate.getSectionsIterator(); getSectionsIterator.hasNext();) {
- ((MemberInfo) iterator.next()).setChecked(false);
- }*/
- }
-
protected void doAction() {
if (!myCallback.checkConflicts(this)) return;
JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC = myJavaDocPanel.getPolicy();
@@ -203,21 +137,15 @@
StatisticsManager
.getInstance().incUseCount(new StatisticsInfo(PULL_UP_STATISTICS_KEY + myClass.getQualifiedName(), name));
}
-
- invokeRefactoring(new PullUpHelper(myClass, superClass, getSelectedMemberInfos(),
+
+ List<MemberInfo> infos = getSelectedMemberInfos();
+ invokeRefactoring(new PullUpHelper(myClass, superClass, infos.toArray(new MemberInfo[infos.size()]),
new DocCommentPolicy(getJavaDocPolicy())));
close(OK_EXIT_CODE);
}
- protected JComponent createCenterPanel() {
- JPanel panel = new JPanel(new BorderLayout());
- myMemberSelectionPanel = new MemberSelectionPanel(RefactoringBundle.message("members.to.be.pulled.up"), myMemberInfos, RefactoringBundle.message("make.abstract"));
- myMemberInfoModel = new MyMemberInfoModel();
- myMemberInfoModel.memberInfoChanged(new MemberInfoChange<PsiMember, MemberInfo>(myMemberInfos));
- myMemberSelectionPanel.getTable().setMemberInfoModel(myMemberInfoModel);
- myMemberSelectionPanel.getTable().addMemberInfoChangeListener(myMemberInfoModel);
- panel.add(myMemberSelectionPanel, BorderLayout.CENTER);
-
+ @Override
+ protected void addCustomElementsToCentralPanel(JPanel panel) {
myJavaDocPanel = new DocCommentPanel(RefactoringBundle.message("javadoc.for.abstracts"));
myJavaDocPanel.setPolicy(JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC);
boolean hasJavadoc = false;
@@ -233,14 +161,17 @@
}
UIUtil.setEnabled(myJavaDocPanel, hasJavadoc, true);
panel.add(myJavaDocPanel, BorderLayout.EAST);
- return panel;
}
- private final InterfaceContainmentVerifier myInterfaceContainmentVerifier =
- new InterfaceContainmentVerifier() {
- public boolean checkedInterfacesContain(PsiMethod psiMethod) {
- return PullUpHelper.checkedInterfacesContain(myMemberInfos, psiMethod);
- }
- };
+
+ @Override
+ protected AbstractMemberSelectionTable<PsiMember, MemberInfo> createMemberSelectionTable(List<MemberInfo> infos) {
+ return new MemberSelectionTable(infos, RefactoringBundle.message("make.abstract"));
+ }
+
+ @Override
+ protected MemberInfoModel<PsiMember, MemberInfo> createMemberInfoModel() {
+ return new MyMemberInfoModel();
+ }
private class MyMemberInfoModel extends UsesAndInterfacesDependencyMemberInfoModel {
public MyMemberInfoModel() {
@@ -296,11 +227,9 @@
PsiClass currentSuperClass = getSuperClass();
if (currentSuperClass != null && currentSuperClass.isInterface()) {
- PsiElement element = member.getMember();
- if (element instanceof PsiModifierListOwner) {
- if (((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC)) {
- return super.checkForProblems(member);
- }
+ PsiMember element = member.getMember();
+ if (element.hasModifierProperty(PsiModifier.STATIC)) {
+ return super.checkForProblems(member);
}
return OK;
}
diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java
index ea230e3..bde3f6c 100644
--- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java
+++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java
@@ -47,6 +47,7 @@
import com.intellij.psi.util.*;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
import com.intellij.refactoring.listeners.JavaRefactoringListenerManager;
import com.intellij.refactoring.listeners.impl.JavaRefactoringListenerManagerImpl;
import com.intellij.refactoring.util.*;
@@ -67,7 +68,7 @@
public class PullUpHelper extends BaseRefactoringProcessor{
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.memberPullUp.PullUpHelper");
- private static final Key<Boolean> PRESERVE_QUALIFIER = Key.<Boolean>create("PRESERVE_QUALIFIER");
+ private static final Key<Boolean> PRESERVE_QUALIFIER = Key.create("PRESERVE_QUALIFIER");
private final PsiClass mySourceClass;
private final PsiClass myTargetSuperClass;
private final boolean myIsTargetInterface;
@@ -169,158 +170,22 @@
// correct private member visibility
for (MemberInfo info : myMembersToMove) {
if (info.getMember() instanceof PsiClass && info.getOverrides() != null) continue;
- PsiModifierListOwner modifierListOwner = info.getMember();
- if (myIsTargetInterface) {
- PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PUBLIC, true);
- }
- else if (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE)) {
- if (info.isToAbstract() || willBeUsedInSubclass(modifierListOwner, movedMembers, myTargetSuperClass, mySourceClass)) {
- PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PROTECTED, true);
- }
- if (modifierListOwner instanceof PsiClass) {
- modifierListOwner.accept(new JavaRecursiveElementWalkingVisitor() {
- @Override
- public void visitMethod(PsiMethod method) {
- check(method);
- }
-
- @Override
- public void visitField(PsiField field) {
- check(field);
- }
-
- @Override
- public void visitClass(PsiClass aClass) {
- check(aClass);
- super.visitClass(aClass);
- }
-
- private void check(PsiMember member) {
- if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
- if (willBeUsedInSubclass(member, movedMembers, myTargetSuperClass, mySourceClass)) {
- PsiUtil.setModifierProperty(member, PsiModifier.PROTECTED, true);
- }
- }
- }
- });
- }
- }
+ setCorrectVisibility(movedMembers, info);
ChangeContextUtil.encodeContextInfo(info.getMember(), true);
}
final PsiSubstitutor substitutor = upDownSuperClassSubstitutor();
- final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
// do actual move
for (MemberInfo info : myMembersToMove) {
if (info.getMember() instanceof PsiMethod) {
- PsiMethod method = (PsiMethod)info.getMember();
- PsiMethod sibling = method;
- PsiMethod anchor = null;
- while (sibling != null) {
- sibling = PsiTreeUtil.getNextSiblingOfType(sibling, PsiMethod.class);
- if (sibling != null) {
- anchor = MethodSignatureUtil
- .findMethodInSuperClassBySignatureInDerived(method.getContainingClass(), myTargetSuperClass,
- sibling.getSignature(PsiSubstitutor.EMPTY), false);
- if (anchor != null) {
- break;
- }
- }
- }
- PsiMethod methodCopy = (PsiMethod)method.copy();
- if (method.findSuperMethods(myTargetSuperClass).length == 0) {
- deleteOverrideAnnotationIfFound(methodCopy);
- }
- boolean isOriginalMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT) || method.hasModifierProperty(PsiModifier.DEFAULT);
- if (myIsTargetInterface || info.isToAbstract()) {
- ChangeContextUtil.clearContextInfo(method);
-
- if (!info.isToAbstract() && !method.hasModifierProperty(PsiModifier.ABSTRACT) && PsiUtil.isLanguageLevel8OrHigher(myTargetSuperClass)) {
- //pull as default
- RefactoringUtil.makeMethodDefault(methodCopy);
- isOriginalMethodAbstract = true;
- } else {
- RefactoringUtil.makeMethodAbstract(myTargetSuperClass, methodCopy);
- }
-
- RefactoringUtil.replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
-
- myJavaDocPolicy.processCopiedJavaDoc(methodCopy.getDocComment(), method.getDocComment(), isOriginalMethodAbstract);
-
- final PsiMember movedElement = anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy);
- CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(method.getProject());
- if (styleSettings.INSERT_OVERRIDE_ANNOTATION) {
- if (PsiUtil.isLanguageLevel5OrHigher(mySourceClass) && !myTargetSuperClass.isInterface() || PsiUtil.isLanguageLevel6OrHigher(mySourceClass)) {
- new AddAnnotationFix(Override.class.getName(), method).invoke(method.getProject(), null, mySourceClass.getContainingFile());
- }
- }
- if (!PsiUtil.isLanguageLevel6OrHigher(mySourceClass) && myTargetSuperClass.isInterface()) {
- if (isOriginalMethodAbstract) {
- for (PsiMethod oMethod : OverridingMethodsSearch.search(method)) {
- deleteOverrideAnnotationIfFound(oMethod);
- }
- }
- deleteOverrideAnnotationIfFound(method);
- }
- myMembersAfterMove.add(movedElement);
- if (isOriginalMethodAbstract) {
- method.delete();
- }
- }
- else {
- if (isOriginalMethodAbstract) {
- PsiUtil.setModifierProperty(myTargetSuperClass, PsiModifier.ABSTRACT, true);
- }
- RefactoringUtil.replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
- fixReferencesToStatic(methodCopy, movedMembers);
- final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(methodCopy, false);
- if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) {
- superClassMethod.replace(methodCopy);
- }
- else {
- final PsiMember movedElement =
- anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy);
- myMembersAfterMove.add(movedElement);
- }
- method.delete();
- }
+ doMoveMethod(movedMembers, substitutor, info);
}
else if (info.getMember() instanceof PsiField) {
- PsiField field = (PsiField)info.getMember();
- field.normalizeDeclaration();
- RefactoringUtil.replaceMovedMemberTypeParameters(field, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
- fixReferencesToStatic(field, movedMembers);
- if (myIsTargetInterface) {
- PsiUtil.setModifierProperty(field, PsiModifier.PUBLIC, true);
- }
- final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(field);
- myMembersAfterMove.add(movedElement);
- field.delete();
+ doMoveField(movedMembers, substitutor, info);
}
else if (info.getMember() instanceof PsiClass) {
- PsiClass aClass = (PsiClass)info.getMember();
- if (Boolean.FALSE.equals(info.getOverrides())) {
- final PsiReferenceList sourceReferenceList = info.getSourceReferenceList();
- LOG.assertTrue(sourceReferenceList != null);
- PsiJavaCodeReferenceElement ref = mySourceClass.equals(sourceReferenceList.getParent()) ?
- RefactoringUtil.removeFromReferenceList(sourceReferenceList, aClass) :
- RefactoringUtil.findReferenceToClass(sourceReferenceList, aClass);
- if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) {
- RefactoringUtil.replaceMovedMemberTypeParameters(ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
- final PsiReferenceList referenceList =
- myTargetSuperClass.isInterface() ? myTargetSuperClass.getExtendsList() : myTargetSuperClass.getImplementsList();
- assert referenceList != null;
- referenceList.add(ref);
- }
- }
- else {
- RefactoringUtil.replaceMovedMemberTypeParameters(aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
- fixReferencesToStatic(aClass, movedMembers);
- final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(aClass);
- myMembersAfterMove.add(movedElement);
- aClass.delete();
- }
+ doMoveClass(movedMembers, substitutor, info);
}
}
@@ -357,6 +222,160 @@
}
}
+ private void setCorrectVisibility(final Set<PsiMember> movedMembers, MemberInfo info) {
+ PsiModifierListOwner modifierListOwner = info.getMember();
+ if (myIsTargetInterface) {
+ PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PUBLIC, true);
+ }
+ else if (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE)) {
+ if (info.isToAbstract() || willBeUsedInSubclass(modifierListOwner, movedMembers, myTargetSuperClass, mySourceClass)) {
+ PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PROTECTED, true);
+ }
+ if (modifierListOwner instanceof PsiClass) {
+ modifierListOwner.accept(new JavaRecursiveElementWalkingVisitor() {
+ @Override
+ public void visitMethod(PsiMethod method) {
+ check(method);
+ }
+
+ @Override
+ public void visitField(PsiField field) {
+ check(field);
+ }
+
+ @Override
+ public void visitClass(PsiClass aClass) {
+ check(aClass);
+ super.visitClass(aClass);
+ }
+
+ private void check(PsiMember member) {
+ if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
+ if (willBeUsedInSubclass(member, movedMembers, myTargetSuperClass, mySourceClass)) {
+ PsiUtil.setModifierProperty(member, PsiModifier.PROTECTED, true);
+ }
+ }
+ }
+ });
+ }
+ }
+ }
+
+ private void doMoveClass(Set<PsiMember> movedMembers, PsiSubstitutor substitutor, MemberInfo info) {
+ PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
+ PsiClass aClass = (PsiClass)info.getMember();
+ if (Boolean.FALSE.equals(info.getOverrides())) {
+ final PsiReferenceList sourceReferenceList = info.getSourceReferenceList();
+ LOG.assertTrue(sourceReferenceList != null);
+ PsiJavaCodeReferenceElement ref = mySourceClass.equals(sourceReferenceList.getParent()) ?
+ RefactoringUtil.removeFromReferenceList(sourceReferenceList, aClass) :
+ RefactoringUtil.findReferenceToClass(sourceReferenceList, aClass);
+ if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) {
+ RefactoringUtil.replaceMovedMemberTypeParameters(ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+ final PsiReferenceList referenceList =
+ myTargetSuperClass.isInterface() ? myTargetSuperClass.getExtendsList() : myTargetSuperClass.getImplementsList();
+ assert referenceList != null;
+ referenceList.add(ref);
+ }
+ }
+ else {
+ RefactoringUtil.replaceMovedMemberTypeParameters(aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+ fixReferencesToStatic(aClass, movedMembers);
+ final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(aClass);
+ myMembersAfterMove.add(movedElement);
+ aClass.delete();
+ }
+ }
+
+ private void doMoveField(Set<PsiMember> movedMembers, PsiSubstitutor substitutor, MemberInfo info) {
+ PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
+ PsiField field = (PsiField)info.getMember();
+ field.normalizeDeclaration();
+ RefactoringUtil.replaceMovedMemberTypeParameters(field, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+ fixReferencesToStatic(field, movedMembers);
+ if (myIsTargetInterface) {
+ PsiUtil.setModifierProperty(field, PsiModifier.PUBLIC, true);
+ }
+ final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(field);
+ myMembersAfterMove.add(movedElement);
+ field.delete();
+ }
+
+ private void doMoveMethod(Set<PsiMember> movedMembers, PsiSubstitutor substitutor, MemberInfo info) {
+ PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
+ PsiMethod method = (PsiMethod)info.getMember();
+ PsiMethod sibling = method;
+ PsiMethod anchor = null;
+ while (sibling != null) {
+ sibling = PsiTreeUtil.getNextSiblingOfType(sibling, PsiMethod.class);
+ if (sibling != null) {
+ anchor = MethodSignatureUtil
+ .findMethodInSuperClassBySignatureInDerived(method.getContainingClass(), myTargetSuperClass,
+ sibling.getSignature(PsiSubstitutor.EMPTY), false);
+ if (anchor != null) {
+ break;
+ }
+ }
+ }
+ PsiMethod methodCopy = (PsiMethod)method.copy();
+ if (method.findSuperMethods(myTargetSuperClass).length == 0) {
+ deleteOverrideAnnotationIfFound(methodCopy);
+ }
+ boolean isOriginalMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT) || method.hasModifierProperty(PsiModifier.DEFAULT);
+ if (myIsTargetInterface || info.isToAbstract()) {
+ ChangeContextUtil.clearContextInfo(method);
+
+ if (!info.isToAbstract() && !method.hasModifierProperty(PsiModifier.ABSTRACT) && PsiUtil.isLanguageLevel8OrHigher(myTargetSuperClass)) {
+ //pull as default
+ RefactoringUtil.makeMethodDefault(methodCopy);
+ isOriginalMethodAbstract = true;
+ } else {
+ RefactoringUtil.makeMethodAbstract(myTargetSuperClass, methodCopy);
+ }
+
+ RefactoringUtil.replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+
+ myJavaDocPolicy.processCopiedJavaDoc(methodCopy.getDocComment(), method.getDocComment(), isOriginalMethodAbstract);
+
+ final PsiMember movedElement = anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy);
+ CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(method.getProject());
+ if (styleSettings.INSERT_OVERRIDE_ANNOTATION) {
+ if (PsiUtil.isLanguageLevel5OrHigher(mySourceClass) && !myTargetSuperClass.isInterface() || PsiUtil.isLanguageLevel6OrHigher(mySourceClass)) {
+ new AddAnnotationFix(Override.class.getName(), method).invoke(method.getProject(), null, mySourceClass.getContainingFile());
+ }
+ }
+ if (!PsiUtil.isLanguageLevel6OrHigher(mySourceClass) && myTargetSuperClass.isInterface()) {
+ if (isOriginalMethodAbstract) {
+ for (PsiMethod oMethod : OverridingMethodsSearch.search(method)) {
+ deleteOverrideAnnotationIfFound(oMethod);
+ }
+ }
+ deleteOverrideAnnotationIfFound(method);
+ }
+ myMembersAfterMove.add(movedElement);
+ if (isOriginalMethodAbstract) {
+ method.delete();
+ }
+ }
+ else {
+ if (isOriginalMethodAbstract) {
+ PsiUtil.setModifierProperty(myTargetSuperClass, PsiModifier.ABSTRACT, true);
+ }
+ RefactoringUtil.replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+ fixReferencesToStatic(methodCopy, movedMembers);
+ final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(methodCopy, false);
+ if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) {
+ superClassMethod.replace(methodCopy);
+ }
+ else {
+ final PsiMember movedElement =
+ anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy);
+ myMembersAfterMove.add(movedElement);
+ }
+ method.delete();
+ }
+ }
+
private PsiSubstitutor upDownSuperClassSubstitutor() {
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(mySourceClass)) {
@@ -909,8 +928,8 @@
return false;
}
- public static boolean checkedInterfacesContain(Collection<MemberInfo> memberInfos, PsiMethod psiMethod) {
- for (MemberInfo memberInfo : memberInfos) {
+ public static boolean checkedInterfacesContain(Collection<? extends MemberInfoBase<? extends PsiMember>> memberInfos, PsiMethod psiMethod) {
+ for (MemberInfoBase<? extends PsiMember> memberInfo : memberInfos) {
if (memberInfo.isChecked() &&
memberInfo.getMember() instanceof PsiClass &&
Boolean.FALSE.equals(memberInfo.getOverrides())) {
diff --git a/java/java-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionPanel.java b/java/java-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionPanel.java
deleted file mode 100644
index 0e9397a..0000000
--- a/java/java-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionPanel.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.intellij.refactoring.ui;
-
-import com.intellij.psi.PsiElement;
-import com.intellij.refactoring.classMembers.MemberInfoBase;
-
-import javax.swing.*;
-
-/**
- * Nikolay.Tropin
- * 8/20/13
- */
-public abstract class AbstractMemberSelectionPanel<T extends PsiElement, M extends MemberInfoBase<T>> extends JPanel {
- public abstract AbstractMemberSelectionTable<T, M> getTable();
-}
diff --git a/java/java-impl/src/com/intellij/refactoring/ui/MemberSelectionPanel.java b/java/java-impl/src/com/intellij/refactoring/ui/MemberSelectionPanel.java
index c503a86..28e0a88 100644
--- a/java/java-impl/src/com/intellij/refactoring/ui/MemberSelectionPanel.java
+++ b/java/java-impl/src/com/intellij/refactoring/ui/MemberSelectionPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/java/java-impl/src/com/intellij/slicer/DuplicateMap.java b/java/java-impl/src/com/intellij/slicer/DuplicateMap.java
index a57dc5f..426efd1 100644
--- a/java/java-impl/src/com/intellij/slicer/DuplicateMap.java
+++ b/java/java-impl/src/com/intellij/slicer/DuplicateMap.java
@@ -21,6 +21,7 @@
import com.intellij.usageView.UsageInfo;
import gnu.trove.THashMap;
import gnu.trove.TObjectHashingStrategy;
+import org.jetbrains.annotations.NotNull;
import java.util.Map;
@@ -43,7 +44,7 @@
};
private final Map<SliceUsage, SliceNode> myDuplicates = new THashMap<SliceUsage, SliceNode>(USAGE_INFO_EQUALITY);
- public SliceNode putNodeCheckDupe(final SliceNode node) {
+ public SliceNode putNodeCheckDupe(@NotNull final SliceNode node) {
return ApplicationManager.getApplication().runReadAction(new Computable<SliceNode>() {
@Override
public SliceNode compute() {
diff --git a/java/java-impl/src/com/intellij/slicer/MyColoredTreeCellRenderer.java b/java/java-impl/src/com/intellij/slicer/MyColoredTreeCellRenderer.java
index 0e31373..c150e0f 100644
--- a/java/java-impl/src/com/intellij/slicer/MyColoredTreeCellRenderer.java
+++ b/java/java-impl/src/com/intellij/slicer/MyColoredTreeCellRenderer.java
@@ -15,12 +15,20 @@
*/
package com.intellij.slicer;
+import org.jetbrains.annotations.NotNull;
+
import javax.swing.*;
/**
* @author cdr
*/
public interface MyColoredTreeCellRenderer {
- void customizeCellRenderer(SliceUsageCellRenderer renderer,
- JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus);
+ void customizeCellRenderer(@NotNull SliceUsageCellRenderer renderer,
+ @NotNull JTree tree,
+ Object value,
+ boolean selected,
+ boolean expanded,
+ boolean leaf,
+ int row,
+ boolean hasFocus);
}
diff --git a/java/java-impl/src/com/intellij/slicer/SliceDereferenceUsage.java b/java/java-impl/src/com/intellij/slicer/SliceDereferenceUsage.java
index 106671f..8578c91 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceDereferenceUsage.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceDereferenceUsage.java
@@ -33,7 +33,7 @@
}
@Override
- public void processChildren(Processor<SliceUsage> processor) {
+ public void processChildren(@NotNull Processor<SliceUsage> processor) {
// no children
}
diff --git a/java/java-impl/src/com/intellij/slicer/SliceForwardUtil.java b/java/java-impl/src/com/intellij/slicer/SliceForwardUtil.java
new file mode 100644
index 0000000..364b853
--- /dev/null
+++ b/java/java-impl/src/com/intellij/slicer/SliceForwardUtil.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.slicer;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.*;
+import com.intellij.psi.search.searches.MethodReferencesSearch;
+import com.intellij.psi.search.searches.OverridingMethodsSearch;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.MethodSignatureUtil;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Processor;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * @author cdr
+ */
+public class SliceForwardUtil {
+ public static boolean processUsagesFlownFromThe(@NotNull PsiElement element, @NotNull final Processor<SliceUsage> processor, @NotNull final SliceUsage parent) {
+ Pair<PsiElement, PsiSubstitutor> pair = getAssignmentTarget(element, parent);
+ if (pair != null) {
+ PsiElement target = pair.getFirst();
+ final PsiSubstitutor substitutor = pair.getSecond();
+ if (target instanceof PsiParameter) {
+ PsiParameter parameter = (PsiParameter)target;
+ PsiElement declarationScope = parameter.getDeclarationScope();
+ if (declarationScope instanceof PsiMethod) {
+ final PsiMethod method = (PsiMethod)declarationScope;
+ final int parameterIndex = method.getParameterList().getParameterIndex(parameter);
+
+ Processor<PsiMethod> myProcessor = new Processor<PsiMethod>() {
+ @Override
+ public boolean process(PsiMethod override) {
+ if (!parent.getScope().contains(override)) return true;
+ final PsiSubstitutor superSubstitutor = method == override
+ ? substitutor
+ : MethodSignatureUtil.getSuperMethodSignatureSubstitutor(method.getSignature(substitutor),
+ override.getSignature(substitutor));
+
+ PsiParameter[] parameters = override.getParameterList().getParameters();
+ if (parameters.length <= parameterIndex) return true;
+ PsiParameter actualParam = parameters[parameterIndex];
+
+ SliceUsage usage = SliceUtil.createSliceUsage(actualParam, parent, superSubstitutor);
+ return processor.process(usage);
+ }
+ };
+ if (!myProcessor.process(method)) return false;
+ return OverridingMethodsSearch.search(method, parent.getScope().toSearchScope(), true).forEach(myProcessor);
+ }
+ }
+
+ SliceUsage usage = SliceUtil.createSliceUsage(target, parent, parent.getSubstitutor());
+ return processor.process(usage);
+ }
+
+ if (element instanceof PsiReferenceExpression) {
+ PsiReferenceExpression ref = (PsiReferenceExpression)element;
+ PsiElement resolved = ref.resolve();
+ if (!(resolved instanceof PsiVariable)) return true;
+ final PsiVariable variable = (PsiVariable)resolved;
+ return processAssignedFrom(variable, ref, parent, processor);
+ }
+ if (element instanceof PsiVariable) {
+ return processAssignedFrom(element, element, parent, processor);
+ }
+ if (element instanceof PsiMethod) {
+ return processAssignedFrom(element, element, parent, processor);
+ }
+ return true;
+ }
+
+ private static boolean processAssignedFrom(final PsiElement from, final PsiElement context, final SliceUsage parent,
+ final Processor<SliceUsage> processor) {
+ if (from instanceof PsiLocalVariable) {
+ return searchReferencesAndProcessAssignmentTarget(from, context, parent, processor);
+ }
+ if (from instanceof PsiParameter) {
+ PsiParameter parameter = (PsiParameter)from;
+ PsiElement scope = parameter.getDeclarationScope();
+ Collection<PsiParameter> parametersToAnalyze = new THashSet<PsiParameter>();
+ if (scope instanceof PsiMethod) {
+ final PsiMethod method = (PsiMethod)scope;
+ int index = method.getParameterList().getParameterIndex(parameter);
+
+ Collection<PsiMethod> superMethods = new THashSet<PsiMethod>(Arrays.asList(method.findDeepestSuperMethods()));
+ superMethods.add(method);
+ for (Iterator<PsiMethod> iterator = superMethods.iterator(); iterator.hasNext(); ) {
+ SliceManager.getInstance(method.getProject()).checkCanceled();
+ PsiMethod superMethod = iterator.next();
+ if (!parent.params.scope.contains(superMethod)) {
+ iterator.remove();
+ }
+ }
+
+ final THashSet<PsiMethod> implementors = new THashSet<PsiMethod>(superMethods);
+ for (PsiMethod superMethod : superMethods) {
+ SliceManager.getInstance(method.getProject()).checkCanceled();
+ if (!OverridingMethodsSearch.search(superMethod, parent.getScope().toSearchScope(), true).forEach(new Processor<PsiMethod>() {
+ @Override
+ public boolean process(PsiMethod sub) {
+ SliceManager.getInstance(method.getProject()).checkCanceled();
+ implementors.add(sub);
+ return true;
+ }
+ })) return false;
+ }
+ for (PsiMethod implementor : implementors) {
+ SliceManager.getInstance(method.getProject()).checkCanceled();
+ if (!parent.params.scope.contains(implementor)) continue;
+ if (implementor instanceof PsiCompiledElement) implementor = (PsiMethod)implementor.getNavigationElement();
+
+ PsiParameter[] parameters = implementor.getParameterList().getParameters();
+ if (index != -1 && index < parameters.length) {
+ parametersToAnalyze.add(parameters[index]);
+ }
+ }
+ }
+ else {
+ parametersToAnalyze.add(parameter);
+ }
+ for (final PsiParameter psiParameter : parametersToAnalyze) {
+ SliceManager.getInstance(from.getProject()).checkCanceled();
+
+ if (!searchReferencesAndProcessAssignmentTarget(psiParameter, null, parent, processor)) return false;
+ }
+ return true;
+ }
+ if (from instanceof PsiField) {
+ return searchReferencesAndProcessAssignmentTarget(from, null, parent, processor);
+ }
+
+ if (from instanceof PsiMethod) {
+ PsiMethod method = (PsiMethod)from;
+
+ Collection<PsiMethod> superMethods = new THashSet<PsiMethod>(Arrays.asList(method.findDeepestSuperMethods()));
+ superMethods.add(method);
+ final Set<PsiReference> processed = new THashSet<PsiReference>(); //usages of super method and overridden method can overlap
+ for (final PsiMethod containingMethod : superMethods) {
+ if (!MethodReferencesSearch.search(containingMethod, parent.getScope().toSearchScope(), true).forEach(new Processor<PsiReference>() {
+ @Override
+ public boolean process(final PsiReference reference) {
+ SliceManager.getInstance(from.getProject()).checkCanceled();
+ synchronized (processed) {
+ if (!processed.add(reference)) return true;
+ }
+ PsiElement element = reference.getElement().getParent();
+
+ return processAssignmentTarget(element, parent, processor);
+ }
+ })) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private static boolean searchReferencesAndProcessAssignmentTarget(@NotNull PsiElement element, @Nullable final PsiElement context, final SliceUsage parent,
+ final Processor<SliceUsage> processor) {
+ return ReferencesSearch.search(element).forEach(new Processor<PsiReference>() {
+ @Override
+ public boolean process(PsiReference reference) {
+ PsiElement element = reference.getElement();
+ if (context != null && element.getTextOffset() < context.getTextOffset()) return true;
+ return processAssignmentTarget(element, parent, processor);
+ }
+ });
+ }
+
+ private static boolean processAssignmentTarget(PsiElement element, final SliceUsage parent, final Processor<SliceUsage> processor) {
+ if (!parent.params.scope.contains(element)) return true;
+ if (element instanceof PsiCompiledElement) element = element.getNavigationElement();
+ Pair<PsiElement, PsiSubstitutor> pair = getAssignmentTarget(element, parent);
+ if (pair != null) {
+ SliceUsage usage = SliceUtil.createSliceUsage(element, parent, pair.getSecond());
+ return processor.process(usage);
+ }
+ if (parent.params.showInstanceDereferences && isDereferenced(element)) {
+ SliceUsage usage = new SliceDereferenceUsage(element.getParent(), parent, parent.getSubstitutor());
+ return processor.process(usage);
+ }
+ return true;
+ }
+
+ private static boolean isDereferenced(PsiElement element) {
+ if (!(element instanceof PsiReferenceExpression)) return false;
+ PsiElement parent = element.getParent();
+ if (!(parent instanceof PsiReferenceExpression)) return false;
+ return ((PsiReferenceExpression)parent).getQualifierExpression() == element;
+ }
+
+ private static Pair<PsiElement,PsiSubstitutor> getAssignmentTarget(PsiElement element, SliceUsage parentUsage) {
+ element = complexify(element);
+ PsiElement target = null;
+ PsiSubstitutor substitutor = parentUsage.getSubstitutor();
+ //assignment
+ PsiElement parent = element.getParent();
+ if (parent instanceof PsiAssignmentExpression) {
+ PsiAssignmentExpression assignment = (PsiAssignmentExpression)parent;
+ if (element.equals(assignment.getRExpression())) {
+ PsiElement left = assignment.getLExpression();
+ if (left instanceof PsiReferenceExpression) {
+ JavaResolveResult result = ((PsiReferenceExpression)left).advancedResolve(false);
+ target = result.getElement();
+ substitutor = result.getSubstitutor();
+ }
+ }
+ }
+ else if (parent instanceof PsiVariable) {
+ PsiVariable variable = (PsiVariable)parent;
+
+ PsiElement initializer = variable.getInitializer();
+ if (element.equals(initializer)) {
+ target = variable;
+ }
+ }
+ //method call
+ else if (parent instanceof PsiExpressionList && parent.getParent() instanceof PsiCallExpression) {
+ PsiExpression[] expressions = ((PsiExpressionList)parent).getExpressions();
+ int index = ArrayUtil.find(expressions, element);
+ PsiCallExpression methodCall = (PsiCallExpression)parent.getParent();
+ JavaResolveResult result = methodCall.resolveMethodGenerics();
+ PsiMethod method = (PsiMethod)result.getElement();
+ if (index != -1 && method != null) {
+ PsiParameter[] parameters = method.getParameterList().getParameters();
+ if (index < parameters.length) {
+ target = parameters[index];
+ substitutor = result.getSubstitutor();
+ }
+ }
+ }
+ else if (parent instanceof PsiReturnStatement) {
+ PsiReturnStatement statement = (PsiReturnStatement)parent;
+ if (element.equals(statement.getReturnValue())) {
+ target = PsiTreeUtil.getParentOfType(statement, PsiMethod.class);
+ }
+ }
+
+ return target == null ? null : Pair.create(target, substitutor);
+ }
+
+ public static PsiElement complexify(@NotNull PsiElement element) {
+ PsiElement parent = element.getParent();
+ if (parent instanceof PsiParenthesizedExpression && element.equals(((PsiParenthesizedExpression)parent).getExpression())) {
+ return complexify(parent);
+ }
+ if (parent instanceof PsiTypeCastExpression && element.equals(((PsiTypeCastExpression)parent).getOperand())) {
+ return complexify(parent);
+ }
+ return element;
+ }
+}
diff --git a/java/java-impl/src/com/intellij/slicer/SliceLeafValueClassNode.java b/java/java-impl/src/com/intellij/slicer/SliceLeafValueClassNode.java
index 630d1cd..e73da41 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceLeafValueClassNode.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceLeafValueClassNode.java
@@ -44,8 +44,8 @@
}
@Override
- public void customizeCellRenderer(SliceUsageCellRenderer renderer,
- JTree tree,
+ public void customizeCellRenderer(@NotNull SliceUsageCellRenderer renderer,
+ @NotNull JTree tree,
Object value,
boolean selected,
boolean expanded,
diff --git a/java/java-impl/src/com/intellij/slicer/SliceLeafValueRootNode.java b/java/java-impl/src/com/intellij/slicer/SliceLeafValueRootNode.java
index a6a4030..dee98f8 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceLeafValueRootNode.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceLeafValueRootNode.java
@@ -40,7 +40,7 @@
public SliceLeafValueRootNode(@NotNull Project project, PsiElement leafExpression, SliceNode root, List<SliceNode> children,
SliceAnalysisParams params) {
- super(project, new SliceUsage(leafExpression, params), root.targetEqualUsages);
+ super(project, SliceUsage.createRootUsage(leafExpression, params), root.targetEqualUsages);
myCachedChildren = children;
}
@@ -69,8 +69,8 @@
}
@Override
- public void customizeCellRenderer(SliceUsageCellRenderer renderer,
- JTree tree,
+ public void customizeCellRenderer(@NotNull SliceUsageCellRenderer renderer,
+ @NotNull JTree tree,
Object value,
boolean selected,
boolean expanded,
@@ -99,8 +99,9 @@
@NotNull final SliceUsageCellRenderer renderer) {
PsiFile file = element.getContainingFile();
List<TextChunk> result = new ArrayList<TextChunk>();
- ChunkExtractor.getExtractor(element.getContainingFile()).createTextChunks(usage, file.getText(), element.getTextRange().getStartOffset(), element.getTextRange().getEndOffset(),
- false, result);
+ ChunkExtractor.getExtractor(element.getContainingFile())
+ .createTextChunks(usage, file.getText(), element.getTextRange().getStartOffset(), element.getTextRange().getEndOffset(),
+ false, result);
for (TextChunk chunk : result) {
renderer.append(chunk.getText(), chunk.getSimpleAttributesIgnoreBackground());
diff --git a/java/java-impl/src/com/intellij/slicer/SliceManager.java b/java/java-impl/src/com/intellij/slicer/SliceManager.java
index eee7e96..42cac25 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceManager.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceManager.java
@@ -124,7 +124,7 @@
SliceAnalysisParams params = handler.askForParams(element, dataFlowToThis, myStoredSettings, dialogTitle);
if (params == null) return;
- SliceRootNode rootNode = new SliceRootNode(myProject, new DuplicateMap(), createRootUsage(element, params));
+ SliceRootNode rootNode = new SliceRootNode(myProject, new DuplicateMap(), SliceUsage.createRootUsage(element, params));
createToolWindow(dataFlowToThis, rootNode, false, getElementDescription(null, element, null));
}
@@ -179,10 +179,6 @@
"</body></html>";
}
- public static SliceUsage createRootUsage(@NotNull PsiElement element, @NotNull SliceAnalysisParams params) {
- return new SliceUsage(element, params);
- }
-
public void checkCanceled() throws ProcessCanceledException {
if (myCanceled) {
throw new ProcessCanceledException();
diff --git a/java/java-impl/src/com/intellij/slicer/SliceNode.java b/java/java-impl/src/com/intellij/slicer/SliceNode.java
index df114e5..cd79d79 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceNode.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceNode.java
@@ -20,7 +20,6 @@
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.progress.impl.ProgressManagerImpl;
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
@@ -52,6 +51,7 @@
this.targetEqualUsages = targetEqualUsages;
}
+ @NotNull
SliceNode copy() {
SliceUsage newUsage = getValue().copy();
SliceNode newNode = new SliceNode(getProject(), newUsage, targetEqualUsages);
@@ -69,7 +69,7 @@
indicator.start();
}
final Collection[] nodes = new Collection[1];
- ((ProgressManagerImpl)ProgressManager.getInstance()).executeProcessUnderProgress(new Runnable(){
+ ProgressManager.getInstance().executeProcessUnderProgress(new Runnable() {
@Override
public void run() {
nodes[0] = getChildrenUnderProgress(ProgressManager.getInstance().getProgressIndicator());
@@ -89,6 +89,7 @@
return index == 0 ? null : (SliceNode)parentChildren.get(index - 1);
}
+ @NotNull
protected List<? extends AbstractTreeNode> getChildrenUnderProgress(ProgressIndicator progress) {
if (isUpToDate()) return myCachedChildren == null ? Collections.<AbstractTreeNode>emptyList() : myCachedChildren;
final List<SliceNode> children = new ArrayList<SliceNode>();
@@ -208,7 +209,7 @@
}
@Override
- public void customizeCellRenderer(SliceUsageCellRenderer renderer, JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+ public void customizeCellRenderer(@NotNull SliceUsageCellRenderer renderer, @NotNull JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
renderer.setIcon(getPresentation().getIcon(expanded));
if (isValid()) {
SliceUsage sliceUsage = getValue();
@@ -227,6 +228,7 @@
@Override
public String toString() {
return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ @Override
public String compute() {
return getValue()==null?"<null>":getValue().toString();
}
diff --git a/java/java-impl/src/com/intellij/slicer/SlicePanel.java b/java/java-impl/src/com/intellij/slicer/SlicePanel.java
index 7c40003..78e8a3e 100644
--- a/java/java-impl/src/com/intellij/slicer/SlicePanel.java
+++ b/java/java-impl/src/com/intellij/slicer/SlicePanel.java
@@ -189,13 +189,13 @@
@NotNull
private JTree createTree() {
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
- final Tree tree = new Tree(new DefaultTreeModel(root)){
+ final Tree tree = new Tree(new DefaultTreeModel(root))/* {
@Override
protected void paintComponent(Graphics g) {
DuplicateNodeRenderer.paintDuplicateNodesBackground(g, this);
super.paintComponent(g);
}
- };
+ }*/;
tree.setOpaque(false);
tree.setToggleClickCount(-1);
diff --git a/java/java-impl/src/com/intellij/slicer/SliceRootNode.java b/java/java-impl/src/com/intellij/slicer/SliceRootNode.java
index 5f1a915..e7b6f1d 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceRootNode.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceRootNode.java
@@ -33,7 +33,7 @@
private final SliceUsage myRootUsage;
public SliceRootNode(@NotNull Project project, @NotNull DuplicateMap targetEqualUsages, final SliceUsage rootUsage) {
- super(project, new SliceUsage(rootUsage.getElement().getContainingFile(), rootUsage.params), targetEqualUsages);
+ super(project, SliceUsage.createRootUsage(rootUsage.getElement().getContainingFile(), rootUsage.params), targetEqualUsages);
myRootUsage = rootUsage;
}
@@ -42,6 +42,7 @@
myCachedChildren = Collections.singletonList(node);
}
+ @NotNull
@Override
SliceRootNode copy() {
SliceUsage newUsage = getValue().copy();
@@ -60,6 +61,7 @@
return myCachedChildren;
}
+ @NotNull
@Override
public List<? extends AbstractTreeNode> getChildrenUnderProgress(ProgressIndicator progress) {
return (List<? extends AbstractTreeNode>)getChildren();
@@ -80,8 +82,8 @@
@Override
- public void customizeCellRenderer(SliceUsageCellRenderer renderer,
- JTree tree,
+ public void customizeCellRenderer(@NotNull SliceUsageCellRenderer renderer,
+ @NotNull JTree tree,
Object value,
boolean selected,
boolean expanded,
diff --git a/java/java-impl/src/com/intellij/slicer/SliceTooComplexDFAUsage.java b/java/java-impl/src/com/intellij/slicer/SliceTooComplexDFAUsage.java
index 89360c0..de150dd 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceTooComplexDFAUsage.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceTooComplexDFAUsage.java
@@ -37,7 +37,7 @@
}
@Override
- public void processChildren(Processor<SliceUsage> processor) {
+ public void processChildren(@NotNull Processor<SliceUsage> processor) {
// no children
}
diff --git a/java/java-impl/src/com/intellij/slicer/SliceUsage.java b/java/java-impl/src/com/intellij/slicer/SliceUsage.java
index 21a84906..0942dcc 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceUsage.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceUsage.java
@@ -21,7 +21,6 @@
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiSubstitutor;
-import com.intellij.slicer.forward.SliceFUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.usages.UsageInfo2UsageAdapter;
import com.intellij.util.CommonProcessors;
@@ -44,14 +43,18 @@
params = parent.params;
assert params != null;
}
- public SliceUsage(@NotNull PsiElement element, @NotNull SliceAnalysisParams params) {
+ private SliceUsage(@NotNull PsiElement element, @NotNull SliceAnalysisParams params) {
super(new UsageInfo(element));
myParent = null;
this.params = params;
mySubstitutor = PsiSubstitutor.EMPTY;
}
- public void processChildren(Processor<SliceUsage> processor) {
+ public static SliceUsage createRootUsage(@NotNull PsiElement element, @NotNull SliceAnalysisParams params) {
+ return new SliceUsage(element, params);
+ }
+
+ public void processChildren(@NotNull Processor<SliceUsage> processor) {
final PsiElement element = getElement();
ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
indicator.checkCanceled();
@@ -76,7 +79,7 @@
SliceUtil.processUsagesFlownDownTo(element, uniqueProcessor, SliceUsage.this, mySubstitutor);
}
else {
- SliceFUtil.processUsagesFlownFromThe(element, uniqueProcessor, SliceUsage.this);
+ SliceForwardUtil.processUsagesFlownFromThe(element, uniqueProcessor, SliceUsage.this);
}
}
});
@@ -93,7 +96,7 @@
SliceUsage copy() {
PsiElement element = getUsageInfo().getElement();
- return getParent() == null ? new SliceUsage(element, params) : new SliceUsage(element, getParent(),mySubstitutor);
+ return getParent() == null ? createRootUsage(element, params) : new SliceUsage(element, getParent(),mySubstitutor);
}
public PsiSubstitutor getSubstitutor() {
diff --git a/java/java-impl/src/com/intellij/slicer/SliceUsageCellRenderer.java b/java/java-impl/src/com/intellij/slicer/SliceUsageCellRenderer.java
index d2fdf1a..c12f62e 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceUsageCellRenderer.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceUsageCellRenderer.java
@@ -18,12 +18,14 @@
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.psi.util.PsiFormatUtilBase;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.ui.ColoredTreeCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.usageView.UsageTreeColors;
import com.intellij.usageView.UsageTreeColorsScheme;
import com.intellij.usages.TextChunk;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
@@ -41,7 +43,7 @@
}
@Override
- public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+ public void customizeCellRenderer(@NotNull JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
assert value instanceof DefaultMutableTreeNode;
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)value;
Object userObject = treeNode.getUserObject();
@@ -58,7 +60,7 @@
}
}
- public void customizeCellRendererFor(SliceUsage sliceUsage) {
+ public void customizeCellRendererFor(@NotNull SliceUsage sliceUsage) {
boolean isForcedLeaf = sliceUsage instanceof SliceDereferenceUsage;
TextChunk[] text = sliceUsage.getPresentation().getText();
@@ -83,12 +85,10 @@
break;
}
}
+ int methodOptions = PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS | PsiFormatUtilBase.SHOW_CONTAINING_CLASS;
String location = method != null
- ? PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME |
- PsiFormatUtil.SHOW_PARAMETERS |
- PsiFormatUtil.SHOW_CONTAINING_CLASS,
- PsiFormatUtil.SHOW_TYPE, 2)
- : aClass != null ? PsiFormatUtil.formatClass(aClass, PsiFormatUtil.SHOW_NAME) : null;
+ ? PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, methodOptions, PsiFormatUtilBase.SHOW_TYPE, 2)
+ : aClass != null ? PsiFormatUtil.formatClass(aClass, PsiFormatUtilBase.SHOW_NAME) : null;
if (location != null) {
SimpleTextAttributes attributes = SimpleTextAttributes.GRAY_ATTRIBUTES;
append(" in " + location, attributes);
diff --git a/java/java-impl/src/com/intellij/slicer/SliceUtil.java b/java/java-impl/src/com/intellij/slicer/SliceUtil.java
index 35b63bf..a689e18 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceUtil.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceUtil.java
@@ -30,7 +30,6 @@
import com.intellij.psi.util.MethodSignatureUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.slicer.forward.SliceFUtil;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.Processor;
import gnu.trove.THashMap;
@@ -54,7 +53,7 @@
expression = simplify(expression);
PsiElement original = expression;
if (expression instanceof PsiReferenceExpression) {
- PsiElement element = SliceFUtil.complexify(expression);
+ PsiElement element = SliceForwardUtil.complexify(expression);
if (element instanceof PsiExpression && PsiUtil.isOnAssignmentLeftHand((PsiExpression)element)) {
PsiExpression rightSide = ((PsiAssignmentExpression)element.getParent()).getRExpression();
return rightSide == null || handToProcessor(rightSide, processor, parent, parentSubstitutor);
@@ -238,9 +237,12 @@
});
}
+ @NotNull
public static SliceUsage createSliceUsage(@NotNull PsiElement element, @NotNull SliceUsage parent, @NotNull PsiSubstitutor substitutor) {
return new SliceUsage(simplify(element), parent, substitutor);
}
+
+ @NotNull
public static SliceUsage createTooComplexDFAUsage(@NotNull PsiElement element, @NotNull SliceUsage parent, @NotNull PsiSubstitutor substitutor) {
return new SliceTooComplexDFAUsage(simplify(element), parent, substitutor);
}
diff --git a/java/java-impl/src/com/intellij/slicer/forward/SliceFUtil.java b/java/java-impl/src/com/intellij/slicer/forward/SliceFUtil.java
deleted file mode 100644
index ef70197..0000000
--- a/java/java-impl/src/com/intellij/slicer/forward/SliceFUtil.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.slicer.forward;
-
-import com.intellij.openapi.util.Pair;
-import com.intellij.psi.*;
-import com.intellij.psi.search.searches.MethodReferencesSearch;
-import com.intellij.psi.search.searches.OverridingMethodsSearch;
-import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.util.MethodSignatureUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.slicer.SliceDereferenceUsage;
-import com.intellij.slicer.SliceManager;
-import com.intellij.slicer.SliceUsage;
-import com.intellij.slicer.SliceUtil;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.Processor;
-import gnu.trove.THashSet;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * @author cdr
- */
-public class SliceFUtil {
- public static boolean processUsagesFlownFromThe(@NotNull PsiElement element, @NotNull final Processor<SliceUsage> processor, @NotNull final SliceUsage parent) {
- Pair<PsiElement, PsiSubstitutor> pair = getAssignmentTarget(element, parent);
- if (pair != null) {
- PsiElement target = pair.getFirst();
- final PsiSubstitutor substitutor = pair.getSecond();
- if (target instanceof PsiParameter) {
- PsiParameter parameter = (PsiParameter)target;
- PsiElement declarationScope = parameter.getDeclarationScope();
- if (declarationScope instanceof PsiMethod) {
- final PsiMethod method = (PsiMethod)declarationScope;
- final int parameterIndex = method.getParameterList().getParameterIndex(parameter);
-
- Processor<PsiMethod> myProcessor = new Processor<PsiMethod>() {
- @Override
- public boolean process(PsiMethod override) {
- if (!parent.getScope().contains(override)) return true;
- final PsiSubstitutor superSubstitutor = method == override
- ? substitutor
- : MethodSignatureUtil.getSuperMethodSignatureSubstitutor(method.getSignature(substitutor),
- override.getSignature(substitutor));
-
- PsiParameter[] parameters = override.getParameterList().getParameters();
- if (parameters.length <= parameterIndex) return true;
- PsiParameter actualParam = parameters[parameterIndex];
-
- SliceUsage usage = SliceUtil.createSliceUsage(actualParam, parent, superSubstitutor);
- return processor.process(usage);
- }
- };
- if (!myProcessor.process(method)) return false;
- return OverridingMethodsSearch.search(method, parent.getScope().toSearchScope(), true).forEach(myProcessor);
- }
- }
-
- SliceUsage usage = SliceUtil.createSliceUsage(target, parent, parent.getSubstitutor());
- return processor.process(usage);
- }
-
- if (element instanceof PsiReferenceExpression) {
- PsiReferenceExpression ref = (PsiReferenceExpression)element;
- PsiElement resolved = ref.resolve();
- if (!(resolved instanceof PsiVariable)) return true;
- final PsiVariable variable = (PsiVariable)resolved;
- return processAssignedFrom(variable, ref, parent, processor);
- }
- if (element instanceof PsiVariable) {
- return processAssignedFrom(element, element, parent, processor);
- }
- if (element instanceof PsiMethod) {
- return processAssignedFrom(element, element, parent, processor);
- }
- return true;
- }
-
- private static boolean processAssignedFrom(final PsiElement from, final PsiElement context, final SliceUsage parent,
- final Processor<SliceUsage> processor) {
- if (from instanceof PsiLocalVariable) {
- return searchReferencesAndProcessAssignmentTarget(from, context, parent, processor);
- }
- if (from instanceof PsiParameter) {
- PsiParameter parameter = (PsiParameter)from;
- PsiElement scope = parameter.getDeclarationScope();
- Collection<PsiParameter> parametersToAnalyze = new THashSet<PsiParameter>();
- if (scope instanceof PsiMethod) {
- final PsiMethod method = (PsiMethod)scope;
- int index = method.getParameterList().getParameterIndex(parameter);
-
- Collection<PsiMethod> superMethods = new THashSet<PsiMethod>(Arrays.asList(method.findDeepestSuperMethods()));
- superMethods.add(method);
- for (Iterator<PsiMethod> iterator = superMethods.iterator(); iterator.hasNext(); ) {
- SliceManager.getInstance(method.getProject()).checkCanceled();
- PsiMethod superMethod = iterator.next();
- if (!parent.params.scope.contains(superMethod)) {
- iterator.remove();
- }
- }
-
- final THashSet<PsiMethod> implementors = new THashSet<PsiMethod>(superMethods);
- for (PsiMethod superMethod : superMethods) {
- SliceManager.getInstance(method.getProject()).checkCanceled();
- if (!OverridingMethodsSearch.search(superMethod, parent.getScope().toSearchScope(), true).forEach(new Processor<PsiMethod>() {
- @Override
- public boolean process(PsiMethod sub) {
- SliceManager.getInstance(method.getProject()).checkCanceled();
- implementors.add(sub);
- return true;
- }
- })) return false;
- }
- for (PsiMethod implementor : implementors) {
- SliceManager.getInstance(method.getProject()).checkCanceled();
- if (!parent.params.scope.contains(implementor)) continue;
- if (implementor instanceof PsiCompiledElement) implementor = (PsiMethod)implementor.getNavigationElement();
-
- PsiParameter[] parameters = implementor.getParameterList().getParameters();
- if (index != -1 && index < parameters.length) {
- parametersToAnalyze.add(parameters[index]);
- }
- }
- }
- else {
- parametersToAnalyze.add(parameter);
- }
- for (final PsiParameter psiParameter : parametersToAnalyze) {
- SliceManager.getInstance(from.getProject()).checkCanceled();
-
- if (!searchReferencesAndProcessAssignmentTarget(psiParameter, null, parent, processor)) return false;
- }
- return true;
- }
- if (from instanceof PsiField) {
- return searchReferencesAndProcessAssignmentTarget(from, null, parent, processor);
- }
-
- if (from instanceof PsiMethod) {
- PsiMethod method = (PsiMethod)from;
-
- Collection<PsiMethod> superMethods = new THashSet<PsiMethod>(Arrays.asList(method.findDeepestSuperMethods()));
- superMethods.add(method);
- final Set<PsiReference> processed = new THashSet<PsiReference>(); //usages of super method and overridden method can overlap
- for (final PsiMethod containingMethod : superMethods) {
- if (!MethodReferencesSearch.search(containingMethod, parent.getScope().toSearchScope(), true).forEach(new Processor<PsiReference>() {
- @Override
- public boolean process(final PsiReference reference) {
- SliceManager.getInstance(from.getProject()).checkCanceled();
- synchronized (processed) {
- if (!processed.add(reference)) return true;
- }
- PsiElement element = reference.getElement().getParent();
-
- return processAssignmentTarget(element, parent, processor);
- }
- })) {
- return false;
- }
- }
- }
- return true;
- }
-
- private static boolean searchReferencesAndProcessAssignmentTarget(@NotNull PsiElement element, @Nullable final PsiElement context, final SliceUsage parent,
- final Processor<SliceUsage> processor) {
- return ReferencesSearch.search(element).forEach(new Processor<PsiReference>() {
- @Override
- public boolean process(PsiReference reference) {
- PsiElement element = reference.getElement();
- if (context != null && element.getTextOffset() < context.getTextOffset()) return true;
- return processAssignmentTarget(element, parent, processor);
- }
- });
- }
-
- private static boolean processAssignmentTarget(PsiElement element, final SliceUsage parent, final Processor<SliceUsage> processor) {
- if (!parent.params.scope.contains(element)) return true;
- if (element instanceof PsiCompiledElement) element = element.getNavigationElement();
- Pair<PsiElement, PsiSubstitutor> pair = getAssignmentTarget(element, parent);
- if (pair != null) {
- SliceUsage usage = SliceUtil.createSliceUsage(element, parent, pair.getSecond());
- return processor.process(usage);
- }
- if (parent.params.showInstanceDereferences && isDereferenced(element)) {
- SliceUsage usage = new SliceDereferenceUsage(element.getParent(), parent, parent.getSubstitutor());
- return processor.process(usage);
- }
- return true;
- }
-
- private static boolean isDereferenced(PsiElement element) {
- if (!(element instanceof PsiReferenceExpression)) return false;
- PsiElement parent = element.getParent();
- if (!(parent instanceof PsiReferenceExpression)) return false;
- return ((PsiReferenceExpression)parent).getQualifierExpression() == element;
- }
-
- private static Pair<PsiElement,PsiSubstitutor> getAssignmentTarget(PsiElement element, SliceUsage parentUsage) {
- element = complexify(element);
- PsiElement target = null;
- PsiSubstitutor substitutor = parentUsage.getSubstitutor();
- //assignment
- PsiElement parent = element.getParent();
- if (parent instanceof PsiAssignmentExpression) {
- PsiAssignmentExpression assignment = (PsiAssignmentExpression)parent;
- if (element.equals(assignment.getRExpression())) {
- PsiElement left = assignment.getLExpression();
- if (left instanceof PsiReferenceExpression) {
- JavaResolveResult result = ((PsiReferenceExpression)left).advancedResolve(false);
- target = result.getElement();
- substitutor = result.getSubstitutor();
- }
- }
- }
- else if (parent instanceof PsiVariable) {
- PsiVariable variable = (PsiVariable)parent;
-
- PsiElement initializer = variable.getInitializer();
- if (element.equals(initializer)) {
- target = variable;
- }
- }
- //method call
- else if (parent instanceof PsiExpressionList && parent.getParent() instanceof PsiCallExpression) {
- PsiExpression[] expressions = ((PsiExpressionList)parent).getExpressions();
- int index = ArrayUtil.find(expressions, element);
- PsiCallExpression methodCall = (PsiCallExpression)parent.getParent();
- JavaResolveResult result = methodCall.resolveMethodGenerics();
- PsiMethod method = (PsiMethod)result.getElement();
- if (index != -1 && method != null) {
- PsiParameter[] parameters = method.getParameterList().getParameters();
- if (index < parameters.length) {
- target = parameters[index];
- substitutor = result.getSubstitutor();
- }
- }
- }
- else if (parent instanceof PsiReturnStatement) {
- PsiReturnStatement statement = (PsiReturnStatement)parent;
- if (element.equals(statement.getReturnValue())) {
- target = PsiTreeUtil.getParentOfType(statement, PsiMethod.class);
- }
- }
-
- return target == null ? null : Pair.create(target, substitutor);
- }
-
- public static PsiElement complexify(@NotNull PsiElement element) {
- PsiElement parent = element.getParent();
- if (parent instanceof PsiParenthesizedExpression && element.equals(((PsiParenthesizedExpression)parent).getExpression())) {
- return complexify(parent);
- }
- if (parent instanceof PsiTypeCastExpression && element.equals(((PsiTypeCastExpression)parent).getOperand())) {
- return complexify(parent);
- }
- return element;
- }
-}
diff --git a/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java b/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java
index 9e389dd..5b4a1f3 100644
--- a/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java
+++ b/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java
@@ -107,6 +107,8 @@
public FileTemplateDescriptor getParametersMethodFileTemplateDescriptor() {
return null;
}
+
+ public abstract char getMnemonic();
public PsiMethod createSetUpPatternMethod(JVMElementFactory factory) {
final FileTemplate template = FileTemplateManager.getInstance().getCodeTemplate(getSetUpMethodFileTemplateDescriptor().getFileName());
diff --git a/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java b/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java
index d34a360..1185d60 100644
--- a/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java
+++ b/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java
@@ -49,6 +49,7 @@
import com.intellij.refactoring.util.RefactoringMessageUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.refactoring.util.classMembers.MemberInfo;
+import com.intellij.testIntegration.JavaTestFramework;
import com.intellij.testIntegration.TestFramework;
import com.intellij.testIntegration.TestIntegrationUtils;
import com.intellij.ui.EditorTextField;
@@ -123,6 +124,12 @@
for (final TestFramework descriptor : Extensions.getExtensions(TestFramework.EXTENSION_NAME)) {
final JRadioButton b = new JRadioButton(descriptor.getName());
+ if (descriptor instanceof JavaTestFramework) {
+ final char mnemonic = ((JavaTestFramework)descriptor).getMnemonic();
+ if (mnemonic > -1) {
+ b.setMnemonic(mnemonic);
+ }
+ }
myLibraryButtons.add(b);
group.add(b);
diff --git a/java/java-impl/src/com/intellij/usageView/UsageContextDataflowToPanel.java b/java/java-impl/src/com/intellij/usageView/UsageContextDataflowToPanel.java
index 226af43..b097a8a 100644
--- a/java/java-impl/src/com/intellij/usageView/UsageContextDataflowToPanel.java
+++ b/java/java-impl/src/com/intellij/usageView/UsageContextDataflowToPanel.java
@@ -122,7 +122,7 @@
ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.FIND);
SliceAnalysisParams params = createParams(element, dataFlowToThis);
- SliceRootNode rootNode = new SliceRootNode(myProject, new DuplicateMap(), SliceManager.createRootUsage(element, params));
+ SliceRootNode rootNode = new SliceRootNode(myProject, new DuplicateMap(), SliceUsage.createRootUsage(element, params));
return new SlicePanel(myProject, dataFlowToThis, rootNode, false, toolWindow) {
@Override
diff --git a/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java b/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java
index 0593133..7e344d2 100644
--- a/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java
+++ b/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java
@@ -50,6 +50,7 @@
if (!(usage instanceof PsiElementUsage)) return null;
PsiElement psiElement = ((PsiElementUsage)usage).getElement();
PsiFile containingFile = psiElement.getContainingFile();
+ if (containingFile == null) return null;
InjectedLanguageManager manager = InjectedLanguageManager.getInstance(containingFile.getProject());
PsiFile topLevelFile = manager.getTopLevelFile(containingFile);
if (topLevelFile instanceof PsiJavaFile) {
diff --git a/java/java-indexing-api/src/com/intellij/psi/search/PsiShortNamesCache.java b/java/java-indexing-api/src/com/intellij/psi/search/PsiShortNamesCache.java
index 6854c57..aa0d088 100644
--- a/java/java-indexing-api/src/com/intellij/psi/search/PsiShortNamesCache.java
+++ b/java/java-indexing-api/src/com/intellij/psi/search/PsiShortNamesCache.java
@@ -120,6 +120,14 @@
public abstract boolean processMethodsWithName(@NonNls @NotNull String name, @NotNull GlobalSearchScope scope, @NotNull Processor<PsiMethod> processor);
+ public boolean processAllMethodNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+ return ContainerUtil.process(getAllFieldNames(), processor);
+ }
+
+ public boolean processAllFieldNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+ return ContainerUtil.process(getAllFieldNames(), processor);
+ }
+
/**
* Returns the list of names of all methods in the project and
* (optionally) libraries.
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java b/java/java-indexing-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java
index e6ba22d..517a300 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java
@@ -117,6 +117,26 @@
}
@Override
+ public boolean processAllMethodNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+ for (PsiShortNamesCache cache : myCaches) {
+ if (!cache.processAllMethodNames(processor, scope, filter)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean processAllFieldNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+ for (PsiShortNamesCache cache : myCaches) {
+ if (!cache.processAllFieldNames(processor, scope, filter)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
public void getAllClassNames(@NotNull HashSet<String> dest) {
for (PsiShortNamesCache cache : myCaches) {
cache.getAllClassNames(dest);
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java b/java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java
index e702d01..8bc35ce 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java
@@ -122,6 +122,16 @@
}
@Override
+ public boolean processAllMethodNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+ return StubIndex.getInstance().processAllKeys(JavaStubIndexKeys.METHODS, processor, scope, filter);
+ }
+
+ @Override
+ public boolean processAllFieldNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+ return StubIndex.getInstance().processAllKeys(JavaStubIndexKeys.FIELDS, processor, scope, filter);
+ }
+
+ @Override
@NotNull
public PsiMethod[] getMethodsByName(@NotNull String name, @NotNull final GlobalSearchScope scope) {
Collection<PsiMethod> methods = StubIndex.getInstance().get(JavaStubIndexKeys.METHODS, name, myManager.getProject(), new JavaSourceFilterScope(scope));
diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
index 94c1563..4cdb0f3 100644
--- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
@@ -109,9 +109,7 @@
public static boolean isLambdaFullyInferred(PsiLambdaExpression expression, PsiType functionalInterfaceType) {
final boolean hasParams = expression.getParameterList().getParametersCount() > 0;
if (hasParams || getFunctionalInterfaceReturnType(functionalInterfaceType) != PsiType.VOID) { //todo check that void lambdas without params check
- if (hasParams && !checkRawAcceptable(expression, functionalInterfaceType)) {
- return false;
- }
+
return !dependsOnTypeParams(functionalInterfaceType, functionalInterfaceType, expression);
}
return true;
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceExpression.java b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceExpression.java
index 2d91cd4..1df1441 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceExpression.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceExpression.java
@@ -35,4 +35,6 @@
*/
@Nullable
PsiType getFunctionalInterfaceType();
+
+ boolean isExact();
}
diff --git a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
index 01120c2..d72d3d8 100644
--- a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
+++ b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
@@ -81,7 +81,7 @@
private int getApplicabilityLevelInner() {
if (myArgumentTypes == null) return ApplicabilityLevel.NOT_APPLICABLE;
- int level = PsiUtil.getApplicabilityLevel(getElement(), getSubstitutor(!Registry.is("enable.graph.inference", false)), myArgumentTypes, myLanguageLevel);
+ int level = PsiUtil.getApplicabilityLevel(getElement(), getSubstitutor(), myArgumentTypes, myLanguageLevel);
if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable()) level = ApplicabilityLevel.NOT_APPLICABLE;
return level;
}
diff --git a/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaDocLexer.java b/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaDocLexer.java
index de1e03f3..0592f9e 100644
--- a/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaDocLexer.java
+++ b/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaDocLexer.java
@@ -54,7 +54,7 @@
}
@Override
- public final void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public final void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
myBuffer = buffer;
myBufferIndex = startOffset;
myBufferEndOffset = endOffset;
@@ -68,6 +68,7 @@
return myState;
}
+ @NotNull
@Override
public CharSequence getBufferSequence() {
return myBuffer;
diff --git a/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaLexer.java b/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaLexer.java
index db6e5e2..f1c6c19 100644
--- a/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaLexer.java
+++ b/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaLexer.java
@@ -175,7 +175,7 @@
}
@Override
- public final void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public final void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
myBuffer = buffer;
myBufferArray = CharArrayUtil.fromSequenceWithoutCopying(buffer);
myBufferIndex = startOffset;
@@ -417,6 +417,7 @@
return pos;
}
+ @NotNull
@Override
public CharSequence getBufferSequence() {
return myBuffer;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
index bc62cc8..103b828 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
@@ -799,7 +799,7 @@
@Override
public void processVariants(@NotNull final PsiScopeProcessor processor) {
final OrFilter filter = new OrFilter();
- if (isInCode() && !(getParent() instanceof PsiImportStatement)) {
+ if (isInCode() && !(getParent() instanceof PsiImportStatement) && !(getParent() instanceof PsiReferenceList)) {
filter.addFilter(new AndFilter(ElementClassFilter.METHOD, new NotFilter(new ConstructorFilter())));
filter.addFilter(ElementClassFilter.VARIABLE);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
index 68bb8b8..15aba88 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.impl.source.resolve;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.pom.java.LanguageLevel;
@@ -196,7 +197,16 @@
.getSubstitutionForTypeParameter(typeParam, param, arg, isContraVariantPosition, languageLevel);
}
+ private PsiInferenceHelper myTestHelper;
+
+ public void setTestHelper(PsiInferenceHelper testHelper) {
+ myTestHelper = testHelper;
+ }
+
public PsiInferenceHelper getInferenceHelper(LanguageLevel languageLevel) {
+ if (ApplicationManager.getApplication().isUnitTestMode()) {
+ return myTestHelper != null ? myTestHelper : new PsiOldInferenceHelper(myManager);
+ }
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && Registry.is("enable.graph.inference", false)) {
return new PsiGraphInferenceHelper(myManager);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java
new file mode 100644
index 0000000..4806a51
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.impl.source.resolve.graphInference;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.constraints.TypeEqualityConstraint;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class FunctionalInterfaceParameterizationUtil {
+ private static final Logger LOG = Logger.getInstance("#" + FunctionalInterfaceParameterizationUtil.class.getName());
+
+ public static boolean isWildcardParameterized(@Nullable PsiType classType) {
+ if (classType == null) return false;
+ if (classType instanceof PsiIntersectionType) {
+ for (PsiType type : ((PsiIntersectionType)classType).getConjuncts()) {
+ if (!isWildcardParameterized(type)) return false;
+ }
+ }
+ if (classType instanceof PsiClassType) {
+ for (PsiType type : ((PsiClassType)classType).getParameters()) {
+ if (type instanceof PsiWildcardType || type instanceof PsiCapturedWildcardType) {
+ return true;
+ }
+ }
+ return false;
+ }
+ LOG.error("Unexpected type: " + classType);
+ return false;
+ }
+
+ @Nullable
+ public static PsiType getFunctionalType(@Nullable PsiType psiClassType, PsiLambdaExpression expr) {
+ if (!expr.hasFormalParameterTypes() || expr.getParameterList().getParametersCount() == 0) return psiClassType;
+ if (!isWildcardParameterized(psiClassType)) {
+ return psiClassType;
+ }
+ final PsiParameter[] lambdaParams = expr.getParameterList().getParameters();
+ if (psiClassType instanceof PsiIntersectionType) {
+ for (PsiType psiType : ((PsiIntersectionType)psiClassType).getConjuncts()) {
+ final PsiType functionalType = getFunctionalType(psiType, expr);
+ if (functionalType != null) return functionalType;
+ }
+ return null;
+ }
+
+ LOG.assertTrue(psiClassType instanceof PsiClassType, "Unexpected type: " + psiClassType);
+ final PsiType[] parameters = ((PsiClassType)psiClassType).getParameters();
+ final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)psiClassType).resolveGenerics();
+ PsiClass psiClass = resolveResult.getElement();
+
+ if (psiClass != null) {
+
+ final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
+ if (interfaceMethod == null) return null;
+
+ final InferenceSession session = new InferenceSession(PsiSubstitutor.EMPTY);
+ PsiTypeParameter[] typeParameters = psiClass.getTypeParameters();
+ if (typeParameters.length != parameters.length) {
+ return null;
+ }
+
+ for (int i = 0; i < typeParameters.length; i++) {
+ session.addVariable(typeParameters[i], parameters[i]);
+ }
+
+ final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(psiClass.getProject());
+ final PsiParameter[] targetMethodParams = interfaceMethod.getParameterList().getParameters();
+ for (int i = 0; i < targetMethodParams.length; i++) {
+ session.addConstraint(new TypeEqualityConstraint(lambdaParams[i].getType(), targetMethodParams[i].getType()));
+ }
+
+ final PsiClassType parameterization = elementFactory.createType(psiClass, session.infer());
+ if (!isWildcardParameterized(parameterization)) return parameterization;
+ }
+ return null;
+ }
+}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
index a63e438..e1c3d63 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
@@ -174,8 +174,10 @@
private void eqEq(List<PsiType> eqBounds) {
for (int i = 0; i < eqBounds.size(); i++) {
PsiType sBound= eqBounds.get(i);
+ if (sBound == null) continue;
for (int j = i + 1; j < eqBounds.size(); j++) {
final PsiType tBound = eqBounds.get(j);
+ if (tBound == null) continue;
addConstraint(new TypeEqualityConstraint(tBound, sBound));
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
index dba4a72..df78507 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
@@ -18,13 +18,17 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiImplUtil;
+import com.intellij.psi.impl.source.resolve.graphInference.constraints.CheckedExceptionCompatibilityConstraint;
import com.intellij.psi.impl.source.resolve.graphInference.constraints.ConstraintFormula;
import com.intellij.psi.impl.source.resolve.graphInference.constraints.ExpressionCompatibilityConstraint;
import com.intellij.psi.impl.source.resolve.graphInference.constraints.TypeCompatibilityConstraint;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.ArrayUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,7 +42,6 @@
private Map<PsiTypeParameter, InferenceVariable> myInferenceVariables = new LinkedHashMap<PsiTypeParameter, InferenceVariable>();
private final List<ConstraintFormula> myConstraints = new ArrayList<ConstraintFormula>();
- private final List<ConstraintFormula> myDelayedConstraints = new ArrayList<ConstraintFormula>();
private PsiSubstitutor mySiteSubstitutor;
private PsiManager myManager;
@@ -46,6 +49,10 @@
private final InferenceIncorporationPhase myIncorporationPhase = new InferenceIncorporationPhase(this);
+ public InferenceSession(PsiSubstitutor siteSubstitutor) {
+ mySiteSubstitutor = siteSubstitutor;
+ }
+
public InferenceSession(PsiTypeParameter[] typeParams,
PsiType[] leftTypes,
PsiType[] rightTypes,
@@ -75,14 +82,10 @@
if (parameters.length > 0) {
for (int i = 0; i < args.length; i++) {
- PsiType parameterType = mySiteSubstitutor.substitute(parameters[i < parameters.length ? i : parameters.length - 1].getType());
- if (parameterType instanceof PsiEllipsisType) {
- if (args.length != parameters.length || args[i] != null && !(args[i].getType() instanceof PsiArrayType)) {
- parameterType = ((PsiEllipsisType)parameterType).getComponentType();
- }
- }
+ PsiType parameterType = getParameterType(parameters, args, i, mySiteSubstitutor);
if (args[i] != null) {
myConstraints.add(new ExpressionCompatibilityConstraint(args[i], parameterType));
+ //myConstraints.add(new CheckedExceptionCompatibilityConstraint(args[i], parameterType));
}
}
}
@@ -98,11 +101,66 @@
}
}
+ public static boolean isPertinentToApplicability(PsiExpression expr, PsiMethod method) {
+ if (expr instanceof PsiLambdaExpression) {
+ if (((PsiLambdaExpression)expr).hasFormalParameterTypes()) return true;
+ for (PsiExpression expression : LambdaUtil.getReturnExpressions((PsiLambdaExpression)expr)) {
+ if (!isPertinentToApplicability(expression, method)) return false;
+ }
+ if (method.getTypeParameters().length > 0) {
+ final PsiElement parent = PsiUtil.skipParenthesizedExprUp(expr.getParent());
+ if (parent instanceof PsiExpressionList) {
+ final PsiElement gParent = parent.getParent();
+ if (gParent instanceof PsiCallExpression && ((PsiCallExpression)gParent).getTypeArgumentList().getTypeParameterElements().length == 0) {
+ final int idx = LambdaUtil.getLambdaIdx(((PsiExpressionList)parent), expr);
+ final PsiParameter[] parameters = method.getParameterList().getParameters();
+ PsiType paramType;
+ if (idx > parameters.length - 1) {
+ final PsiType lastParamType = parameters[parameters.length - 1].getType();
+ paramType = parameters[parameters.length - 1].isVarArgs() ? ((PsiEllipsisType)lastParamType).getComponentType() : lastParamType;
+ }
+ else {
+ paramType = parameters[idx].getType();
+ }
+ final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(paramType);
+ if (psiClass instanceof PsiTypeParameter && ((PsiTypeParameter)psiClass).getOwner() == method) return false;
+ }
+ }
+ }
+ return true;
+ }
+ if (expr instanceof PsiMethodReferenceExpression) {
+ return ((PsiMethodReferenceExpression)expr).isExact();
+ }
+ if (expr instanceof PsiParenthesizedExpression) {
+ return isPertinentToApplicability(((PsiParenthesizedExpression)expr).getExpression(), method);
+ }
+ if (expr instanceof PsiConditionalExpression) {
+ final PsiExpression thenExpression = ((PsiConditionalExpression)expr).getThenExpression();
+ if (!isPertinentToApplicability(thenExpression, method)) return false;
+ final PsiExpression elseExpression = ((PsiConditionalExpression)expr).getElseExpression();
+ if (!isPertinentToApplicability(elseExpression, method)) return false;
+ }
+ return true;
+ }
+
+ private static PsiType getParameterType(PsiParameter[] parameters, PsiExpression[] args, int i, PsiSubstitutor substitutor) {
+ PsiType parameterType = substitutor.substitute(parameters[i < parameters.length ? i : parameters.length - 1].getType());
+ if (parameterType instanceof PsiEllipsisType) {
+ if (args.length != parameters.length || PsiPolyExpressionUtil
+ .isPolyExpression(args[i]) || args[i] != null && !(args[i].getType() instanceof PsiArrayType)) {
+ parameterType = ((PsiEllipsisType)parameterType).getComponentType();
+ }
+ }
+ return parameterType;
+ }
+
@NotNull
public PsiSubstitutor infer() {
repeatInferencePhases();
for (InferenceVariable inferenceVariable : myInferenceVariables.values()) {
+ if (inferenceVariable.isCaptured()) continue;
final PsiTypeParameter typeParameter = inferenceVariable.getParameter();
PsiType instantiation = inferenceVariable.getInstantiation();
if (instantiation == PsiType.NULL) {
@@ -136,25 +194,60 @@
}
}
}
+
+ public void addCapturedVariable(PsiTypeParameter param) {
+ if (myInferenceVariables.containsKey(param)) return; //same method call
+ final InferenceVariable variable = new InferenceVariable(param);
+ variable.setCaptured(true);
+ myInferenceVariables.put(param, variable);
+ }
private void initReturnTypeConstraint(PsiMethod method, PsiCallExpression context) {
if (PsiPolyExpressionUtil.isPolyExpression(context) ||
context instanceof PsiNewExpression && PsiDiamondType.ourDiamondGuard.currentStack().contains(context)) {
final PsiType returnType = method.getReturnType();
if (!PsiType.VOID.equals(returnType) && returnType != null) {
- final PsiType targetType = PsiPolyExpressionUtil.getTargetType(context);//todo primitive type
+ PsiType targetType = PsiTypesUtil.getExpectedTypeByParent(context);
+ if (targetType == null) {
+ final PsiElement parent = PsiUtil.skipParenthesizedExprUp(context.getParent());
+ if (parent instanceof PsiExpressionList) {
+ final PsiElement gParent = parent.getParent();
+ if (gParent instanceof PsiCallExpression) {
+ final PsiExpressionList argumentList = ((PsiCallExpression)gParent).getArgumentList();
+ if (argumentList != null) {
+ final JavaResolveResult resolveResult = ((PsiCallExpression)gParent).resolveMethodGenerics();
+ final PsiElement parentMethod = resolveResult.getElement();
+ if (parentMethod instanceof PsiMethod) {
+ final PsiParameter[] parameters = ((PsiMethod)parentMethod).getParameterList().getParameters();
+ PsiElement arg = context;
+ while (arg.getParent() instanceof PsiParenthesizedExpression) {
+ arg = parent.getParent();
+ }
+ final PsiExpression[] args = argumentList.getExpressions();
+ targetType = getParameterType(parameters, args, ArrayUtilRt.find(args, arg), resolveResult.getSubstitutor());
+ }
+ }
+ }
+ } else if (parent instanceof PsiConditionalExpression) {
+ targetType = PsiTypesUtil.getExpectedTypeByParent((PsiExpression)parent);
+ }
+ }
if (targetType != null) {
- myConstraints.add(new TypeCompatibilityConstraint(targetType, returnType));
+ myConstraints.add(new TypeCompatibilityConstraint(targetType, PsiImplUtil.normalizeWildcardTypeByPosition(returnType, context)));
}
}
}
}
public InferenceVariable getInferenceVariable(PsiType psiType) {
+ return getInferenceVariable(psiType, true);
+ }
+
+ public InferenceVariable getInferenceVariable(PsiType psiType, boolean acceptCaptured) {
final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(psiType);
if (psiClass instanceof PsiTypeParameter) {
final InferenceVariable inferenceVariable = myInferenceVariables.get(psiClass);
- if (inferenceVariable != null) {
+ if (inferenceVariable != null && (acceptCaptured || !inferenceVariable.isCaptured())) {
return inferenceVariable;
}
}
@@ -162,10 +255,16 @@
}
public boolean isProperType(@Nullable PsiType type) {
- return collectDependencies(type, null);
+ return isProperType(type, true);
}
- public boolean collectDependencies(@Nullable PsiType type, @Nullable final Set<InferenceVariable> dependencies) {
+ public boolean isProperType(@Nullable PsiType type, boolean acceptCaptured) {
+ return collectDependencies(type, null, acceptCaptured);
+ }
+
+ public boolean collectDependencies(@Nullable PsiType type,
+ @Nullable final Set<InferenceVariable> dependencies,
+ final boolean acceptCaptured) {
if (type == null) return true;
final Boolean isProper = type.accept(new PsiTypeVisitor<Boolean>() {
@Nullable
@@ -191,7 +290,7 @@
@Nullable
@Override
public Boolean visitClassType(PsiClassType classType) {
- final InferenceVariable inferenceVariable = getInferenceVariable(classType);
+ final InferenceVariable inferenceVariable = getInferenceVariable(classType, acceptCaptured);
if (inferenceVariable != null) {
if (dependencies != null) {
dependencies.add(inferenceVariable);
@@ -225,7 +324,7 @@
List<ConstraintFormula> newConstraints = new ArrayList<ConstraintFormula>();
for (int i = myConstraintIdx; i < myConstraints.size(); i++) {
ConstraintFormula constraint = myConstraints.get(i);
- if (!constraint.reduce(this, newConstraints, myDelayedConstraints)) {
+ if (!constraint.reduce(this, newConstraints)) {
return false;
}
}
@@ -241,7 +340,7 @@
for (List<InferenceVariable> variables : independentVars) {
for (InferenceVariable inferenceVariable : variables) {
- if (inferenceVariable.getInstantiation() != PsiType.NULL) continue;
+ if (inferenceVariable.isCaptured() || inferenceVariable.getInstantiation() != PsiType.NULL) continue;
final PsiTypeParameter typeParameter = inferenceVariable.getParameter();
try {
final List<PsiType> eqBounds = inferenceVariable.getBounds(InferenceBound.EQ);
@@ -253,19 +352,18 @@
}
PsiType bound = null;
for (PsiType eqBound : eqBounds) {
- eqBound = acceptBoundsWithRecursiveDependencies(typeParameter, eqBound);
- if (isProperType(eqBound)) {
- bound = eqBound;
- break;
- }
+ bound = acceptBoundsWithRecursiveDependencies(typeParameter, eqBound);
}
if (bound != null) {
+ if (bound instanceof PsiCapturedWildcardType && eqBounds.size() > 1) {
+ continue;
+ }
inferenceVariable.setInstantiation(bound);
} else {
PsiType lub = null;
for (PsiType lowerBound : lowerBounds) {
lowerBound = acceptBoundsWithRecursiveDependencies(typeParameter, lowerBound);
- if (isProperType(lowerBound)) {
+ if (isProperType(lowerBound, false)) {
if (lub == null) {
lub = lowerBound;
}
@@ -281,7 +379,7 @@
PsiType glb = null;
for (PsiType upperBound : upperBounds) {
upperBound = acceptBoundsWithRecursiveDependencies(typeParameter, upperBound);
- if (isProperType(upperBound)) {
+ if (isProperType(upperBound, false)) {
if (glb == null) {
glb = upperBound;
}
@@ -307,8 +405,9 @@
}
private PsiType acceptBoundsWithRecursiveDependencies(PsiTypeParameter typeParameter, PsiType bound) {
- if (PsiPolyExpressionUtil.mentionsTypeParameters(bound, Collections.singleton(typeParameter))) {
- return mySiteSubstitutor.put(typeParameter, null).substitute(bound);
+ if (!isProperType(bound)) {
+ final PsiSubstitutor substitutor = PsiUtil.resolveClassInType(bound) != typeParameter ? mySiteSubstitutor.put(typeParameter, null) : mySiteSubstitutor;
+ return substitutor.substitute(bound);
}
return bound;
}
@@ -330,4 +429,24 @@
myConstraints.add(constraint);
}
}
+
+ public Collection<PsiTypeParameter> getTypeParams() {
+ return myInferenceVariables.keySet();
+ }
+
+ public void addVariable(PsiTypeParameter typeParameter, final PsiType parameter) {
+ InferenceVariable variable = new InferenceVariable(typeParameter);
+ if (parameter instanceof PsiWildcardType) {
+ PsiType bound = ((PsiWildcardType)parameter).getBound();
+ if (bound != null) {
+ variable.addBound(bound, ((PsiWildcardType)parameter).isExtends() ? InferenceBound.UPPER : InferenceBound.LOWER);
+ } else {
+ variable.addBound(PsiType.getJavaLangObject(typeParameter.getManager(), parameter.getResolveScope()),
+ InferenceBound.UPPER);
+ }
+ } else {
+ variable.addBound(parameter, InferenceBound.EQ);
+ }
+ myInferenceVariables.put(typeParameter, variable);
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
index e69f229..f750e12 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
@@ -58,7 +58,8 @@
list = new ArrayList<PsiType>();
myBounds.put(inferenceBound, list);
}
- if (!list.contains(classType)) {
+ final int idx = list.indexOf(classType);
+ if (idx < 0 || inferenceBound == InferenceBound.EQ && classType instanceof PsiCapturedWildcardType && list.get(idx) != classType) {
list.add(classType);
return true;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariablesOrder.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariablesOrder.java
index 4a2c412..c27ae4a 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariablesOrder.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariablesOrder.java
@@ -41,7 +41,7 @@
for (InferenceBound inferenceBound : InferenceBound.values()) {
for (PsiType bound : var.getBounds(inferenceBound)) {
final HashSet<InferenceVariable> dependencies = new HashSet<InferenceVariable>();
- session.collectDependencies(bound, dependencies);
+ session.collectDependencies(bound, dependencies, true);
for (InferenceVariable dependentVariable : dependencies) {
final InferenceGraphNode<InferenceVariable> dependency = nodes.get(dependentVariable);
if (dependency != null) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java
index 2e425e0..d6a1d46 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java
@@ -82,10 +82,6 @@
return false;
}
- public static PsiType getTargetType(@NotNull PsiCallExpression expression) {
- return PsiTypesUtil.getExpectedTypeByParent(expression);
- }
-
public static Boolean mentionsTypeParameters(@Nullable PsiType returnType, final Set<PsiTypeParameter> typeParameters) {
if (returnType == null) return false;
return returnType.accept(new PsiTypeVisitor<Boolean>() {
@@ -125,7 +121,7 @@
private static boolean isInAssignmentOrInvocationContext(PsiExpression expr) {
final PsiElement context = expr.getParent();
- return context instanceof PsiExpressionList || isAssignmentContext(expr, context);
+ return context instanceof PsiExpressionList || context instanceof PsiConditionalExpression || isAssignmentContext(expr, context);
}
private static boolean isAssignmentContext(PsiExpression expr, PsiElement context) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java
new file mode 100644
index 0000000..19f50e6
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.impl.source.resolve.graphInference.constraints;
+
+import com.intellij.codeInsight.ExceptionUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
+import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * User: anna
+ */
+public class CheckedExceptionCompatibilityConstraint extends InputOutputConstraintFormula {
+ private static final Logger LOG = Logger.getInstance("#" + CheckedExceptionCompatibilityConstraint.class.getName());
+ private final PsiExpression myExpression;
+ private final PsiType myT;
+
+ public CheckedExceptionCompatibilityConstraint(PsiExpression expression, PsiType t) {
+ myExpression = expression;
+ myT = t;
+ }
+
+ @Override
+ public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
+ if (!PsiPolyExpressionUtil.isPolyExpression(myExpression) ||
+ myExpression instanceof PsiCallExpression) {
+ return true;
+ }
+ if (myExpression instanceof PsiParenthesizedExpression) {
+ constraints.add(new CheckedExceptionCompatibilityConstraint(((PsiParenthesizedExpression)myExpression).getExpression(), myT));
+ return true;
+ }
+ if (myExpression instanceof PsiConditionalExpression) {
+ final PsiExpression thenExpression = ((PsiConditionalExpression)myExpression).getThenExpression();
+ if (thenExpression != null) {
+ constraints.add(new CheckedExceptionCompatibilityConstraint(thenExpression, myT));
+ }
+ final PsiExpression elseExpression = ((PsiConditionalExpression)myExpression).getElseExpression();
+ if (elseExpression != null) {
+ constraints.add(new CheckedExceptionCompatibilityConstraint(elseExpression, myT));
+ }
+ return true;
+ }
+ if (myExpression instanceof PsiLambdaExpression || myExpression instanceof PsiMethodReferenceExpression) {
+ if (LambdaHighlightingUtil.checkInterfaceFunctional(myT) != null) {
+ return false;
+ }
+ final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(myT);
+ if (interfaceMethod == null) {
+ return false;
+ }
+
+ final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, PsiUtil.resolveGenericsClassInType(myT));
+ for (PsiParameter parameter : interfaceMethod.getParameterList().getParameters()) {
+ if (!session.isProperType(substitutor.substitute(parameter.getType()))) return false;
+ }
+ final PsiType returnType = interfaceMethod.getReturnType();
+ LOG.assertTrue(returnType != null, interfaceMethod);
+ if (!session.isProperType(substitutor.substitute(returnType))) return false;
+
+ final List<PsiType>
+ expectedThrownTypes = ContainerUtil.map(interfaceMethod.getThrowsList().getReferencedTypes(), new Function<PsiType, PsiType>() {
+ @Override
+ public PsiType fun(PsiType type) {
+ return substitutor.substitute(type);
+ }
+ });
+ final List<PsiType> expectedNonProperThrownTypes = new ArrayList<PsiType>();
+ for (PsiType type : expectedThrownTypes) {
+ if (!session.isProperType(type)) {
+ expectedNonProperThrownTypes.add(type);
+ }
+ }
+
+ final List<PsiType> thrownTypes = new ArrayList<PsiType>();
+ if (myExpression instanceof PsiLambdaExpression) {
+ //todo
+ } else {
+ final PsiElement resolve = ((PsiMethodReferenceExpression)myExpression).resolve();
+ if (resolve instanceof PsiMethod) {
+ for (PsiClassType type : ((PsiMethod)resolve).getThrowsList().getReferencedTypes()) {
+ if (!ExceptionUtil.isUncheckedException(type)) {
+ thrownTypes.add(type);
+ }
+ }
+ }
+ }
+
+ if (expectedNonProperThrownTypes.isEmpty()) {
+ for (PsiType thrownType : thrownTypes) {
+ if (!isAddressed(expectedThrownTypes, thrownType)) return false;
+ }
+ } else {
+ final ArrayList<PsiType> expectedProperTypes = new ArrayList<PsiType>(expectedThrownTypes);
+ expectedProperTypes.retainAll(expectedNonProperThrownTypes);
+ for (PsiType thrownType : thrownTypes) {
+ if (!isAddressed(expectedProperTypes, thrownType)) {
+ for (PsiType expectedNonProperThrownType : expectedNonProperThrownTypes) {
+ constraints.add(new TypeCompatibilityConstraint(expectedNonProperThrownType, thrownType));
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private static boolean isAddressed(List<PsiType> expectedThrownTypes, PsiType thrownType) {
+ for (PsiType expectedThrownType : expectedThrownTypes) {
+ if (TypeConversionUtil.isAssignable(expectedThrownType, thrownType)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ protected PsiExpression getExpression() {
+ return myExpression;
+ }
+
+ @Override
+ protected PsiType getT() {
+ return myT;
+ }
+
+ @Override
+ protected InputOutputConstraintFormula createSelfConstraint(PsiType type, PsiExpression expression) {
+ return new CheckedExceptionCompatibilityConstraint(expression, type);
+ }
+
+ @Override
+ protected void collectReturnTypeVariables(InferenceSession session,
+ PsiExpression psiExpression,
+ PsiMethod interfaceMethod,
+ Set<InferenceVariable> result) {
+ final PsiType returnType = interfaceMethod.getReturnType();
+ session.collectDependencies(returnType, result, true);
+ }
+}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ConstraintFormula.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ConstraintFormula.java
index 992d875..8dc8ee0 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ConstraintFormula.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ConstraintFormula.java
@@ -23,5 +23,5 @@
* User: anna
*/
public interface ConstraintFormula {
- boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints);
+ boolean reduce(InferenceSession session, List<ConstraintFormula> constraints);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
index a0e6a76..7084538 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
@@ -15,18 +15,22 @@
*/
package com.intellij.psi.impl.source.resolve.graphInference.constraints;
+import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
+import com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl;
+import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.NotNull;
-import java.util.List;
+import java.util.*;
/**
* User: anna
*/
-public class ExpressionCompatibilityConstraint implements ConstraintFormula {
+public class ExpressionCompatibilityConstraint extends InputOutputConstraintFormula {
private PsiExpression myExpression;
private PsiType myT;
@@ -36,7 +40,7 @@
}
@Override
- public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
+ public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
if (session.isProperType(myT)) {
return TypeConversionUtil.areTypesAssignmentCompatible(myT, myExpression);
}
@@ -69,11 +73,59 @@
}
if (myExpression instanceof PsiCallExpression) {
- //todo
+ final PsiExpressionList argumentList = ((PsiCallExpression)myExpression).getArgumentList();
+ if (argumentList != null) {
+ final Map<PsiElement,Pair<PsiMethod,PsiSubstitutor>> map = MethodCandidateInfo.CURRENT_CANDIDATE.get();
+ final Pair<PsiMethod,PsiSubstitutor> pair = map != null ? map.get(argumentList) : null;
+ final PsiMethod method = pair != null ? pair.first : ((PsiCallExpression)myExpression).resolveMethod();
+ PsiType returnType = null;
+ InferenceSession callSession = null;
+ if (method != null) {
+ returnType = method.getReturnType();
+ final PsiParameter[] parameters = method.getParameterList().getParameters();
+ if (returnType != null) {
+ callSession = new InferenceSession(method.getTypeParameters(), parameters,
+ argumentList.getExpressions(),
+ PsiSubstitutor.EMPTY, null, myExpression.getManager());
+
+ }
+ } else if (myExpression instanceof PsiNewExpression) { //default constructor
+ final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)myExpression).getClassOrAnonymousClassReference();
+ if (classReference != null) {
+ final PsiElement psiClass = classReference.resolve();
+ if (psiClass instanceof PsiClass) {
+ returnType = JavaPsiFacade.getElementFactory(argumentList.getProject()).createType((PsiClass)psiClass, PsiSubstitutor.EMPTY);
+ callSession = new InferenceSession(((PsiClass)psiClass).getTypeParameters(),
+ PsiParameter.EMPTY_ARRAY,
+ argumentList.getExpressions(),
+ PsiSubstitutor.EMPTY, null, myExpression.getManager());
+ }
+ }
+ }
+
+ if (callSession != null) {
+
+ for (PsiTypeParameter typeParameter : session.getTypeParams()) {
+ callSession.addCapturedVariable(typeParameter);
+ }
+ callSession.addConstraint(new TypeCompatibilityConstraint(myT, returnType));
+ final PsiSubstitutor callSubstitutor = callSession.infer();
+
+ if (myExpression instanceof PsiMethodCallExpression) {
+ returnType = PsiMethodCallExpressionImpl.captureReturnType((PsiMethodCallExpression)myExpression, method, returnType, callSubstitutor);
+ }
+ else {
+ returnType = callSubstitutor.substitute(returnType);
+ }
+ constraints.add(new TypeCompatibilityConstraint(myT, returnType)); //todo primitive types
+ }
+ }
+ return true;
}
if (myExpression instanceof PsiMethodReferenceExpression) {
- //todo
+ constraints.add(new PsiMethodReferenceCompatibilityConstraint(((PsiMethodReferenceExpression)myExpression), myT));
+ return true;
}
if (myExpression instanceof PsiLambdaExpression) {
@@ -104,4 +156,37 @@
result = 31 * result + myT.hashCode();
return result;
}
+
+ @Override
+ public PsiExpression getExpression() {
+ return myExpression;
+ }
+
+ @Override
+ public PsiType getT() {
+ return myT;
+ }
+
+ @Override
+ protected InputOutputConstraintFormula createSelfConstraint(PsiType type, PsiExpression expression) {
+ return new ExpressionCompatibilityConstraint(expression, type);
+ }
+
+ protected void collectReturnTypeVariables(InferenceSession session,
+ PsiExpression psiExpression,
+ PsiMethod interfaceMethod,
+ Set<InferenceVariable> result) {
+ if (psiExpression instanceof PsiLambdaExpression) {
+ final PsiType returnType = interfaceMethod.getReturnType();
+ if (returnType != PsiType.VOID) {
+ final List<PsiExpression> returnExpressions = LambdaUtil.getReturnExpressions((PsiLambdaExpression)psiExpression);
+ for (PsiExpression expression : returnExpressions) {
+ final Set<InferenceVariable> resultInputVars = createSelfConstraint(returnType, expression).getInputVariables(session);
+ if (resultInputVars != null) {
+ result.addAll(resultInputVars);
+ }
+ }
+ }
+ }
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java
new file mode 100644
index 0000000..d06538c
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.impl.source.resolve.graphInference.constraints;
+
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
+import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
+import com.intellij.psi.util.PsiUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * User: anna
+ * Date: 9/25/13
+ */
+public abstract class InputOutputConstraintFormula implements ConstraintFormula {
+
+ protected abstract PsiExpression getExpression();
+ protected abstract PsiType getT();
+ protected abstract InputOutputConstraintFormula createSelfConstraint(PsiType type, PsiExpression expression);
+ protected abstract void collectReturnTypeVariables(InferenceSession session,
+ PsiExpression psiExpression,
+ PsiMethod interfaceMethod,
+ Set<InferenceVariable> result);
+
+ public Set<InferenceVariable> getInputVariables(InferenceSession session) {
+ final PsiExpression psiExpression = getExpression();
+ if (PsiPolyExpressionUtil.isPolyExpression(psiExpression)) {
+ final PsiType type = getT();
+ if (psiExpression instanceof PsiLambdaExpression || psiExpression instanceof PsiMethodReferenceExpression) {
+ final InferenceVariable inferenceVariable = session.getInferenceVariable(type);
+ if (inferenceVariable != null) {
+ return Collections.singleton(inferenceVariable);
+ }
+ final PsiType functionalInterfaceType = psiExpression instanceof PsiLambdaExpression
+ ? ((PsiLambdaExpression)psiExpression).getFunctionalInterfaceType()
+ : ((PsiMethodReferenceExpression)psiExpression).getFunctionalInterfaceType();
+ if (functionalInterfaceType != null) {
+ final PsiType functionType =
+ psiExpression instanceof PsiLambdaExpression
+ ? FunctionalInterfaceParameterizationUtil.getFunctionalType(functionalInterfaceType, (PsiLambdaExpression)psiExpression)
+ : functionalInterfaceType;
+ final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionType);
+ final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
+ if (interfaceMethod != null) {
+
+ final Set<InferenceVariable> result = new HashSet<InferenceVariable>();
+ final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult);
+ for (PsiParameter parameter : interfaceMethod.getParameterList().getParameters()) {
+ session.collectDependencies(substitutor.substitute(parameter.getType()), result, true);
+ }
+
+ collectReturnTypeVariables(session, psiExpression, interfaceMethod, result);
+
+ return result;
+ }
+ }
+ }
+
+ if (psiExpression instanceof PsiParenthesizedExpression) {
+ final PsiExpression expression = ((PsiParenthesizedExpression)psiExpression).getExpression();
+ return expression != null ? createSelfConstraint(type, expression).getInputVariables(session) : null;
+ }
+
+ if (psiExpression instanceof PsiConditionalExpression) {
+ final PsiExpression thenExpression = ((PsiConditionalExpression)psiExpression).getThenExpression();
+ final PsiExpression elseExpression = ((PsiConditionalExpression)psiExpression).getElseExpression();
+ final Set<InferenceVariable> thenResult = thenExpression != null ? createSelfConstraint(type, thenExpression).getInputVariables(session) : null;
+ final Set<InferenceVariable> elseResult = elseExpression != null ? createSelfConstraint(type, elseExpression).getInputVariables(session) : null;
+ if (thenResult == null) {
+ return elseResult;
+ } else if (elseResult == null) {
+ return thenResult;
+ } else {
+ thenResult.addAll(elseResult);
+ return thenResult;
+ }
+ }
+ }
+ return null;
+ }
+
+
+ @Nullable
+ public Set<InferenceVariable> getOutputVariables(Set<InferenceVariable> inputVariables, InferenceSession session) {
+ if (!PsiPolyExpressionUtil.isPolyExpression(getExpression())) {
+ final HashSet<InferenceVariable> mentionedVariables = new HashSet<InferenceVariable>();
+ session.collectDependencies(getT(), mentionedVariables, true);
+ mentionedVariables.removeAll(inputVariables);
+ return mentionedVariables;
+ }
+ return null;
+ }
+}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java
index 9d9dad46..d775175 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java
@@ -1,8 +1,8 @@
package com.intellij.psi.impl.source.resolve.graphInference.constraints;
import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
-import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
import com.intellij.psi.util.PsiUtil;
import java.util.List;
@@ -20,30 +20,21 @@
}
@Override
- public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
- final InferenceVariable inferenceVariable = session.getInferenceVariable(myT);
- if (inferenceVariable != null) {
- delayedConstraints.add(this);
- return true;
- }
+ public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
if (LambdaHighlightingUtil.checkInterfaceFunctional(myT) != null) {
return false;
}
if (myExpression.hasFormalParameterTypes()) {
}
- final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(myT);
+ final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(
+ FunctionalInterfaceParameterizationUtil.getFunctionalType(myT, myExpression));
+ final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
if (interfaceMethod == null) {
return false;
}
- final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, PsiUtil.resolveGenericsClassInType(myT));
+ final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult);
final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters();
- for (PsiParameter parameter : parameters) {
- if (!session.isProperType(parameter.getType())) {
- delayedConstraints.add(this);
- return true;
- }
- }
final PsiParameter[] lambdaParameters = myExpression.getParameterList().getParameters();
if (lambdaParameters.length != parameters.length) {
@@ -53,20 +44,27 @@
for (int i = 0; i < lambdaParameters.length; i++) {
constraints.add(new TypeEqualityConstraint(lambdaParameters[i].getType(), substitutor.substitute(parameters[i].getType())));
}
+ } else {
+ for (PsiParameter parameter : parameters) {
+ if (!session.isProperType(substitutor.substitute(parameter.getType()))) {
+ return false;
+ }
+ }
}
final PsiType returnType = interfaceMethod.getReturnType();
if (returnType != null) {
+ final List<PsiExpression> returnExpressions = LambdaUtil.getReturnExpressions(myExpression);
if (returnType.equals(PsiType.VOID)) {
- if (!myExpression.isVoidCompatible() && !(myExpression.getBody() instanceof PsiExpression)) {
+ if (!returnExpressions.isEmpty() && !(myExpression.getBody() instanceof PsiExpression)) {
return false;
}
} else {
- if (myExpression.isVoidCompatible()) { //not value-compatible
+ if (returnExpressions.isEmpty()) { //not value-compatible
return false;
}
- for (PsiExpression returnExpressions : LambdaUtil.getReturnExpressions(myExpression)) {
- constraints.add(new ExpressionCompatibilityConstraint(returnExpressions, returnType));
+ for (PsiExpression returnExpression : returnExpressions) {
+ constraints.add(new ExpressionCompatibilityConstraint(returnExpression, substitutor.substitute(returnType)));
}
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
new file mode 100644
index 0000000..d1de66e
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.impl.source.resolve.graphInference.constraints;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
+import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
+import com.intellij.psi.util.PsiUtil;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * User: anna
+ */
+public class PsiMethodReferenceCompatibilityConstraint implements ConstraintFormula {
+ private static final Logger LOG = Logger.getInstance("#" + PsiMethodReferenceCompatibilityConstraint.class.getName());
+ private final PsiMethodReferenceExpression myExpression;
+ private final PsiType myT;
+
+ public PsiMethodReferenceCompatibilityConstraint(PsiMethodReferenceExpression expression, PsiType t) {
+ myExpression = expression;
+ myT = t;
+ }
+
+ @Override
+ public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
+ if (LambdaHighlightingUtil.checkInterfaceFunctional(myT) != null) {
+ return false;
+ }
+
+ final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(myT);
+ if (interfaceMethod == null) {
+ return false;
+ }
+
+ final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, PsiUtil.resolveGenericsClassInType(myT));
+ final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters();
+ for (PsiParameter parameter : parameters) {
+ if (!session.isProperType(substitutor.substitute(parameter.getType()))) {
+ return false;
+ }
+ }
+
+ final PsiElement resolve = myExpression.resolve();
+ if (resolve == null) {
+ return false;
+ }
+
+ final PsiType returnType = interfaceMethod.getReturnType();
+ LOG.assertTrue(returnType != null, interfaceMethod);
+ if (PsiType.VOID.equals(returnType)) {
+ return true;
+ }
+
+ if (resolve instanceof PsiMethod) {
+ final PsiMethod method = (PsiMethod)resolve;
+ final PsiType referencedMethodReturnType;
+ if (method.isConstructor()) {
+ final PsiClass containingClass = method.getContainingClass();
+ LOG.assertTrue(containingClass != null, method);
+ referencedMethodReturnType = JavaPsiFacade.getElementFactory(method.getProject()).createType(containingClass);
+ }
+ else {
+ referencedMethodReturnType = method.getReturnType();
+ }
+ LOG.assertTrue(referencedMethodReturnType != null, method);
+
+ if (myExpression.getTypeParameters().length == 0 &&
+ ((PsiMethod)resolve).getTypeParameters().length > 0 &&
+ PsiPolyExpressionUtil.mentionsTypeParameters(returnType, new HashSet<PsiTypeParameter>(Arrays.asList(interfaceMethod.getTypeParameters())))) {
+ //todo target type constraint
+ return true;
+ }
+
+ if (PsiType.VOID.equals(referencedMethodReturnType)) {
+ return false;
+ }
+
+ constraints.add(new TypeCompatibilityConstraint(substitutor.substitute(returnType), referencedMethodReturnType));
+ }
+
+ return true;
+ }
+}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/SubtypingConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/SubtypingConstraint.java
index 64c28d1..e2677bf7 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/SubtypingConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/SubtypingConstraint.java
@@ -20,7 +20,6 @@
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
import com.intellij.psi.util.TypeConversionUtil;
-import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -39,7 +38,7 @@
}
@Override
- public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
+ public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
if (myIsRefTypes) {
if (session.isProperType(myS) && session.isProperType(myT)) {
if (myT == null || myS == null) return myS == myT;
@@ -127,6 +126,11 @@
}
return false;
} else {
+
+ if (myS instanceof PsiCapturedWildcardType) {
+ myS = ((PsiCapturedWildcardType)myS).getWildcard();
+ }
+
if (myS instanceof PsiWildcardType) {
final PsiType sBound = ((PsiWildcardType)myS).getBound();
if (sBound != null && ((PsiWildcardType)myS).isSuper()) {
@@ -140,9 +144,19 @@
}
return false;
} else {
+ InferenceVariable inferenceVariable = session.getInferenceVariable(myT);
if (myS instanceof PsiWildcardType) {
- return false;
+ return inferenceVariable != null && inferenceVariable.isCaptured();
} else {
+ if (inferenceVariable != null) {
+ inferenceVariable.addBound(myS, InferenceBound.EQ);
+ return true;
+ }
+ inferenceVariable = session.getInferenceVariable(myS);
+ if (inferenceVariable != null) {
+ inferenceVariable.addBound(myT, InferenceBound.EQ);
+ return true;
+ }
constraints.add(new SubtypingConstraint(myT, myS, true));
return true;
}
@@ -159,6 +173,9 @@
SubtypingConstraint that = (SubtypingConstraint)o;
if (myIsRefTypes != that.myIsRefTypes) return false;
+
+ if (!myIsRefTypes && myS instanceof PsiCapturedWildcardType && myS != that.myS) return false;
+
if (myS != null ? !myS.equals(that.myS) : that.myS != null) return false;
if (myT != null ? !myT.equals(that.myT) : that.myT != null) return false;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java
index 353f03b..cd9ec95 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java
@@ -37,7 +37,7 @@
}
@Override
- public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
+ public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
if (session.isProperType(myT) && session.isProperType(myS)) {
return TypeConversionUtil.isAssignable(myS, myT);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java
index a714656..06e7b2b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java
@@ -38,7 +38,7 @@
}
@Override
- public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
+ public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
if (session.isProperType(myT) && session.isProperType(myS)) {
return myT.equals(myS);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java
index 4e2300f..80b7e94 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java
@@ -18,24 +18,23 @@
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.tree.*;
-import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.ChildRoleBase;
+import com.intellij.psi.tree.IElementType;
import com.intellij.util.CharTable;
import org.jetbrains.annotations.NotNull;
-public class PsiArrayInitializerExpressionImpl extends ExpressionPsiElement implements PsiArrayInitializerExpression, Constants {
+public class PsiArrayInitializerExpressionImpl extends ExpressionPsiElement implements PsiArrayInitializerExpression {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiArrayInitializerExpressionImpl");
public PsiArrayInitializerExpressionImpl() {
- super(ARRAY_INITIALIZER_EXPRESSION);
+ super(JavaElementType.ARRAY_INITIALIZER_EXPRESSION);
}
@Override
@NotNull
public PsiExpression[] getInitializers(){
- return getChildrenAsPsiElements(EXPRESSION_BIT_SET, PsiExpression.ARRAY_FACTORY);
+ return getChildrenAsPsiElements(ElementType.EXPRESSION_BIT_SET, PsiExpression.ARRAY_FACTORY);
}
@Override
@@ -69,10 +68,10 @@
return null;
case ChildRole.LBRACE:
- return findChildByType(LBRACE);
+ return findChildByType(JavaTokenType.LBRACE);
case ChildRole.RBRACE:
- return findChildByType(RBRACE);
+ return findChildByType(JavaTokenType.RBRACE);
}
}
@@ -80,17 +79,17 @@
public int getChildRole(ASTNode child) {
LOG.assertTrue(child.getTreeParent() == this);
IElementType i = child.getElementType();
- if (i == COMMA) {
+ if (i == JavaTokenType.COMMA) {
return ChildRole.COMMA;
}
- else if (i == LBRACE) {
+ else if (i == JavaTokenType.LBRACE) {
return ChildRole.LBRACE;
}
- else if (i == RBRACE) {
+ else if (i == JavaTokenType.RBRACE) {
return ChildRole.RBRACE;
}
else {
- if (EXPRESSION_BIT_SET.contains(child.getElementType())) {
+ if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) {
return ChildRole.EXPRESSION_IN_LIST;
}
return ChildRoleBase.NONE;
@@ -129,17 +128,17 @@
if (ElementType.EXPRESSION_BIT_SET.contains(first.getElementType())) {
final CharTable charTab = SharedImplUtil.findCharTableByTree(this);
for (ASTNode child = first.getTreeNext(); child != null; child = child.getTreeNext()) {
- if (child.getElementType() == COMMA) break;
+ if (child.getElementType() == JavaTokenType.COMMA) break;
if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) {
- TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, charTab, getManager());
+ TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, charTab, getManager());
super.addInternal(comma, comma, first, Boolean.FALSE);
break;
}
}
for (ASTNode child = first.getTreePrev(); child != null; child = child.getTreePrev()) {
- if (child.getElementType() == COMMA) break;
+ if (child.getElementType() == JavaTokenType.COMMA) break;
if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) {
- TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, charTab, getManager());
+ TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, charTab, getManager());
super.addInternal(comma, comma, child, Boolean.FALSE);
break;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java
index 3093099..5091ea0 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java
@@ -19,6 +19,7 @@
import com.intellij.psi.*;
import com.intellij.psi.controlFlow.*;
import com.intellij.psi.impl.PsiImplUtil;
+import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
import com.intellij.psi.impl.source.tree.ChildRole;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.scope.PsiScopeProcessor;
@@ -63,7 +64,7 @@
@Nullable
@Override
public PsiType getFunctionalInterfaceType() {
- return LambdaUtil.getFunctionalInterfaceType(this, true);
+ return FunctionalInterfaceParameterizationUtil.getFunctionalType(LambdaUtil.getFunctionalInterfaceType(this, true), this);
}
@Override
@@ -118,6 +119,6 @@
for (PsiParameter parameter : parameters) {
if (parameter.getTypeElement() == null) return false;
}
- return parameters.length > 0;
+ return true;
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java
index 1dd74f1..36013c36 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java
@@ -170,7 +170,7 @@
}
@Nullable
- private static PsiType getResultType(PsiExpression call,
+ private static PsiType getResultType(PsiMethodCallExpression call,
PsiReferenceExpression methodExpression,
JavaResolveResult result,
@NotNull final LanguageLevel languageLevel) {
@@ -196,40 +196,46 @@
ret = ((PsiClassType)ret).setLanguageLevel(languageLevel);
}
if (is15OrHigher) {
- final PsiSubstitutor substitutor = result.getSubstitutor();
- PsiType substitutedReturnType = substitutor.substitute(ret);
- if (substitutedReturnType == null) return TypeConversionUtil.erasure(ret);
- if (PsiUtil.isRawSubstitutor(method, substitutor)) {
- final PsiType returnTypeErasure = TypeConversionUtil.erasure(ret);
- if (Comparing.equal(TypeConversionUtil.erasure(substitutedReturnType), returnTypeErasure)) {
- return returnTypeErasure;
- }
- }
- PsiType lowerBound = PsiType.NULL;
- if (substitutedReturnType instanceof PsiCapturedWildcardType) {
- lowerBound = ((PsiCapturedWildcardType)substitutedReturnType).getLowerBound();
- } else if (substitutedReturnType instanceof PsiWildcardType) {
- lowerBound = ((PsiWildcardType)substitutedReturnType).getSuperBound();
- }
- if (lowerBound != PsiType.NULL) { //? super
- final PsiClass containingClass = method.getContainingClass();
- final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
- final PsiClass childClass = qualifierExpression != null ? PsiUtil.resolveClassInClassTypeOnly(qualifierExpression.getType()) : null;
- if (containingClass != null && childClass != null) {
- final PsiType typeInChildClassTypeParams = TypeConversionUtil.getSuperClassSubstitutor(containingClass, childClass, PsiSubstitutor.EMPTY).substitute(ret);
- final PsiClass substituted = PsiUtil.resolveClassInClassTypeOnly(typeInChildClassTypeParams);
- if (substituted instanceof PsiTypeParameter) {
- final PsiClassType[] extendsListTypes = substituted.getExtendsListTypes();
- if (extendsListTypes.length == 1) {
- return extendsListTypes[0];
- }
- }
- }
- }
- return PsiImplUtil.normalizeWildcardTypeByPosition(substitutedReturnType, call);
+ return captureReturnType(call, method, ret, result.getSubstitutor());
}
return TypeConversionUtil.erasure(ret);
}
}
+
+ public static PsiType captureReturnType(PsiMethodCallExpression call,
+ PsiMethod method,
+ PsiType ret,
+ PsiSubstitutor substitutor) {
+ PsiType substitutedReturnType = substitutor.substitute(ret);
+ if (substitutedReturnType == null) return TypeConversionUtil.erasure(ret);
+ if (PsiUtil.isRawSubstitutor(method, substitutor)) {
+ final PsiType returnTypeErasure = TypeConversionUtil.erasure(ret);
+ if (Comparing.equal(TypeConversionUtil.erasure(substitutedReturnType), returnTypeErasure)) {
+ return returnTypeErasure;
+ }
+ }
+ PsiType lowerBound = PsiType.NULL;
+ if (substitutedReturnType instanceof PsiCapturedWildcardType) {
+ lowerBound = ((PsiCapturedWildcardType)substitutedReturnType).getLowerBound();
+ } else if (substitutedReturnType instanceof PsiWildcardType) {
+ lowerBound = ((PsiWildcardType)substitutedReturnType).getSuperBound();
+ }
+ if (lowerBound != PsiType.NULL) { //? super
+ final PsiClass containingClass = method.getContainingClass();
+ final PsiExpression qualifierExpression = call.getMethodExpression().getQualifierExpression();
+ final PsiClass childClass = qualifierExpression != null ? PsiUtil.resolveClassInClassTypeOnly(qualifierExpression.getType()) : null;
+ if (containingClass != null && childClass != null) {
+ final PsiType typeInChildClassTypeParams = TypeConversionUtil.getSuperClassSubstitutor(containingClass, childClass, PsiSubstitutor.EMPTY).substitute(ret);
+ final PsiClass substituted = PsiUtil.resolveClassInClassTypeOnly(typeInChildClassTypeParams);
+ if (substituted instanceof PsiTypeParameter) {
+ final PsiClassType[] extendsListTypes = substituted.getExtendsListTypes();
+ if (extendsListTypes.length == 1) {
+ return extendsListTypes[0];
+ }
+ }
+ }
+ }
+ return PsiImplUtil.normalizeWildcardTypeByPosition(substitutedReturnType, call);
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
index 4678857..537ce23 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
@@ -72,6 +72,15 @@
}
@Override
+ public boolean isExact() {
+ PsiElement resolve = resolve();
+ if (resolve instanceof PsiMethod) {
+ return !((PsiMethod)resolve).isVarArgs();
+ }
+ return true;
+ }
+
+ @Override
public PsiExpression getQualifierExpression() {
final PsiElement qualifier = getQualifier();
return qualifier instanceof PsiExpression ? (PsiExpression)qualifier : null;
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
index 27e4227..6992e9f 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
@@ -51,15 +51,15 @@
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.scope.conflictResolvers.JavaMethodsConflictResolver");
private final PsiElement myArgumentsList;
- private final PsiType[] myActualParameterTypes;
+ private PsiType[] myActualParameterTypes;
protected LanguageLevel myLanguageLevel;
public JavaMethodsConflictResolver(@NotNull PsiExpressionList list, @NotNull LanguageLevel languageLevel) {
- this(list, list.getExpressionTypes(), languageLevel);
+ this(list, null, languageLevel);
}
public JavaMethodsConflictResolver(@NotNull PsiElement argumentsList,
- @NotNull PsiType[] actualParameterTypes,
+ PsiType[] actualParameterTypes,
@NotNull LanguageLevel languageLevel) {
myArgumentsList = argumentsList;
myActualParameterTypes = actualParameterTypes;
@@ -71,7 +71,7 @@
if (conflicts.isEmpty()) return null;
if (conflicts.size() == 1) return conflicts.get(0);
- boolean atLeastOneMatch = checkParametersNumber(conflicts, myActualParameterTypes.length, true);
+ boolean atLeastOneMatch = checkParametersNumber(conflicts, getActualParameterTypes().length, true);
if (conflicts.size() == 1) return conflicts.get(0);
checkSameSignatures(conflicts);
@@ -80,7 +80,7 @@
checkAccessStaticLevels(conflicts, true);
if (conflicts.size() == 1) return conflicts.get(0);
- checkParametersNumber(conflicts, myActualParameterTypes.length, false);
+ checkParametersNumber(conflicts, getActualParameterTypes().length, false);
if (conflicts.size() == 1) return conflicts.get(0);
final int applicabilityLevel = checkApplicability(conflicts);
@@ -96,7 +96,7 @@
checkSpecifics(conflicts, applicabilityLevel, myLanguageLevel);
if (conflicts.size() == 1) return conflicts.get(0);
- checkPrimitiveVarargs(conflicts, myActualParameterTypes.length);
+ checkPrimitiveVarargs(conflicts, getActualParameterTypes().length);
if (conflicts.size() == 1) return conflicts.get(0);
checkAccessStaticLevels(conflicts, false);
@@ -109,8 +109,8 @@
private void checkLambdaApplicable(@NotNull List<CandidateInfo> conflicts, @NotNull LanguageLevel languageLevel) {
if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) return;
- for (int i = 0; i < myActualParameterTypes.length; i++) {
- PsiType parameterType = myActualParameterTypes[i];
+ for (int i = 0; i < getActualParameterTypes().length; i++) {
+ PsiType parameterType = getActualParameterTypes()[i];
if (parameterType instanceof PsiLambdaExpressionType) {
final PsiLambdaExpression lambdaExpression = ((PsiLambdaExpressionType)parameterType).getExpression();
for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext(); ) {
@@ -122,7 +122,7 @@
if (methodParameters.length == 0) continue;
final PsiParameter param = i < methodParameters.length ? methodParameters[i] : methodParameters[methodParameters.length - 1];
final PsiType paramType = param.getType();
- if (!LambdaUtil.isAcceptable(lambdaExpression, conflict.getSubstitutor().substitute(paramType), true)) {
+ if (!LambdaUtil.isAcceptable(lambdaExpression, conflict.getSubstitutor().substitute(paramType), lambdaExpression.hasFormalParameterTypes())) {
iterator.remove();
} else {
/*todo
@@ -141,7 +141,7 @@
}
}
}
- checkMoreSpecificReturnType(conflicts, myActualParameterTypes, languageLevel);
+ checkMoreSpecificReturnType(conflicts, getActualParameterTypes(), languageLevel);
}
public void checkSpecifics(@NotNull List<CandidateInfo> conflicts,
@@ -426,6 +426,14 @@
(method.getCurrentFileResolveScope() instanceof PsiImportStaticStatement ? 0 : 1);
}
+ private PsiType[] getActualParameterTypes() {
+ if (myActualParameterTypes == null) {
+ LOG.assertTrue(myArgumentsList instanceof PsiExpressionList, myArgumentsList);
+ myActualParameterTypes = ((PsiExpressionList)myArgumentsList).getExpressionTypes();
+ }
+ return myActualParameterTypes;
+ }
+
private enum Specifics {
FIRST,
SECOND,
@@ -489,7 +497,7 @@
ProgressManager.checkCanceled();
PsiType type1 = classSubstitutor1.substitute(types1[i]);
PsiType type2 = classSubstitutor2.substitute(types2[i]);
- PsiType argType = i < myActualParameterTypes.length ? myActualParameterTypes[i] : null;
+ PsiType argType = i < getActualParameterTypes().length ? getActualParameterTypes()[i] : null;
boolean boxingInFirst = false;
if (isBoxingHappened(argType, type1, languageLevel)) {
@@ -691,6 +699,12 @@
for (int functionalInterfaceIdx = 0; functionalInterfaceIdx < actualParameterTypes.length; functionalInterfaceIdx++) {
final PsiType interfaceReturnType = getReturnType(functionalInterfaceIdx, method);
final PsiType interfaceReturnType1 = getReturnType(functionalInterfaceIdx, conflict);
+ if (actualParameterTypes[functionalInterfaceIdx] instanceof PsiLambdaExpressionType) {
+ final PsiLambdaExpression lambdaExpression = ((PsiLambdaExpressionType)actualParameterTypes[functionalInterfaceIdx]).getExpression();
+ if (!lambdaExpression.hasFormalParameterTypes()) {
+ return Specifics.NEITHER;
+ }
+ }
if (actualParameterTypes[functionalInterfaceIdx] instanceof PsiLambdaExpressionType || actualParameterTypes[functionalInterfaceIdx] instanceof PsiMethodReferenceType) {
if (interfaceReturnType != null && interfaceReturnType1 != null && !Comparing.equal(interfaceReturnType, interfaceReturnType1)) {
Specifics moreSpecific1 = comparePrimitives(actualParameterTypes[functionalInterfaceIdx], interfaceReturnType, interfaceReturnType1);
diff --git a/java/java-tests/testData/codeInsight/completion/normal/NoFieldsInImplements.java b/java/java-tests/testData/codeInsight/completion/normal/NoFieldsInImplements.java
new file mode 100644
index 0000000..bb4a834
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normal/NoFieldsInImplements.java
@@ -0,0 +1,9 @@
+public class Doo implements Intf.I<caret> {
+}
+
+
+
+interface Intf {
+ int INT_FIELD = 2;
+ interface Inner {}
+}
diff --git a/java/java-tests/testData/codeInsight/completion/normal/NoFieldsInImplements_after.java b/java/java-tests/testData/codeInsight/completion/normal/NoFieldsInImplements_after.java
new file mode 100644
index 0000000..ea272a1
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normal/NoFieldsInImplements_after.java
@@ -0,0 +1,9 @@
+public class Doo implements Intf.Inner<caret> {
+}
+
+
+
+interface Intf {
+ int INT_FIELD = 2;
+ interface Inner {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AmbiguousTypeParamVsConcrete.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AmbiguousTypeParamVsConcrete.java
new file mode 100644
index 0000000..272fb29
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AmbiguousTypeParamVsConcrete.java
@@ -0,0 +1,22 @@
+public class CssPropertyValueImpl extends CssTableValueBase<CssPropertyValue, Object> implements CssPropertyValue {
+ public CssPropertyValueImpl(final Type type) {
+ super(type);
+ }
+}
+
+public abstract class CssTableValueBase<V extends CssTableValue, T> implements CssTableValue<V, T> {
+
+ protected CssTableValueBase(final Type type) {
+ }
+
+ protected CssTableValueBase(final T value) {
+ }
+}
+
+enum Type {}
+
+interface CssTableValue<A, B> {
+}
+
+interface CssPropertyValue extends CssTableValue<CssPropertyValue, Object> {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AnnotationsAsPartOfModifierList.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AnnotationsAsPartOfModifierList.java
new file mode 100644
index 0000000..3fca0c0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AnnotationsAsPartOfModifierList.java
@@ -0,0 +1,9 @@
+@Deprecated @SuppressWarnings("")
+<error descr="Class 'Foo' must either be declared abstract or implement abstract method 'run()' in 'Runnable'">public class Foo implements Runnable</error> {
+
+}
+
+class F {
+ @Deprecated @SuppressWarnings("") <error descr="'f()' is already defined in 'F'">void f()</error> {}
+ @Deprecated @SuppressWarnings("") <error descr="'f()' is already defined in 'F'">void f()</error> {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Autoboxing.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Autoboxing.java
new file mode 100644
index 0000000..9815668
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Autoboxing.java
@@ -0,0 +1,69 @@
+public class Autoboxing {
+ public boolean compare(short s, Integer i) {
+ return i == s; //OK, i is unboxed
+ }
+
+ public boolean compare(Short s, Integer i) {
+ return <error descr="Operator '==' cannot be applied to 'java.lang.Integer', 'java.lang.Short'">i == s</error>; //comparing as references
+ }
+
+ void f(Integer i) {
+ switch(i) {
+ default:
+ }
+ }
+
+ {
+ Object data = 1;
+ boolean is1 = <error descr="Operator '==' cannot be applied to 'java.lang.Object', 'int'">data == 1</error>;
+ }
+
+ //IDEADEV-5549: Short and double are convertible
+ public static double f () {
+ Short s = 0;
+ return (double)s;
+ }
+
+ //IDEADEV-5613
+ class DumbTest {
+ private long eventId;
+
+ public int hashCode() {
+ return ((Long) eventId).hashCode();
+ }
+ }
+
+ public static void main(String[] args) {
+ Long l = 0L;
+ Short s = 0;
+
+ int d = <error descr="Inconvertible types; cannot cast 'java.lang.Long' to 'int'">(int)l</error>;
+ d = (int)s;
+
+ short t = 0;
+ Integer d1 = <error descr="Inconvertible types; cannot cast 'short' to 'java.lang.Integer'">(Integer) t</error>;
+ Byte b = <error descr="Inconvertible types; cannot cast 'short' to 'java.lang.Byte'">(Byte) t</error>;
+
+ }
+
+ {
+ {
+ boolean cond = true;
+ // test for JLS3 bug, see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6888770
+ Byte B = 0;
+ byte b = 0;
+ byte value = cond ? B : b; /////////
+
+ short s = 0;
+ Short S = 0;
+ short rs = cond ? S : s;
+
+ char c = 0;
+ Character C = 0;
+ char rc = cond ? C : c;
+
+ boolean bb = cond ? Boolean.FALSE : true;
+ }
+
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AutoboxingConstructors.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AutoboxingConstructors.java
new file mode 100644
index 0000000..12c5332
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AutoboxingConstructors.java
@@ -0,0 +1,13 @@
+public class Test {
+
+ public Test(Object a) {
+ }
+
+ public Test(int i) {
+ this(new Integer(i));
+ }
+
+ public Test(long l) {
+ this(new Long(l));
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AutoboxingMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AutoboxingMethods.java
new file mode 100644
index 0000000..d020997
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/AutoboxingMethods.java
@@ -0,0 +1,44 @@
+public class Autoboxing {
+ void method(int i) {
+ System.out.println("i = " + i);
+ }
+
+ void method(Integer integer) {
+ System.out.println("integer = " + integer);
+ }
+
+ void m1(Integer integer) { }
+ void m2(int i) { }
+
+ {
+ method(10);
+ method(new Integer(10));
+ m1(10);
+ m1(new Integer(10));
+ m2(10);
+ m2(new Integer(10));
+ }
+}
+public class Autoboxing1 {
+ void method(String s, int i) {
+ System.out.println("i = " + i);
+ }
+
+ void method(String s, Object o) {
+ System.out.println("integer = " + o);
+ }
+
+ {
+ method("abc", new Integer(10));
+ method("abc", 10);
+ }
+}
+
+class BoxingConflict {
+ public static void main(String[] args) {
+ add<error descr="Ambiguous method call: both 'BoxingConflict.add(long, Long)' and 'BoxingConflict.add(Long, Long)' match">(0L, 0L)</error>;
+ }
+
+ public static void add(long k, Long v) { }
+ public static void add(Long k, Long v) { }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/BooleanInferenceFromIfCondition.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/BooleanInferenceFromIfCondition.java
new file mode 100644
index 0000000..44fbeef
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/BooleanInferenceFromIfCondition.java
@@ -0,0 +1,12 @@
+public class Main {
+ public <T> T getAttribute() {return null;}
+ public <T> T getAttribute(T def) {return null;}
+
+ {
+ if (getAttribute()) {}
+
+ while (getAttribute()) {}
+ do {} while (getAttribute());
+ for(int i = 0; getAttribute(); i++);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/BoxingSpecific.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/BoxingSpecific.java
new file mode 100644
index 0000000..382f4e7
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/BoxingSpecific.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+abstract class A {
+ void computeCostIfNeeded(Map<Object, Integer> costMap) {
+ Math.min(costMap.get(null), 1);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CaptureTopLevelWildcardsForConditionalExpression.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CaptureTopLevelWildcardsForConditionalExpression.java
new file mode 100644
index 0000000..86c2e40
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CaptureTopLevelWildcardsForConditionalExpression.java
@@ -0,0 +1,6 @@
+import java.util.*;
+class Bug {
+ void foo(Double d) {
+ List<Class<?>> list = Arrays.asList(d == null ? Object.class : d.getClass());
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CaptureWildcardsInTypeCasts.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CaptureWildcardsInTypeCasts.java
new file mode 100644
index 0000000..9bd704b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CaptureWildcardsInTypeCasts.java
@@ -0,0 +1,8 @@
+import java.util.Collection;
+
+class Foo {
+ private void test() {
+ Object x = null;
+ ((java.util.Collection<?>)x).add<error descr="'add(capture<?>)' in 'java.util.Collection' cannot be applied to '(java.lang.String)'">("")</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CapturedWildcardAssignments.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CapturedWildcardAssignments.java
new file mode 100644
index 0000000..08761a6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/CapturedWildcardAssignments.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.*;
+
+public class Test {
+ public static void bar() {
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends java.util.Iterator>>', required: 'java.lang.Class<? extends java.util.Iterator<?>>'">Class<? extends Iterator<?>> c = foo();</error>
+ }
+
+ public static Class<? extends Iterator> foo() {
+ return null;
+ }
+}
+
+class Example {
+ static List<? extends AbstractTreeNode> treeNodes = null;
+
+ public static void main(String[] args) {
+ for (AbstractTreeNode<String> treeNode : treeNodes) {
+
+ }
+ }
+
+}
+class AbstractTreeNode<T> {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ClassInheritance.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ClassInheritance.java
new file mode 100644
index 0000000..1a4e80f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ClassInheritance.java
@@ -0,0 +1,122 @@
+class D implements I<I>{
+}
+class DT<T> implements I<T>{
+}
+
+interface I <T> {
+}
+
+<error descr="'I' cannot be inherited with different type arguments: 'I' and 'D'">class CCC extends D implements I<D></error> {
+}
+abstract class CCC2<T> extends DT<T> implements I<T> {
+}
+
+class a extends b<d, c> implements c<d, c<c,c>>, d<b<c<c,c>,d>> {}
+public class b<K,V> implements c<K, c<V,V>> { }
+interface c<K,V> extends d<b<V,K>> {}
+interface d<K> {}
+
+// extending final classes in bounds
+class C<T extends String> {
+ <E extends Integer> void f() {}
+}
+
+class GenericExtendItself<T, U extends T>
+{
+ GenericExtendItself<Object,Object> foo;
+}
+
+
+////////////////////
+public abstract class ZZZZ<E> {
+ public abstract E getElement();
+}
+abstract class Z<E> extends ZZZZ<E> {}
+class Z2 extends Z<Integer> {
+ public Integer getElement() {
+ return null;
+ }
+}
+/////////////////
+class BaseC <E> {
+ E remove(){
+ return null;
+ }
+}
+
+class DerivedC extends BaseC<String> {
+ public String remove() {
+ String s = super.remove();
+ return null;
+ }
+}
+
+/// raw in the multiple supers
+interface Int<T> {
+ AClass<T> f();
+}
+abstract class AClass<T> implements Int<T> {
+ public abstract AClass<T> f();
+}
+
+class MyClass extends AClass implements Int{
+ public AClass f() {
+ return null;
+ }
+}
+
+class A<T>{
+ A(){}
+ A(T t){}
+
+ {
+ new A<A>(new A()){};
+ }
+}
+
+//IDEADEV-4733: this overriding is OK
+class Outer<T>
+{
+ public class Inner
+ {
+ private final T t;
+
+ public Inner(T t) { this.t = t; }
+
+ public T getT() { return t; }
+
+ public String toString() { return t.toString(); }
+ }
+}
+
+class Other extends Outer<String>
+{
+ public class Ither extends Outer<String>.Inner
+ {
+ public Ither()
+ {
+ super("hello"); //valid super constructor call
+ }
+ }
+}
+
+//end of //IDEADEV-4733
+interface AI {
+}
+interface BI {
+}
+abstract class AbstractClass<T> {
+ AbstractClass(Class<T> clazz) {
+ }
+}
+class ConcreteClass extends AbstractClass<AI> {
+ ConcreteClass() {
+ super(AI.class);
+ }
+ class InnerClass extends AbstractClass<BI> {
+ InnerClass() {
+ super(BI.class); //
+ }
+ }
+}
+///////////////////////
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ConditionalExpression.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ConditionalExpression.java
new file mode 100644
index 0000000..88c1d57
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ConditionalExpression.java
@@ -0,0 +1,21 @@
+import java.util.TreeMap;
+import java.util.HashMap;
+import java.util.Map;
+
+class Test {
+ boolean f () {
+ return false;
+ }
+
+ Boolean g (int i) {
+ //This is OK thanks to boxing f()
+ return i > 0 ? f () : null;
+ }
+
+ {
+ Object values = new Object();
+ //IDEADEV-1756: this should be OK
+ final Map<Object,Object> newValues = true ? new TreeMap<Object,Object>() : new HashMap<Object,Object>();
+ newValues.get(values);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ContinueInferenceAfterFirstRawResult.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ContinueInferenceAfterFirstRawResult.java
new file mode 100644
index 0000000..eeab573
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ContinueInferenceAfterFirstRawResult.java
@@ -0,0 +1,23 @@
+import java.util.*;
+
+class Test {
+
+ List<String> getList(Function<Object, String> function) {
+ /*
+ * When the first argument below is a raw type it turns red because IDEA thinks the return
+ * type is Collection<>. javac and Eclipse don't care
+ */
+ return transform(new ArrayList(), new ArrayList<String>(), function);
+ }
+
+ <R, S, T extends Collection<S>> T transform(Iterable<? extends R> oldCollection, T newCollection, Function<R, S> function) {
+ for (R r : oldCollection) {
+ newCollection.add(function.apply(r));
+ }
+ return newCollection;
+ }
+
+ interface Function<X, Y> {
+ Y apply(X input);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ConvertibleTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ConvertibleTypes.java
new file mode 100644
index 0000000..572ef4a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ConvertibleTypes.java
@@ -0,0 +1,90 @@
+import java.util.Collection;
+import java.util.ArrayList;
+
+interface YO<<warning descr="Type parameter 'T' is never used">T</warning>> {}
+interface YO1 extends YO<String> {}
+interface YO2 extends YO<Integer> {}
+
+public class ConvertibleTest {
+
+ YO2 bar (YO1 s) {
+ return <error descr="Inconvertible types; cannot cast 'YO1' to 'YO2'">(YO2) s</error>;
+ }
+}
+
+
+//IDEA-1097
+interface Interface1 {}
+interface Interface2 {}
+
+class Implementation implements Interface1 {}
+
+public class InconvertibleTypesTest <E extends Interface2>
+{
+ E thing;
+
+ public E getThing() {
+ return thing;
+ }
+
+ Implementation foo(InconvertibleTypesTest<? extends Interface1> i2) {
+ //This is a valid cast from intersection type
+ return (Implementation) i2.getThing();
+ }
+}
+
+class MyCollection extends ArrayList<Integer> {}
+class Tester {
+ Collection<String> x(MyCollection l) {
+ return <error descr="Inconvertible types; cannot cast 'MyCollection' to 'java.util.Collection<java.lang.String>'">(Collection<String>) l</error>;
+ }
+}
+
+
+class IDEADEV3978 {
+ class Constructor<T> {
+ Class<T> getDeclaringClass() {
+ return null;
+ }
+ }
+ public static void foo(Constructor<?> constructor) {
+ if(constructor.getDeclaringClass() == String.class) { //captured wildcard is convertible
+ System.out.println("yep");
+ }
+ }
+}
+
+class C2<T> {
+ void f(T t) {
+ if (t instanceof Object[]) return;
+ }
+}
+
+class Casting {
+ void f(Object o)
+ {
+ if (o instanceof int[]) return;
+
+ Object obj1 = (Object)true; f(obj1);
+ Object ob = (Number)1; f(ob);
+ Object ob2 = (Object)1; f(ob2);
+
+ }
+
+ public static <T> T convert(Class<T> clazz, Object obj) {
+ if (obj == null) return null;
+ if (String[].class == clazz)
+ return <warning descr="Unchecked cast: 'java.lang.String[]' to 'T'">(T) parseArray(obj)</warning>;
+ return null;
+ }
+
+ private static String[] parseArray(Object obj) {
+ return obj.toString().split(",");
+ }
+}
+
+class CastPrimitiveToTypeParam<T> {
+ T foo() {
+ return <error descr="Inconvertible types; cannot cast 'int' to 'T'">(T)1</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DeepConflictingReturnTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DeepConflictingReturnTypes.java
new file mode 100644
index 0000000..0477aee
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DeepConflictingReturnTypes.java
@@ -0,0 +1,21 @@
+class W {
+ Object f() {
+ return 0;
+ }
+}
+
+class WW extends W {
+ String f() {
+ return null;
+ }
+}
+
+interface IQ {
+ void f();
+}
+
+
+<error descr="'f()' in 'WW' clashes with 'f()' in 'IQ'; attempting to use incompatible return type">class WWW extends WW implements IQ</error> {
+
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DifferentTypeParamsInOverloadedMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DifferentTypeParamsInOverloadedMethods.java
new file mode 100644
index 0000000..4feabc9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DifferentTypeParamsInOverloadedMethods.java
@@ -0,0 +1,28 @@
+import java.util.*;
+class Nav {
+ interface Sized {}
+ interface Stream<<warning descr="Type parameter 'T' is never used">T</warning>> { }
+
+ private static<U, T extends Sized & Iterable<U>> Stream<U> stream(T entity, int flags) {
+ System.out.println(entity);
+ System.out.println(flags);
+ return null;
+ }
+
+ private static<U, T extends Iterable<U>> Stream<U> <warning descr="Private method 'stream(T, int)' is never used">stream</warning>(T entity, int flags) {
+ System.out.println(entity);
+ System.out.println(flags);
+ return null;
+ }
+
+ static class A<T> implements Iterable<T>, Sized {
+ public Iterator<T> iterator() {
+ return null;
+ }
+ }
+
+ public static void main(String[] args) {
+ Stream<String> aStream = stream(new A<String>(), 0);
+ System.out.println(aStream);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DisableCastingToNestedWildcards.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DisableCastingToNestedWildcards.java
new file mode 100644
index 0000000..9c076ab
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DisableCastingToNestedWildcards.java
@@ -0,0 +1,32 @@
+import java.util.List;
+
+public class Test {
+
+ interface P {
+
+ }
+
+ public abstract class AP implements P {
+
+ }
+
+ public class AP1 extends AP {
+
+ }
+
+ public class AP2 extends AP {
+
+ }
+
+ private static final List<Class<AP1>> AP_LIST = listOf(AP1.class);
+
+
+ private static <T> List<T> listOf(T... ts) {
+ return null;
+ }
+
+ public static void test() {
+ List<Class<? extends AP>> apList1 = <error descr="Inconvertible types; cannot cast 'java.util.List<java.lang.Class<Test.AP1>>' to 'java.util.List<java.lang.Class<? extends Test.AP>>'">(List<Class<? extends AP>>) AP_LIST</error>;
+ List<Class<? super AP1>> apList2 = <error descr="Inconvertible types; cannot cast 'java.util.List<java.lang.Class<Test.AP1>>' to 'java.util.List<java.lang.Class<? super Test.AP1>>'">(List<Class<? super AP1>>) AP_LIST</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DisableWithinBoundsCheckForSuperWildcards.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DisableWithinBoundsCheckForSuperWildcards.java
new file mode 100644
index 0000000..703c377
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DisableWithinBoundsCheckForSuperWildcards.java
@@ -0,0 +1,15 @@
+import java.util.Comparator;
+
+public class Main2 {
+ static class OfRef<T> {
+ public OfRef() {
+ this((Comparator<? super T>) naturalOrder());
+ }
+
+ public OfRef(Comparator<? super T> comparator) {
+ }
+ static <K extends Comparable<? super K>> Comparator<K> naturalOrder() {
+ return null;
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DoNotAcceptLowerBoundIfRaw.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DoNotAcceptLowerBoundIfRaw.java
new file mode 100644
index 0000000..b132d74
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/DoNotAcceptLowerBoundIfRaw.java
@@ -0,0 +1,17 @@
+import java.util.*;
+
+class Test {
+ interface Condition<K> {}
+ class IOC<M> implements Condition {}
+
+ static <T> List<T> filter(T[] c, Condition<? super T> con) {
+ return null;
+ }
+
+ interface OE {}
+ interface LOE extends OE {}
+
+ void foo(OE[] es, IOC<LOE> con) {
+ List<LOE> l = filter(es, con);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Enum.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Enum.java
new file mode 100644
index 0000000..027ada4
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Enum.java
@@ -0,0 +1,205 @@
+enum Operation {
+ X;
+ static int s = 0;
+ public static final String constS = "";
+ Operation() {
+ int i = <error descr="It is illegal to access static member 's' from enum constructor or instance initializer">Operation.s</error>;
+ i = <error descr="It is illegal to access static member 's' from enum constructor or instance initializer">s</error>;
+ <error descr="It is illegal to access static member 's' from enum constructor or instance initializer">s</error> = 0;
+ final int x = Integer.MAX_VALUE;
+ String co = constS;
+ // TODO: unclear
+ //Operation o = X;
+ }
+ static {
+ int i = Operation.s;
+ i = s;
+ s = 0;
+ final int x = Integer.MAX_VALUE;
+ String co = constS;
+ // TODO: unclear
+ //Operation o = X;
+ }
+ {
+ int i = <error descr="It is illegal to access static member 's' from enum constructor or instance initializer">Operation.s</error>;
+ i = <error descr="It is illegal to access static member 's' from enum constructor or instance initializer">s</error>;
+ <error descr="It is illegal to access static member 's' from enum constructor or instance initializer">s</error> = 0;
+ final int x = Integer.MAX_VALUE;
+ String co = constS;
+ // TODO: unclear
+ //Operation o = X;
+
+ Operation ooo = <error descr="Enum types cannot be instantiated">new Operation()</error>;
+ }
+
+ <error descr="'values()' is already defined in 'Operation'">void values()</error> {}
+ void values(int i) {}
+ void valueOf() {}
+ <error descr="'valueOf(String)' is already defined in 'Operation'">void valueOf(String s)</error> {}
+}
+
+class exte extends <error descr="Cannot inherit from final 'Operation'">Operation</error> {
+}
+
+class use {
+ void f(Operation op) {
+ switch(op) {
+ case <error descr="An enum switch case label must be the unqualified name of an enumeration constant">Operation.X</error>: break;
+ }
+ switch(op) {
+ case X: break;
+ }
+ switch(op) {
+ case <error descr="Duplicate label 'X'">X</error>: break;
+ case <error descr="Duplicate label 'X'">X</error>: break;
+ }
+ }
+}
+
+enum pubCtr {
+ X(1);
+ <error descr="Modifier 'public' not allowed here">public</error> pubCtr(int i) {}
+}
+enum protCtr {
+ X(1);
+ <error descr="Modifier 'protected' not allowed here">protected</error> protCtr(int i) {}
+}
+<error descr="Modifier 'final' not allowed here">final</error> enum Fin { Y }
+<error descr="Modifier 'abstract' not allowed here">abstract</error> enum Abstr { }
+
+enum params<error descr="Enum may not have type parameters"><T></error> {
+}
+
+enum OurEnum {
+ A, B, C;
+
+ OurEnum() {
+ }
+
+ {
+ Enum<OurEnum> a = <error descr="It is illegal to access static member 'A' from enum constructor or instance initializer">A</error>;
+ OurEnum enumValue = <error descr="It is illegal to access static member 'B' from enum constructor or instance initializer">B</error>;
+ switch (enumValue) {
+ }
+
+ switch (enumValue) {
+ case A:
+ break;
+ }
+ }
+}
+
+enum TestEnum
+{
+ A(<error descr="Illegal forward reference">B</error>), B(A);
+ TestEnum(TestEnum other) {
+ <error descr="Call to super is not allowed in enum constructor">super(null, 0)</error>;
+ }
+}
+
+<error descr="Class 'abstr' must either be declared abstract or implement abstract method 'run()' in 'Runnable'">enum abstr implements Runnable</error> {
+}
+
+//this one is OK, enum constants are checked instead of enum itself
+enum abstr1 implements Runnable {
+ A {
+ public void run() {}
+ };
+}
+
+class X extends <error descr="Classes cannot directly extend 'java.lang.Enum'">Enum</error> {
+ public X(String name, int ordinal) {
+ super(name, ordinal);
+ }
+}
+
+enum StaticInEnumConstantInitializer {
+ AN {
+ <error descr="Inner classes cannot have static declarations"><error descr="Modifier 'static' not allowed here">static</error></error> class s { }
+ private <error descr="Inner classes cannot have static declarations">static</error> final String t = String.valueOf(1);
+ };
+}
+
+interface Barz {
+ void baz();
+}
+
+enum Fooz implements Barz {
+ <error descr="Class 'Fooz' must implement abstract method 'baz()' in 'Barz'">FOO</error>;
+}
+
+///////////////////////
+class sss {
+ void f() {
+ <error descr="Enum must not be local">enum EEEE</error> { EE, YY };
+ }
+}
+
+//////////////////////
+//This code is OK
+enum PowerOfTen {
+ ONE(1),TEN(10),
+ HUNDRED(100) {
+ public String toString() {
+ return Integer.toString(super.val);
+ }
+ };
+
+ private final int val;
+
+ PowerOfTen(int val) {
+ this.val = val;
+ }
+
+ public String toString() {
+ return name().toLowerCase();
+ }
+
+ public static void main(String[] args) {
+ System.out.println(ONE + " " + TEN + " " + HUNDRED);
+ }
+}
+
+//IDEADEV-8192
+enum MyEnum {
+ X1, X2;
+
+ private static MyEnum[] values = values();
+
+ public static void test() {
+
+ for (MyEnum e : values) { // values is colored red
+ e.toString();
+ }
+ }
+}
+//end of IDEADEV-8192
+
+class EnumBugIDEADEV15333 {
+ public enum Type { one, to }
+ Type type = Type.one;
+ public void main() {
+ switch(type){
+ case one:
+ Object one = new Object();
+ }
+ }
+}
+
+class NestedEnums {
+ enum E1 { }
+
+ class C2 {
+ <error descr="Inner classes cannot have static declarations">enum E2</error> { }
+ }
+
+ static class C3 {
+ enum E3 { }
+ }
+
+ {
+ new C3() {
+ <error descr="Inner classes cannot have static declarations">enum E2</error> { }
+ };
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Enum56239.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Enum56239.java
new file mode 100644
index 0000000..28e844a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Enum56239.java
@@ -0,0 +1,34 @@
+enum IDEA56239 {
+ A, B() {
+ {
+ System.out.println(<error descr="It is illegal to access static member 'A' from enum constructor or instance initializer">A</error>);
+ System.out.println(<error descr="It is illegal to access static member 'FOO' from enum constructor or instance initializer">FOO</error>);
+ System.out.println(FOO1);
+ System.out.println(<error descr="It is illegal to access static member 'C' from enum constructor or instance initializer">C</error>);
+ }
+ }, C(<error descr="Illegal forward reference">D</error>), D;
+
+ public static String FOO = "";
+ public static final String FOO1 = "";
+
+ IDEA56239() {
+ }
+
+ IDEA56239(IDEA56239 t) {
+ System.out.println(<error descr="It is illegal to access static member 'A' from enum constructor or instance initializer">A</error>);
+ System.out.println(<error descr="It is illegal to access static member 'FOO' from enum constructor or instance initializer">FOO</error>);
+ System.out.println(FOO1);
+ }
+
+ {
+ System.out.println(<error descr="It is illegal to access static member 'A' from enum constructor or instance initializer">A</error>);
+ System.out.println(<error descr="It is illegal to access static member 'FOO' from enum constructor or instance initializer">FOO</error>);
+ System.out.println(FOO1);
+ }
+
+ void foo() {
+ System.out.println(A);
+ System.out.println(FOO);
+ System.out.println(FOO1);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/EnumWithAbstractMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/EnumWithAbstractMethods.java
new file mode 100644
index 0000000..1abae6b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/EnumWithAbstractMethods.java
@@ -0,0 +1,24 @@
+<error descr="Modifier 'abstract' not allowed here">abstract</error> enum OurEnum {
+ <error descr="Class 'Anonymous class derived from OurEnum' must implement abstract method 'foo()' in 'OurEnum'">A</error> {
+ },
+ <error descr="'OurEnum' is abstract; cannot be instantiated">B</error>,
+ C {
+ void foo() {}
+ }
+ ;
+
+ abstract void foo();
+}
+
+enum xxx {
+ <error descr="'xxx' is abstract; cannot be instantiated">X</error>,
+ <error descr="Class 'Anonymous class derived from xxx' must implement abstract method 'f()' in 'xxx'">Y</error> {
+ };
+
+ abstract void f();
+}
+
+enum ok {
+ X { void f() {} };
+ abstract void f();
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ErasureTypeParameterBound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ErasureTypeParameterBound.java
new file mode 100644
index 0000000..ffa8897
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ErasureTypeParameterBound.java
@@ -0,0 +1,9 @@
+interface Foo<T> {
+ public <A extends T, B extends A> void bar(Class<A> key, B value);
+}
+
+class FooImpl implements Foo<String>{
+ public <A extends String, B extends A> void bar(Class<A> key, B value) {
+
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Exceptions.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Exceptions.java
new file mode 100644
index 0000000..039cfe6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Exceptions.java
@@ -0,0 +1,23 @@
+class C <T extends Exception> {
+ void foo () throws T {}
+ void bar () {
+ <error descr="Unhandled exception: T">foo ();</error>
+ }
+
+ <T extends Error> void goo() {
+ try {
+ int i = 12;
+ } catch (<error descr="Cannot catch type parameters">T</error> ex) {
+ }
+ }
+}
+
+//IDEADEV-4169: no problem here
+interface Blub {
+ public <E extends Throwable> void Switch() throws E;
+}
+
+class Blib implements Blub {
+ public <E extends Throwable> void Switch() throws E {
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ExplicitMethodParameters.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ExplicitMethodParameters.java
new file mode 100644
index 0000000..22c3b7e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ExplicitMethodParameters.java
@@ -0,0 +1,20 @@
+import java.util.*;
+
+class Foo {
+ <T> void foo() {}
+ <T1 extends List, T2> void foo1() {}
+ void bar() {}
+ <T> void xyz(T l) {}
+
+ {
+ foo();
+ this.<String>foo();
+ this.<error descr="Wrong number of type arguments: 2; required: 1"><String, Integer></error>foo();
+ this.<String>bar();
+ this.<String, Integer>bar();
+ this.<<error descr="Type parameter 'java.lang.String' is not within its bound; should implement 'java.util.List'">String</error>, Integer>foo1();
+ this.<String>xyz<error descr="'xyz(java.lang.String)' in 'Foo' cannot be applied to '(java.lang.Integer)'">(Integer.valueOf("27"))</error>;
+ ArrayList list = new <String>ArrayList<String>();
+ }
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FailedInferenceWithBoxing.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FailedInferenceWithBoxing.java
new file mode 100644
index 0000000..7e690fd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FailedInferenceWithBoxing.java
@@ -0,0 +1,12 @@
+class Test {
+ public <T> T doStuff() {
+ return null;
+ }
+ public boolean test() {
+ return doStuff();
+ }
+
+ public Boolean test1() {
+ return doStuff();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Fields.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Fields.java
new file mode 100644
index 0000000..4b9dffc
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Fields.java
@@ -0,0 +1,10 @@
+import java.util.*;
+
+class C {
+ static final List EMPTY = new ArrayList(0);
+
+ void m() {
+ List<String> list = C.<error descr="Reference parameters are not allowed here"><String></error>EMPTY;
+ System.out.println(list);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FixedFailedInferenceWithBoxing.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FixedFailedInferenceWithBoxing.java
new file mode 100644
index 0000000..7e690fd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FixedFailedInferenceWithBoxing.java
@@ -0,0 +1,12 @@
+class Test {
+ public <T> T doStuff() {
+ return null;
+ }
+ public boolean test() {
+ return doStuff();
+ }
+
+ public Boolean test1() {
+ return doStuff();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FlattenIntersectionType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FlattenIntersectionType.java
new file mode 100644
index 0000000..7fa937d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/FlattenIntersectionType.java
@@ -0,0 +1,16 @@
+interface BusinessEntity<E extends BusinessEntity<E>> {
+}
+
+interface EntityId<E extends BusinessEntity> {
+ E getEntity();
+}
+
+public class MyTest {
+ <T extends BusinessEntity<T>> T getEntity(EntityId<T> defaultValue) {
+ return getEntityID(defaultValue).getEntity();
+ }
+
+ public <P extends EntityId<?>> P getEntityID(P defaultValue) {
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ForeachTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ForeachTypes.java
new file mode 100644
index 0000000..bd06d92
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ForeachTypes.java
@@ -0,0 +1,29 @@
+class a {
+ void f(int[] c) {
+ for (int i:c) {}
+ for (<error descr="Incompatible types. Found: 'int', required: 'char'">char i:c</error>) {}
+ for (double i:c) {}
+ double[] db = null;
+ for (<error descr="Incompatible types. Found: 'double', required: 'int'">int i:db</error>) {}
+ for (double i:db) {}
+
+ java.util.List list = null;
+ for (<error descr="Incompatible types. Found: 'java.lang.Object', required: 'java.lang.String'">String i:list</error>) {}
+ for (Object o:list) {}
+
+ java.util.List<Integer> ct = null;
+ for (Number n:ct) {}
+ for (Object n:ct) {}
+ for (Integer n:ct) {}
+ for (<error descr="Incompatible types. Found: 'java.lang.Integer', required: 'java.lang.String'">String i:ct</error>) {}
+ for (<error descr="Incompatible types. Found: 'java.lang.Integer', required: 'java.util.List<java.lang.Integer>'">java.util.List<Integer> i:ct</error>) {}
+
+ Object o = null;
+ for (Object oi: (Iterable)o) {}
+
+
+ for (<error descr="Incompatible types. Found: 'double', required: 'int'">int i:db</error>) {
+ for (<error descr="Incompatible types. Found: 'java.lang.Object', required: 'int'">int p: list</error>) {}
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/GenericExtendException.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/GenericExtendException.java
new file mode 100644
index 0000000..b9c5d5a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/GenericExtendException.java
@@ -0,0 +1,4 @@
+class T extends Exception {}
+class E<T> extends <error descr="Generic class may not extend 'java.lang.Throwable'">Error</error> {}
+class M<T2 extends Exception> extends <error descr="Generic class may not extend 'java.lang.Throwable'">T</error> {}
+class Ex<X,Y> extends <error descr="Generic class may not extend 'java.lang.Throwable'">Throwable</error> {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/GenericsOverrideMethodInRawInheritor.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/GenericsOverrideMethodInRawInheritor.java
new file mode 100644
index 0000000..b0a6f18
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/GenericsOverrideMethodInRawInheritor.java
@@ -0,0 +1,9 @@
+import java.util.List;
+
+<error descr="'method(List<String>)' in 'Implementation' clashes with 'method(List<String>)' in 'IfcWithGenericMethod'; both methods have same erasure, yet neither overrides the other">class Implementation implements IfcWithGenericMethod</error> {
+ public void method(final List<String> strings) {}
+}
+
+interface IfcWithGenericMethod<T> {
+ void method(List<String> strings);
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA103760.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA103760.java
new file mode 100644
index 0000000..e4d05f0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA103760.java
@@ -0,0 +1,9 @@
+import java.util.*;
+public class MyList extends ArrayList {}
+
+public class Test {
+ public void test() {
+ List<? super List> list = new ArrayList<List>();
+ list.add(new MyList());
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104100.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104100.java
new file mode 100644
index 0000000..e854f4a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104100.java
@@ -0,0 +1,7 @@
+public class TestGenericMap<A extends Comparable<A>, B extends Comparable<B>>
+{
+ public TestGenericMap<B, A> inverse()
+ {
+ return new TestGenericMap<>();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104160.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104160.java
new file mode 100644
index 0000000..92e5b57
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104160.java
@@ -0,0 +1,13 @@
+import java.util.*;
+class Test<T> {
+ public static void foo(<error descr="'Test.this' cannot be referenced from a static context">T</error> t) {}
+ public void bar(T t) {}
+
+ static class A extends ArrayList<<error descr="'Test.this' cannot be referenced from a static context">T</error>> {
+ static void boo(<error descr="'Test.this' cannot be referenced from a static context">T</error> t){}
+ }
+
+ class B extends ArrayList<T> {
+ void foo(T r){}
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104992.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104992.java
new file mode 100644
index 0000000..5e46842
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA104992.java
@@ -0,0 +1,17 @@
+import java.util.Collection;
+import java.util.Set;
+
+class FooObject<T> {}
+class FooId<T extends FooObject> {}
+
+interface Bar {
+ <T extends FooObject, I extends FooId<? extends T>> T get(I key);
+ <T extends FooObject, I extends FooId<? extends T>> Collection<T> get(Collection<I> keys);
+}
+
+public class Target {
+ void foo(Bar bar) {
+ final Set<FooId<?>> keys = null;
+ final Collection<FooObject> values = bar.get(keys);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA105695.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA105695.java
new file mode 100644
index 0000000..8b1a962
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA105695.java
@@ -0,0 +1,10 @@
+import java.util.Map;
+
+public class Test {
+ void bar(Prop p) {
+ Map<? extends String, ? extends String> map = <error descr="Inconvertible types; cannot cast 'Prop' to 'java.util.Map<? extends java.lang.String,? extends java.lang.String>'">(Map<? extends String, ? extends String>)p</error>;
+ }
+}
+
+abstract class Hashtble<K,V> implements Map<K,V> {}
+abstract class Prop extends Hashtble<Object, Object>{}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA105846.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA105846.java
new file mode 100644
index 0000000..04d39bd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA105846.java
@@ -0,0 +1,6 @@
+class MyClass {
+ public static void main(Class<? extends MyClass> clazz){
+ clazz = (Class<? extends MyClass>) clazz.getSuperclass();
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<? super capture<? extends MyClass>>>', required: 'java.lang.Class<? extends MyClass>'">clazz = clazz.getSuperclass()</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA106964.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA106964.java
new file mode 100644
index 0000000..5745a60
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA106964.java
@@ -0,0 +1,12 @@
+import java.io.Serializable;
+
+public abstract class Test {
+
+ abstract <T> T test(Class<T> cls);
+
+ abstract <T> T test(Serializable type);
+
+ private void call(){
+ <error descr="Incompatible types. Found: 'java.lang.String[]', required: 'java.lang.String'">String s = test(String[].class);</error>
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107440.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107440.java
new file mode 100644
index 0000000..21073ff
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107440.java
@@ -0,0 +1,18 @@
+class GoodCodeRed {
+ static class ClassA {
+ }
+
+ static class Pair<T, N> {
+ }
+
+ <T extends ClassA, M extends T, N extends Number> void max(final M object, Pair<T, N> attribute, final N cnt) {
+ }
+
+ <T extends ClassA, M extends T, N extends String> void max(final M object, Pair<T, N> attribute, final N str) {
+ }
+
+
+ {
+ max(new ClassA(), new Pair<ClassA, Integer>(), 1);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107654.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107654.java
new file mode 100644
index 0000000..7af6110
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107654.java
@@ -0,0 +1,3 @@
+class X<A extends X<A>> {
+ static class Y<B extends Y> extends X<<error descr="Type parameter 'B' is not within its bound; should extend 'X<B>'">B</error>> {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107782.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107782.java
new file mode 100644
index 0000000..4beb3ff
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107782.java
@@ -0,0 +1,15 @@
+public class Test {
+ {
+ final MyResult hello = parseXML(new Parser());
+ }
+ public <R, P extends AbstractParser & Result<R>> R parseXML(P parser) {
+ R result = null;
+ return result;
+ }
+}
+class MyResult {}
+
+class AbstractParser {}
+interface Result<T> {}
+class Parser extends AbstractParser implements Result {}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107957.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107957.java
new file mode 100644
index 0000000..1228be1
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA107957.java
@@ -0,0 +1,37 @@
+class Test1 {
+
+ private static final Foo<Boolean> test = new Foo().method(Boolean.TRUE);
+
+ public static void main(String[] args) {
+ System.out.println(test);
+ }
+
+ public static class Foo<T> {
+ public Foo<Boolean> method(boolean arg) {
+ return null;
+ }
+
+ public <T extends Enum<T>> Foo<T> method(T arg) {
+ return null;
+ }
+ }
+}
+
+class Test2 {
+
+ private static final Foo<Boolean> test = Foo.method(Boolean.TRUE);
+
+ public static void main(String[] args) {
+ System.out.println(test);
+ }
+
+ public static class Foo<T> {
+ public static Foo<Boolean> method(boolean arg) {
+ return null;
+ }
+
+ public static <T extends Enum<T>> Foo<T> method(T arg) {
+ return null;
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA108287.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA108287.java
new file mode 100644
index 0000000..e717d2d2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA108287.java
@@ -0,0 +1,9 @@
+class Foo<T> {
+ static class Nested {};
+}
+class Bar extends Foo<<error descr="Nested is not accessible in current context">Bar.Nested</error>> {}
+
+interface FooI<T> {
+ interface Nested {};
+}
+interface BarI extends FooI<<error descr="Nested is not accessible in current context">BarI.Nested</error>> {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA109556.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA109556.java
new file mode 100644
index 0000000..4701229
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA109556.java
@@ -0,0 +1,9 @@
+class Base { }
+class Extended extends Base {}
+
+class Test<T extends Base> {
+ <T extends Base, U extends T> void test(T x, Class<U> test) {}
+ {
+ test(new Extended(), Base.class);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA109875.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA109875.java
new file mode 100644
index 0000000..d799ba2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA109875.java
@@ -0,0 +1,13 @@
+import java.util.Collections;
+import java.util.Set;
+
+public class Test<Y> {
+
+ public static <K> Test<K> doTest(K k){
+ return null;
+ }
+
+ public static void main(String[] args) {
+ Test.<Set<String>>doTest(Collections.emptySet());
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110568.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110568.java
new file mode 100644
index 0000000..ed9eedd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110568.java
@@ -0,0 +1,20 @@
+import java.util.Collection;
+
+public class IncorrectError extends NarrowClass {
+ public Collection<String> bar() {
+ return super.doStuff();
+ }
+}
+
+interface Interface {
+ Collection<String> doStuff();
+}
+
+class NarrowClass extends BaseClass implements Interface {
+}
+
+class BaseClass {
+ public Collection doStuff() {
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110869.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110869.java
new file mode 100644
index 0000000..acc0272
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110869.java
@@ -0,0 +1,12 @@
+class A {
+}
+
+abstract class B {
+ public <T extends A> T getA(Class<T> aClass) {
+ return null;
+ }
+
+ void foo(Class<?> aClass) {
+ A a = <error descr="Inferred type 'capture<?>' for type parameter 'T' is not within its bound; should extend 'A'">getA(aClass)</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110947.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110947.java
new file mode 100644
index 0000000..5f7ac80
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110947.java
@@ -0,0 +1,17 @@
+interface Result {}
+
+interface Command<R extends Result> {}
+
+interface Procedure<C extends Command<Result>> {
+}
+
+abstract class ProcedureService {
+ abstract <C extends Command<Result>> Class<? extends Procedure<Command<Result>>> getProcedure(Class<C> cmd);
+
+ public <C extends Command<Result>> void execute(Class<? extends Command> aClass) {
+ Class<Procedure<Command<Result>>> procedureClass = getProcedure(aClass);
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends Command>>', required: 'java.lang.Class<Command>'">Class<Command> c = aClass;</error>
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends Command>>', required: 'java.lang.Class<C>'">Class<C> c1 = aClass;</error>
+ }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA111085.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA111085.java
new file mode 100644
index 0000000..e67e0d3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA111085.java
@@ -0,0 +1,20 @@
+import java.io.*;
+import java.util.List;
+
+class Main {
+ public <T> T foo(String str, Class<T> classOfT) {
+ return null;
+ }
+
+ public <T> T foo(String str, Serializable typeOfT) {
+ return null;
+ }
+
+ {
+ asList(foo("", String[].class));
+ }
+
+ public static <T> List<T> asList(T... a) {
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA112122.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA112122.java
new file mode 100644
index 0000000..bb1e1ab
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA112122.java
@@ -0,0 +1,16 @@
+class Cast<T> implements SemElement {
+
+ {
+ final SemKey<? extends Cast> key = null;
+ final Cast semElement = getSemElement(key);
+ }
+
+ public <T extends SemElement> T getSemElement(SemKey<T> key) {
+ return null;
+ }
+
+
+ class SemKey<T extends SemElement> {}
+}
+
+interface SemElement {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA113225.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA113225.java
new file mode 100644
index 0000000..7b4bbab
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA113225.java
@@ -0,0 +1,11 @@
+import java.io.Serializable;
+
+public class Test {
+ public <T extends Serializable> void foo(byte[] data) {
+ T foo = (T) data;
+ }
+
+ public <T extends Serializable & Runnable> void bar(byte[] data) {
+ T bar = <error descr="Inconvertible types; cannot cast 'byte[]' to 'T'">(T) data</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA18425.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA18425.java
new file mode 100644
index 0000000..7a496b2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA18425.java
@@ -0,0 +1,15 @@
+public abstract class BiFunction<A,B> {
+ public abstract B apply(A a);
+ public abstract A unapply(B b);
+ public BiFunction<B,A> flip() {
+ return new BiFunction<B, A>() {
+ public A apply(B b) {
+ return BiFunction.this.unapply(b);
+ }
+
+ public B unapply(A a) {
+ return BiFunction.this.apply(a);
+ }
+ };
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA20244.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA20244.java
new file mode 100644
index 0000000..ee5235a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA20244.java
@@ -0,0 +1,23 @@
+import java.util.Collection;
+class Test {
+ public static final UnaryFunction<Object, Object, RuntimeException> unaryFunction = new UnaryFunction<Object, Object, RuntimeException>() {
+ public Object execute(Object o) throws RuntimeException {
+ return null;
+ }
+ };
+
+ public static <A, B, X extends Throwable> void someMethod() {
+ transformCollection(null, unaryFunction, null);
+ }
+
+ public static <A, B, X extends Throwable> void transformCollection(Collection<? extends A> input, UnaryFunction<A, B, X> transform, Collection<? super B> output) throws X {
+ for (A a : input) {
+ B b = transform.execute(a);
+ output.add(b);
+ }
+ }
+}
+
+interface UnaryFunction<A, B, X extends Throwable> {
+ public B execute(A a) throws X;
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA20573.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA20573.java
new file mode 100644
index 0000000..22bd7a3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA20573.java
@@ -0,0 +1,26 @@
+public class GoodCodeIsRed {
+
+ public void test() {
+ FileIF file = new FileImpl();
+ file.getInputStream();
+ }
+}
+
+class FileImpl implements FileIF {
+
+ public void getInputStream() {
+ }
+
+}
+
+interface FileIF extends BasicFileIF, DataSource {
+}
+
+interface BasicFileIF {
+ void getInputStream();
+}
+
+
+interface DataSource {
+ void getInputStream() throws java.io.IOException;
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21597.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21597.java
new file mode 100644
index 0000000..36899243
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21597.java
@@ -0,0 +1,7 @@
+interface Foo<A> {}
+interface Bar extends Foo<Boolean> {}
+class FooFactory {
+ public <A> Foo<A> getFoo() {
+ return (Foo<A>) new Bar() {};
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21602.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21602.java
new file mode 100644
index 0000000..217e1fd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21602.java
@@ -0,0 +1,17 @@
+import java.util.Collection;
+import java.util.Collections;
+
+public class IDEABug {
+
+ static class ClassA {
+ static <T> void sayHello(Collection<? extends T> msg) {}
+ }
+
+ static class ClassB extends ClassA {
+ <error descr="'sayHello(Collection<? extends T>)' in 'IDEABug.ClassB' clashes with 'sayHello(Collection<? extends T>)' in 'IDEABug.ClassA'; both methods have same erasure, yet neither hides the other">static <T extends String> void sayHello(Collection<? extends T> msg)</error> {}
+ }
+
+ public static void main(String[] args) {
+ ClassB.sayHello(Collections.<String>emptyList());
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21602_7.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21602_7.java
new file mode 100644
index 0000000..217e1fd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA21602_7.java
@@ -0,0 +1,17 @@
+import java.util.Collection;
+import java.util.Collections;
+
+public class IDEABug {
+
+ static class ClassA {
+ static <T> void sayHello(Collection<? extends T> msg) {}
+ }
+
+ static class ClassB extends ClassA {
+ <error descr="'sayHello(Collection<? extends T>)' in 'IDEABug.ClassB' clashes with 'sayHello(Collection<? extends T>)' in 'IDEABug.ClassA'; both methods have same erasure, yet neither hides the other">static <T extends String> void sayHello(Collection<? extends T> msg)</error> {}
+ }
+
+ public static void main(String[] args) {
+ ClassB.sayHello(Collections.<String>emptyList());
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA22005.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA22005.java
new file mode 100644
index 0000000..78aad3c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA22005.java
@@ -0,0 +1,13 @@
+class Test {
+ interface Foo<T> {
+ void boo(T t);
+ }
+
+ private static void f(Foo<?>... fs) {
+ fs[0].boo<error descr="'boo(capture<?>)' in 'Test.Foo' cannot be applied to '(java.lang.String)'">("hey!")</error>;
+ }
+
+ private static void f1(Foo<? extends String>... fs) {
+ fs[0].boo<error descr="'boo(capture<? extends java.lang.String>)' in 'Test.Foo' cannot be applied to '(java.lang.String)'">("hey!")</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA22079.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA22079.java
new file mode 100644
index 0000000..f3b25c9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA22079.java
@@ -0,0 +1,18 @@
+import java.util.List;
+
+public class SubClass extends BaseClass<String> {
+ public static void main(String[] args) {
+ new SubClass().method(null);
+ }
+
+ @Override
+ public void method(List list) {}
+}
+
+class BaseClass<E> implements EntityListListener<E> {
+ public void method(List list) {}
+}
+
+interface EntityListListener<E> {
+ public void method(List<E> list);
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA27080.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA27080.java
new file mode 100644
index 0000000..c5f2696
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA27080.java
@@ -0,0 +1,9 @@
+abstract class TypeToken<T> {
+ private <T> TypeToken<T> tt(Class<T> t) { return null; }
+ private <T> void checkedTestInexactSupertype(TypeToken<T> expectedSuperclass, TypeToken<? extends T> type) {}
+ TypeToken<? super Integer> ft = null;
+
+ {
+ checkedTestInexactSupertype(ft, tt(Integer.class));
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA27185.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA27185.java
new file mode 100644
index 0000000..73800a6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA27185.java
@@ -0,0 +1,13 @@
+import java.io.Serializable;
+interface A<T extends Serializable>
+{
+ <S extends T> S foo(S s);
+}
+class B implements A<Number>
+{
+ @Override
+ public <S extends Number> S foo(S s)
+ {
+ return s;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA55510.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA55510.java
new file mode 100644
index 0000000..f85901d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA55510.java
@@ -0,0 +1,22 @@
+abstract class IdeaBugTest<M extends IdeaBugTest.Mapping>
+{
+ static class Mapping {}
+}
+
+class BugTestSub extends IdeaBugTest<<error descr="SubMapping is not accessible in current context">BugTestSub.SubMapping</error>>
+{
+ public abstract static class SubMapping extends Mapping {}
+}
+
+class BugTestSub1 extends IdeaBugTest<BugTestSub1.SubMapping>
+{
+ public abstract static class SubMapping extends IdeaBugTest.Mapping {} //fqn here
+}
+
+class AbstractSettings {
+ interface State {}
+}
+interface SomeInterface<T> {}
+class Settings extends AbstractSettings implements SomeInterface<Settings.MyState> {
+ static class MyState implements State {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57259.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57259.java
new file mode 100644
index 0000000..10f9e870
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57259.java
@@ -0,0 +1,8 @@
+class A<T extends A.B> {
+ class B extends A<B> {}
+}
+
+class C<T> {
+ class D extends C<T> {}
+ <T extends C<String>.D> void foo(){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57264.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57264.java
new file mode 100644
index 0000000..485126b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57264.java
@@ -0,0 +1,17 @@
+class A1<T> {}
+class B1<T extends A1<? super A1<? super T>>>{
+ {
+ T a = null;
+ <error descr="Incompatible types. Found: 'T', required: 'A1<? super T>'">A1<? super T> b = a;</error>
+ }
+}
+
+class A<T> {}
+class B<T extends A<? super A<? super T>>> {
+
+ void bar(T x){
+ foo(x);
+ }
+ void foo(A<? super T> x){}
+ void foo(Object x){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57265.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57265.java
new file mode 100644
index 0000000..787606b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57265.java
@@ -0,0 +1,5 @@
+class A<T> {
+ class B<S> {
+ <error descr="Improper formed type; some type parameters are missing">A<T>.B</error> x;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57271.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57271.java
new file mode 100644
index 0000000..25b6c9c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57271.java
@@ -0,0 +1,9 @@
+abstract class A<S> {
+ abstract <T> T foo(T x, T y);
+
+ {
+ A<? extends A<? extends Throwable>> a = null;
+ A<? extends A<?>> b = null;
+ foo(a, b);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57272.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57272.java
new file mode 100644
index 0000000..343d667
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57272.java
@@ -0,0 +1,8 @@
+abstract class A<S> {
+ abstract <T extends A<? extends Throwable>> T foo(T y);
+
+ {
+ A<?> a = null;
+ <error descr="Inferred type 'A<capture<?>>' for type parameter 'T' is not within its bound; should extend 'A<? extends java.lang.Throwable>'">foo(a)</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57275.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57275.java
new file mode 100644
index 0000000..934d107
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57275.java
@@ -0,0 +1,13 @@
+abstract class A {
+ abstract <S, T extends Iterable<S>> void foo();
+
+ {
+ foo();
+ }
+}
+
+class X{
+ <T extends Enum<T>> void foo(){
+ foo();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57284.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57284.java
new file mode 100644
index 0000000..a9dc4c2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57284.java
@@ -0,0 +1,6 @@
+abstract class A<S> {
+ abstract <T extends S> void foo();
+ void bar(A<? super Exception> x){
+ x.<<error descr="Type parameter 'String[]' is not within its bound; should extend 'capture<? super java.lang.Exception>'">String[]</error>>foo();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57285.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57285.java
new file mode 100644
index 0000000..c420eb9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57285.java
@@ -0,0 +1,12 @@
+package pck;
+
+abstract class A<S> {
+ S y;
+ void bar(A<? extends int[]> x){
+ Object obj = <error descr="Array type expected; found: 'capture<? extends int[]>'">x.y</error>[0];
+ }
+
+ void baz(A<? super int[]> x){
+ Object obj = <error descr="Array type expected; found: 'capture<? super int[]>'">x.y</error>[0];
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57286.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57286.java
new file mode 100644
index 0000000..7378705
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57286.java
@@ -0,0 +1,6 @@
+class A<T> {
+ <S extends A<? extends T>> void foo(){}
+ void bar(A<?> a){
+ a.<<error descr="Type parameter 'A' is not within its bound; should extend 'A<capture<?>>'">A<?></error>>foo();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57289.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57289.java
new file mode 100644
index 0000000..eb64128
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57289.java
@@ -0,0 +1,8 @@
+class C<T> {
+ void foo(C<C<?>> x) {
+ C<Object> c = bar(x);
+ }
+ <T> C<T> bar(C<? super C<T>> x){
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57307.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57307.java
new file mode 100644
index 0000000..8f9ffe6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57307.java
@@ -0,0 +1,10 @@
+class C<<warning descr="Type parameter 'T' is never used">T</warning>>{}
+class A<<warning descr="Type parameter 'S' is never used">S</warning>,<warning descr="Type parameter 'T' is never used">T</warning>> {}
+class B<S,T extends C<S>> extends A<S,T> {
+ void foo(B<?,?> x){
+ bar(x);
+ }
+ <S, T> void bar(A<S,T> x){
+ System.out.println(x);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57308.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57308.java
new file mode 100644
index 0000000..154c143
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57308.java
@@ -0,0 +1,13 @@
+class A<T> {}
+
+interface IA{
+ <T> void foo(A<? extends T[]> x);
+}
+interface IB{
+ <T> int foo(A<? extends T> x);
+}
+class C {
+ <<error descr="'foo(A<? extends T>)' in 'IB' clashes with 'foo(A<? extends T[]>)' in 'IA'; both methods have same erasure, yet neither overrides the other"></error><error descr="'foo(A<? extends T>)' in 'IB' clashes with 'foo(A<? extends T[]>)' in 'IA'; both methods have same erasure, yet neither overrides the other"></error>T extends IA & IB> void bar(T x, A<String[]> y){
+ <error descr="Incompatible types. Found: 'void', required: 'int'">int z = x.foo(y);</error>
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57309.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57309.java
new file mode 100644
index 0000000..ffb4317
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57309.java
@@ -0,0 +1,9 @@
+class A<S> {
+ void bar(A<? super Exception> x, A<? super Throwable> y){
+ foo(x, y);
+ }
+
+ <T> T foo(A<? super T> x, A<? super T> y){
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57310.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57310.java
new file mode 100644
index 0000000..41a80a8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57310.java
@@ -0,0 +1,9 @@
+class A<T> {
+ Exception[] bar(A<? super Exception[]> x, A<? super Throwable[]> y){
+ return this.foo(x, y);
+ }
+
+ <T> T foo(A<? super T> x, A<? super T> y){
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57311.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57311.java
new file mode 100644
index 0000000..a566b5b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57311.java
@@ -0,0 +1,11 @@
+class A<T> {
+ A<A<? extends T>> foo(){
+ return null;
+ }
+
+ void bar(A<?> x){
+ baz<error descr="'baz(A<A<?>>)' in 'A' cannot be applied to '(A<A<capture<?>>>)'">(x.foo())</error>;
+ }
+
+ <S> void baz(A<A<? extends S>> x){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57312.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57312.java
new file mode 100644
index 0000000..b60c978
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57312.java
@@ -0,0 +1,11 @@
+class A<T> {
+ A<A<? super A<T>>> foo(){
+ return null;
+ }
+
+ void bar(A<?> x){
+ baz(x.foo());
+ }
+
+ <S> void baz(A<A<? super A<S>>> x){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57315.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57315.java
new file mode 100644
index 0000000..d855872
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57315.java
@@ -0,0 +1,4 @@
+class A<K>{
+ void foo(A<A<A<String>>> b){ bar(b); }
+ <U, S extends A<U>, T extends A<S>> void bar(A<T> a){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57325.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57325.java
new file mode 100644
index 0000000..b4933e8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57325.java
@@ -0,0 +1,12 @@
+interface IA<T> {
+ IA<? extends T> foo();
+}
+
+class A {
+ void baz(IA<? extends Throwable> x) {
+ bar(x.foo());
+ }
+
+ <T extends Throwable> void bar(IA<T> a) {
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57334.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57334.java
new file mode 100644
index 0000000..068f8d9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57334.java
@@ -0,0 +1,41 @@
+abstract class A<T, S> {
+ abstract <T> void foo(A<? extends T, ? extends T> x);
+ void bar(A<? extends Throwable, ? extends Exception> x){
+ foo(x);
+ }
+}
+
+abstract class A0<T, S> {
+ abstract <T> void foo(A0<? extends T, ? extends T> x);
+ void bar(A0<? extends Exception, ? extends Throwable> x){
+ foo(x);
+ }
+}
+
+abstract class A1<T, S> {
+ abstract <T> void foo(A1<? extends T, ? extends T> x);
+ void bar(A1<? extends Throwable, Exception> x){
+ foo(x);
+ }
+}
+
+abstract class A10<T, S> {
+ abstract <T> void foo(A10<? extends T, ? extends T> x);
+ void bar(A10<Throwable, Exception> x){
+ foo(x);
+ }
+}
+
+abstract class A2<T, S> {
+ abstract <T> void foo(A2<? super T, ? super T> x);
+ void bar(A2<? super Exception, ? super Throwable> x){
+ foo(x);
+ }
+}
+
+abstract class A20<T, S> {
+ abstract <T> void foo(A20<? super T, ? super T> x);
+ void bar(A20<? super Throwable, ? super Exception> x){
+ foo(x);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57339.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57339.java
new file mode 100644
index 0000000..01d694a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57339.java
@@ -0,0 +1,7 @@
+abstract class A {
+ abstract <T extends Iterable & Cloneable> void foo();
+}
+
+abstract class B extends A{
+ abstract <T extends Cloneable & Iterable> void foo();
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57340.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57340.java
new file mode 100644
index 0000000..7bbba7b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57340.java
@@ -0,0 +1,26 @@
+class A<T, S> {
+}
+
+class B<L> {
+ A<L, L> foo() {
+ return null;
+ }
+
+ void bar(B<?> b, A<?, ?> foo1) {
+ baz(b.foo());
+ A<?, ?> foo = b.foo();
+ baz<error descr="'baz(A<K,K>)' in 'B' cannot be applied to '(A<capture<?>,capture<?>>)'">(foo)</error>;
+ baz<error descr="'baz(A<K,K>)' in 'B' cannot be applied to '(A<capture<?>,capture<?>>)'">(foo1)</error>;
+ }
+
+ <K> void baz(A<K, K> a) {
+ }
+}
+
+
+
+class C<T,S>{}
+class D<T> extends C<T,T> {
+ void foo(D<?> x){ bar(x); }
+ <T> void bar(C<T,T> x){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57346.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57346.java
new file mode 100644
index 0000000..e4bfd47
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57346.java
@@ -0,0 +1,5 @@
+
+class D<T> {
+ void foo(D<D<?>> x){ this.bar(x); }
+ <T extends Throwable> void bar(D<? super D<T>> x){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57378.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57378.java
new file mode 100644
index 0000000..31e47fa
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57378.java
@@ -0,0 +1,9 @@
+interface IA {
+ <T extends Cloneable & Iterable> void foo(T x);
+ <T extends Iterable & Cloneable> void foo(T x);
+}
+
+abstract class A<T extends Throwable> {
+ abstract <T extends Comparable<?> & Iterable> void foo(T x, A<?> y);
+ abstract <T extends Iterable & Comparable<?>> void foo(T x, A<? extends Throwable> y);
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57391.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57391.java
new file mode 100644
index 0000000..dfc34f8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57391.java
@@ -0,0 +1,7 @@
+abstract class B<T> {
+ abstract <S extends T> void foo(T x, S y);
+}
+
+class A extends B<String> {
+ void foo(String x, String y) {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57410.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57410.java
new file mode 100644
index 0000000..19e90a3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57410.java
@@ -0,0 +1,10 @@
+
+interface IA {
+ <T> void a(Iterable<String> x);
+}
+
+interface IB {
+ <T> void a(Iterable x);
+}
+
+<error descr="'a(Iterable)' in 'IB' clashes with 'a(Iterable<String>)' in 'IA'; both methods have same erasure, yet neither overrides the other">abstract class C implements IA, IB</error> {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57411.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57411.java
new file mode 100644
index 0000000..89aea4a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57411.java
@@ -0,0 +1,18 @@
+class A<S> {
+ <T> T foo(T x, S y){
+ return x;
+ }
+}
+
+class B<S> extends A<S> {
+ Object foo(Object x, Object y){
+ return x;
+ }
+}
+
+<error descr="'foo(T, S)' in 'A' clashes with 'foo(Object, Object)' in 'B'; both methods have same erasure, yet neither overrides the other">class C extends B<String></error> {
+ @Override
+ <T> T foo(T x, String y) {
+ <error descr="Incompatible types. Found: 'java.lang.Object', required: 'T'">return super.foo(x, y);</error>
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57413.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57413.java
new file mode 100644
index 0000000..699a60d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57413.java
@@ -0,0 +1,7 @@
+class A<T> {
+ <T extends A<T>> void foo(T x){}
+
+ void bar(A<?> x){
+ foo<error descr="'foo(T)' in 'A' cannot be applied to '(A<capture<?>>)'">(x)</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57439.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57439.java
new file mode 100644
index 0000000..d0063b5
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57439.java
@@ -0,0 +1,43 @@
+class A<T> {}
+
+class B<T> extends A<A<T>> {
+ void bar(B<?> b, B<? extends String> eb, B<? super String> sb, B<String> s) {
+ foo(b);
+ foo(eb);
+ foo(sb);
+ foo(s);
+
+ <error descr="Inferred type 'capture<?>' for type parameter 'T' is not within its bound; should extend 'java.lang.String'">foo1(b)</error>;
+ foo1(eb);
+ <error descr="Inferred type 'capture<? super java.lang.String>' for type parameter 'T' is not within its bound; should extend 'java.lang.String'">foo1(sb)</error>;
+ foo1(s);
+
+ foo2(b);
+ foo2(eb);
+ foo2(sb);
+ foo2(s);
+
+ foo3<error descr="'foo3(A<A<?>>)' in 'B' cannot be applied to '(B<capture<?>>)'">(b)</error>;
+ foo3<error descr="'foo3(A<A<? extends java.lang.String>>)' in 'B' cannot be applied to '(B<capture<? extends java.lang.String>>)'">(eb)</error>;
+ foo3<error descr="'foo3(A<A<?>>)' in 'B' cannot be applied to '(B<capture<? super java.lang.String>>)'">(sb)</error>;
+ foo3<error descr="'foo3(A<A<? extends java.lang.String>>)' in 'B' cannot be applied to '(B<java.lang.String>)'">(s)</error>;
+
+ foo4<error descr="'foo4(A<A<? super T>>)' in 'B' cannot be applied to '(B<capture<?>>)'">(b)</error>;
+ foo4<error descr="'foo4(A<A<? super T>>)' in 'B' cannot be applied to '(B<capture<? extends java.lang.String>>)'">(eb)</error>;
+ foo4<error descr="'foo4(A<A<? super java.lang.String>>)' in 'B' cannot be applied to '(B<capture<? super java.lang.String>>)'">(sb)</error>;
+ foo4<error descr="'foo4(A<A<? super java.lang.String>>)' in 'B' cannot be applied to '(B<java.lang.String>)'">(s)</error>;
+
+ foo5(b);
+ foo5(eb);
+ foo5(sb);
+ foo5(s);
+ }
+
+
+ <T> void foo(A<A<T>> x) {}
+ <T extends String> void foo1(A<A<T>> x) {}
+ <T> void foo2(A<? extends A<T>> x) {}
+ <T> void foo3(A<A<? extends T>> x) {}
+ <T> void foo4(A<A<? super T>> x) {}
+ <T> void foo5(A<? super A<T>> x) {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57446.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57446.java
new file mode 100644
index 0000000..9cd9f2a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57446.java
@@ -0,0 +1,7 @@
+abstract class A<T>{
+ abstract void foo(T x);
+ class B extends A<B> {
+ @Override
+ void foo(A<T>.B x) {}
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57482.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57482.java
new file mode 100644
index 0000000..0f88cf3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57482.java
@@ -0,0 +1,9 @@
+class C<T>{
+ static class D{
+ class E{
+ <error descr="'C.this' cannot be referenced from a static context">T</error> x;
+ }
+ }
+}
+
+class T{}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57484.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57484.java
new file mode 100644
index 0000000..4e2aff7
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57484.java
@@ -0,0 +1,7 @@
+abstract class C{
+ abstract <T> T foo(T x, T y);
+
+ {
+ Long s = (Long) foo(1,1L);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57485.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57485.java
new file mode 100644
index 0000000..5ab00da
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57485.java
@@ -0,0 +1,9 @@
+abstract class A{
+ abstract <S extends Number & Comparable<?>, T extends Number & Comparable<? extends S>> T foo(
+ Comparable<? extends T> x,
+ Comparable<? extends T> y);
+
+ {
+ foo(1, 1L);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57486.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57486.java
new file mode 100644
index 0000000..a3c16dd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57486.java
@@ -0,0 +1,8 @@
+class B<T,S>{}
+abstract class A<T> {
+ abstract B<T,T> foo();
+ <T> void baz(B<T,T> b){}
+ void bar(A<?> a){
+ baz(a.foo());
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57492.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57492.java
new file mode 100644
index 0000000..62d8138
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57492.java
@@ -0,0 +1,17 @@
+abstract class A<T>{
+ abstract <S> S foo(S x, S y);
+ <S extends Number & Comparable<? extends Number>> void baz(A<S> a){}
+
+ void bar(A<Long> x, A<Integer> y){
+ baz<error descr="'baz(A<S>)' in 'A' cannot be applied to '(A<capture<? extends java.lang.Number & java.lang.Comparable<? extends java.lang.Comparable<?>>>>)'">(foo(x, y))</error>;
+ }
+}
+
+abstract class A1<T>{
+ abstract <S> S foo(S x, S y);
+ <T extends Number & Comparable<?>, S extends Number & Comparable<? extends T>> void baz(A1<S> a){}
+
+ void bar(A1<Long> x, A1<Integer> y){
+ baz<error descr="'baz(A1<S>)' in 'A1' cannot be applied to '(A1<capture<? extends java.lang.Number & java.lang.Comparable<? extends java.lang.Comparable<?>>>>)'">(foo(x, y))</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57493.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57493.java
new file mode 100644
index 0000000..f344fd8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57493.java
@@ -0,0 +1,8 @@
+abstract class A<T>{
+ abstract <S> S foo(S x, S y);
+ <S extends Number & Comparable<?>> void baz(A<S> a){}
+
+ void bar(A<Long> x, A<Integer> y){
+ baz<error descr="'baz(A<S>)' in 'A' cannot be applied to '(A<capture<? extends java.lang.Number & java.lang.Comparable<? extends java.lang.Comparable<?>>>>)'">(foo(x, y))</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57494.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57494.java
new file mode 100644
index 0000000..38bafca
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57494.java
@@ -0,0 +1,16 @@
+import java.util.*;
+abstract class A {
+ abstract <T> T baz(List<? super List<? super T>> a);
+
+ void bar(List<List<?>> x){
+ String s = baz(x);
+ }
+}
+
+abstract class A1{
+ abstract <T> T baz(List<? super T> a);
+
+ void bar(List<?> x){
+ String o = baz<error descr="'baz(java.util.List<? super T>)' in 'A1' cannot be applied to '(java.util.List<capture<?>>)'">(x)</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57495.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57495.java
new file mode 100644
index 0000000..63f8c91
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57495.java
@@ -0,0 +1,9 @@
+import java.util.*;
+interface C<T> extends List<List<T>>{}
+abstract class A {
+ abstract <T> T baz(List<? super List<? super T>> a);
+
+ void bar(C<?> x){
+ baz<error descr="'baz(java.util.List<? super java.util.List<? super T>>)' in 'A' cannot be applied to '(C<capture<?>>)'">(x)</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57496.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57496.java
new file mode 100644
index 0000000..e33bb53
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57496.java
@@ -0,0 +1,11 @@
+interface I<T>{}
+interface A extends I<A[]>{}
+interface B extends I<B[]>{}
+
+abstract class c{
+ abstract <T> T baz(T x, T y);
+
+ void bar(A x, B y){
+ baz(x, y);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57509.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57509.java
new file mode 100644
index 0000000..5925159
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57509.java
@@ -0,0 +1,9 @@
+import java.util.List;
+
+abstract class X {
+ abstract <T> void copy(List<T> dest, List<? extends T> src);
+
+ void foo(List<? super Throwable> x, List<? extends Exception> y){
+ copy(x, y);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57533.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57533.java
new file mode 100644
index 0000000..5d1507f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57533.java
@@ -0,0 +1,6 @@
+class C<T extends C<? extends C<? extends T>>>{
+ void foo(C<?> x){
+ bar<error descr="'bar(C<T>)' in 'C' cannot be applied to '(C<capture<?>>)'">(x)</error>;
+ }
+ <T extends C<? extends T>> void bar(C<T> x){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57534.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57534.java
new file mode 100644
index 0000000..ea3e242
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57534.java
@@ -0,0 +1,15 @@
+abstract class C{
+ abstract <T extends Cloneable> void foo(T x);
+ abstract <T extends Object & Cloneable> void foo(T x);
+ void bar(Cloneable x){
+ foo<error descr="Ambiguous method call: both 'C.foo(Cloneable)' and 'C.foo(Cloneable)' match">(x)</error>;
+ }
+}
+
+abstract class D {
+ abstract <T extends Iterable<? extends Exception>> void foo(T x);
+ abstract <T extends Object & Iterable<? super Exception>> void foo(T x);
+ void bar(Iterable<Exception> x){
+ foo<error descr="Ambiguous method call: both 'D.foo(Iterable<Exception>)' and 'D.foo(Iterable<Exception>)' match">(x)</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57539.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57539.java
new file mode 100644
index 0000000..1969294
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57539.java
@@ -0,0 +1,13 @@
+class E<T> {
+ Class<T[]> o = <error descr="Cannot select from a type variable">T[]</error>.class;
+}
+
+class MyClass<T> {
+ Class<T[]> getTs() {
+ return <error descr="Cannot select from a type variable">T[]</error>.class;
+ }
+
+ public static void main(String[] args) {
+ new MyClass<String>().getTs();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57557.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57557.java
new file mode 100644
index 0000000..8f482f9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57557.java
@@ -0,0 +1,7 @@
+abstract class A {
+ abstract void foo(Enum<?> x);
+}
+
+class B extends A {
+ void foo(Enum<? extends Enum<?>> x) { }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57563.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57563.java
new file mode 100644
index 0000000..1837362
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57563.java
@@ -0,0 +1,7 @@
+class C {
+ void foo(){}
+}
+
+class D extends C{
+ <error descr="'foo()' in 'D' clashes with 'foo()' in 'C'; both methods have same erasure, yet neither hides the other">static <T> void foo()</error>{}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57650.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57650.java
new file mode 100644
index 0000000..cfbc413
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57650.java
@@ -0,0 +1,7 @@
+abstract class A {
+ abstract <T> T foo();
+
+ {
+ int x = foo();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57667.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57667.java
new file mode 100644
index 0000000..d56af09
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57667.java
@@ -0,0 +1,7 @@
+class A {
+ <T> A(T x) {}
+
+ {
+ new <<error descr="Actual type argument and inferred type contradict each other">String</error>>A(1);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57668.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57668.java
new file mode 100644
index 0000000..65efaee
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57668.java
@@ -0,0 +1,17 @@
+class A {
+ <T> A() {}
+
+ {
+ new <<error descr="Type argument cannot be of primitive type">int</error>>A();
+ }
+}
+
+class B<T> {
+ {
+ new B<<error descr="Type argument cannot be of primitive type">int</error>>();
+ B.<<error descr="Type argument cannot be of primitive type">int</error>>m();
+ }
+
+ <S> void m(){}
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57877.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57877.java
new file mode 100644
index 0000000..87c94303
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57877.java
@@ -0,0 +1,8 @@
+import java.util.*;
+
+class Test {
+ {
+ Object obj = new Object();
+ Set<Class<?>> types = Collections.singleton(obj.getClass());
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA63291.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA63291.java
new file mode 100644
index 0000000..077eb2d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA63291.java
@@ -0,0 +1,57 @@
+import java.util.Comparator;
+import java.util.Set;
+
+public class CastError {
+ public void foo(Comparator<? super byte[]> comparator) throws Exception {
+ MyComparator comparator1 = (MyComparator) comparator;
+ }
+
+ public void foo1(Comparator<byte[]> comparator) throws Exception {
+ MyComparator comparator1 = (MyComparator) comparator;
+ }
+
+ public void foo2(Comparator<? extends byte[]> comparator) throws Exception {
+ MyComparator comparator1 = (MyComparator) comparator;
+ }
+
+ public void foo3(Comparator<? super String[]> comparator) throws Exception {
+ MyComparator comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Comparator<capture<? super java.lang.String[]>>' to 'MyComparator'">(MyComparator) comparator</error>;
+ }
+
+ public void foo4(Comparator<? extends String[]> comparator) throws Exception {
+ MyComparator comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Comparator<capture<? extends java.lang.String[]>>' to 'MyComparator'">(MyComparator) comparator</error>;
+ }
+
+ public void foo5(Comparator<?> comparator) throws Exception {
+ MyComparator comparator1 = (MyComparator) comparator;
+ }
+
+ //--||--||--||--||--||--||--||--||--||--||--||--||--||--||--||--||--||--||--
+
+ public void sfoo(Set<Comparator<? super byte[]>> comparator) throws Exception {
+ Set<MyComparator> comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Set<java.util.Comparator<? super byte[]>>' to 'java.util.Set<MyComparator>'">(Set<MyComparator>) comparator</error>;
+ }
+
+ public void sfoo1(Set<Comparator<byte[]>> comparator) throws Exception {
+ Set<MyComparator> comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Set<java.util.Comparator<byte[]>>' to 'java.util.Set<MyComparator>'">(Set<MyComparator>) comparator</error>;
+ }
+
+ public void sfoo2(Set<Comparator<? extends byte[]>> comparator) throws Exception {
+ Set<MyComparator> comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Set<java.util.Comparator<? extends byte[]>>' to 'java.util.Set<MyComparator>'">(Set<MyComparator>) comparator</error>;
+ }
+
+ public void sfoo3(Set<Comparator<? super String[]>> comparator) throws Exception {
+ Set<MyComparator> comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Set<java.util.Comparator<? super java.lang.String[]>>' to 'java.util.Set<MyComparator>'">(Set<MyComparator>) comparator</error>;
+ }
+
+ public void sfoo4(Set<Comparator<? extends String[]>> comparator) throws Exception {
+ Set<MyComparator> comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Set<java.util.Comparator<? extends java.lang.String[]>>' to 'java.util.Set<MyComparator>'">(Set<MyComparator>) comparator</error>;
+ }
+
+ public void sfoo5(Set<Comparator<?>> comparator) throws Exception {
+ Set<MyComparator> comparator1 = <error descr="Inconvertible types; cannot cast 'java.util.Set<java.util.Comparator<?>>' to 'java.util.Set<MyComparator>'">(Set<MyComparator>) comparator</error>;
+ }
+}
+
+abstract class MyComparator implements Comparator<byte[]> {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA65066.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA65066.java
new file mode 100644
index 0000000..3078f60
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA65066.java
@@ -0,0 +1,19 @@
+import java.util.List;
+
+class Generics {
+ public static void main( String[] args ) {
+ Outer<? extends List<? extends Nested<?>>, ?> var = OuterImpl.create(); //marked red
+ }
+
+ private static interface Outer<I, O> {
+ }
+
+ private static class OuterImpl<T> implements Outer<T, T> {
+ public static <T> OuterImpl<T> create() {
+ return new OuterImpl<T>();
+ }
+ }
+
+ private static class Nested<T> {
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA66311.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA66311.java
new file mode 100644
index 0000000..659d8fa
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA66311.java
@@ -0,0 +1,21 @@
+import java.util.*;
+
+class ErasureTest {
+ <error descr="'toArrayDouble(List<? extends Number>)' clashes with 'toArrayDouble(List<double[]>)'; both methods have same erasure">public static double[] toArrayDouble(List<? extends Number> v)</error> {
+ return null;
+ }
+
+ public static double[][] toArrayDouble(List<double[]> v) {
+ return null;
+ }
+}
+
+class ErasureTest1 {
+ <error descr="'toArrayDouble(List<? extends Number>)' clashes with 'toArrayDouble(List)'; both methods have same erasure">public static double[] toArrayDouble(List<? extends Number> v)</error> {
+ return null;
+ }
+
+ public static double[][] toArrayDouble(List v) {
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA66311_16.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA66311_16.java
new file mode 100644
index 0000000..f95898a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA66311_16.java
@@ -0,0 +1,31 @@
+import java.util.*;
+
+class ErasureTest {
+ <error descr="'toArrayDouble(List<? extends Number>)' clashes with 'toArrayDouble(List<double[]>)'; both methods have same erasure">public static double[] toArrayDouble(List<? extends Number> v)</error> {
+ return null;
+ }
+
+ public static double[][] toArrayDouble(List<double[]> v) {
+ return null;
+ }
+}
+
+class ErasureTest1 {
+ <error descr="'toArrayDouble(List<? extends Number>)' clashes with 'toArrayDouble(List)'; both methods have same erasure">public static double[] toArrayDouble(List<? extends Number> v)</error> {
+ return null;
+ }
+
+ public static double[][] toArrayDouble(List v) {
+ return null;
+ }
+}
+
+class ErasureTest2 {
+ <error descr="'toArrayDouble(List<? extends Number>)' clashes with 'toArrayDouble(List<String>)'; both methods have same erasure">public static double[] toArrayDouble(List<? extends Number> v)</error> {
+ return null;
+ }
+
+ public static double[] toArrayDouble(List<String> v) {
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67570.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67570.java
new file mode 100644
index 0000000..98e7c6b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67570.java
@@ -0,0 +1,21 @@
+interface A1
+{
+ String foo();
+}
+
+interface B1
+{
+ Object foo();
+}
+
+class C1<T extends B1 & A1> {
+ void bar(T x) {
+ String foo = x.foo();
+ }
+}
+
+class C2<T extends A1 & B1> {
+ void bar(T x) {
+ String foo = x.foo();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67571.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67571.java
new file mode 100644
index 0000000..b0cd45c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67571.java
@@ -0,0 +1,17 @@
+interface A
+{
+ abstract <T> void foo();
+}
+
+interface B
+{
+ abstract <T,S> void foo();
+}
+
+class C<<error descr="'foo()' in 'B' clashes with 'foo()' in 'A'; both methods have same erasure, yet neither overrides the other"></error>T extends A & B>
+{
+ void bar(T x)
+ {
+ x.foo<error descr="Ambiguous method call: both 'A.foo()' and 'B.foo()' match">()</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67577.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67577.java
new file mode 100644
index 0000000..ff1a04f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67577.java
@@ -0,0 +1,7 @@
+class X<T>{}
+
+class A<T,S extends X<T>> {}
+
+class C {
+ void foo(A<?, <error descr="Type parameter 'X' is not within its bound; should extend 'X<?>'">X</error>> a){ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67584.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67584.java
new file mode 100644
index 0000000..e5c5b45
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67584.java
@@ -0,0 +1,11 @@
+abstract class A
+{
+ abstract void foo();
+}
+
+interface B
+{
+ abstract void foo();
+}
+
+abstract class C extends A implements B { }
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67597.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67597.java
new file mode 100644
index 0000000..26240ad
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67597.java
@@ -0,0 +1,4 @@
+class A<T>
+{
+ T x = <error descr="Inconvertible types; cannot cast 'int' to 'T'">(T) 1</error>;
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67599.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67599.java
new file mode 100644
index 0000000..67d49ac
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67599.java
@@ -0,0 +1,8 @@
+abstract class A<T, S extends T>
+{
+ abstract S bar();
+ void foo(A<Cloneable[], ? extends Throwable[]> a)
+ {
+ int x = a.bar().length;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67667.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67667.java
new file mode 100644
index 0000000..35e4ed2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67667.java
@@ -0,0 +1,8 @@
+import java.util.Collection;
+import java.util.List;
+
+interface A
+{
+ <S extends Cloneable & Comparable<?>> void foo(S x);
+ <S extends Comparable<?> & Cloneable> void foo(S x);
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67672.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67672.java
new file mode 100644
index 0000000..918e550
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67672.java
@@ -0,0 +1,7 @@
+import java.util.Collection;
+import java.util.List;
+
+interface A
+{
+ <<error descr="'add(E)' in 'java.util.List' clashes with 'add(E)' in 'java.util.Collection'; both methods have same erasure, yet neither overrides the other"></error><error descr="'add(E)' in 'java.util.List' clashes with 'add(E)' in 'java.util.Collection'; both methods have same erasure, yet neither overrides the other"></error>T extends List<?> & Collection<? extends Cloneable>> void foo(T x);
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67677.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67677.java
new file mode 100644
index 0000000..7f206bb
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67677.java
@@ -0,0 +1,11 @@
+import java.util.List;
+
+interface B<T extends Cloneable> {
+ void foo(List<? super T> x);
+}
+
+class D {
+ void bar(B<?> x, List<?> y) {
+ x.foo<error descr="'foo(java.util.List<? super capture<? extends java.lang.Cloneable>>)' in 'B' cannot be applied to '(java.util.List<capture<?>>)'">(y)</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67681.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67681.java
new file mode 100644
index 0000000..b5abcb6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67681.java
@@ -0,0 +1,33 @@
+
+interface A<T> { }
+
+class B<T> implements A<T> {}
+
+class C {
+ void bar(A<A<?>> x){
+ B<A<String>> y = <error descr="Inconvertible types; cannot cast 'A<A<?>>' to 'B<A<java.lang.String>>'">(B<A<String>>) x</error>;
+ }
+}
+
+//-----------------------
+interface A2<T> { }
+
+class B2<T> implements A2<T> {}
+
+class C2 {
+ void bar(A2<A2> x){
+ B2<A2<?>> y = <error descr="Inconvertible types; cannot cast 'A2<A2>' to 'B2<A2<?>>'">(B2<A2<?>>) x</error>;
+ }
+}
+
+//-----------------------
+interface A3<T> { }
+
+class B3<T> implements A3<T> {}
+
+class C3 {
+ <T> void bar(A3<A3<T>> x){
+ A3<A3<?>> y = <error descr="Inconvertible types; cannot cast 'A3<A3<T>>' to 'A3<A3<?>>'">(A3<A3<?>>) x</error>;
+
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67682.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67682.java
new file mode 100644
index 0000000..4a48242
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67682.java
@@ -0,0 +1,15 @@
+import java.util.List;
+
+abstract class B {
+ <T> void foo(List<List<String>[]> x) {
+ Object y1 = <error descr="Inconvertible types; cannot cast 'java.util.List<java.util.List<java.lang.String>[]>' to 'java.util.List<java.util.List<T>[]>'">(List<List<T>[]>)x</error>;
+ }
+
+ <T> void foo1(List<List<List<String>>[]> x) {
+ Object y1 = <error descr="Inconvertible types; cannot cast 'java.util.List<java.util.List<java.util.List<java.lang.String>>[]>' to 'java.util.List<java.util.List<java.util.List<T>>[]>'">(List<List<List<T>>[]>)x</error>;
+ }
+
+ <T> void foo2(List<String[]> x) {
+ Object y1 = <error descr="Inconvertible types; cannot cast 'java.util.List<java.lang.String[]>' to 'java.util.List<T[]>'">(List<T[]>)x</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67744.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67744.java
new file mode 100644
index 0000000..9914b1f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67744.java
@@ -0,0 +1,16 @@
+import java.util.List;
+
+abstract class B {
+ abstract <T> T[] foo(List<? super List<T>> x);
+ abstract <T> T foo0(List<? super List<T>> x);
+ abstract <T> T[] foo1(List<? extends List<T>> x);
+ abstract <T> T[] foo2(List<List<? super List<T>>> x);
+
+ void bar(List<List<?>> x, List<List<List<?>>> y){
+ foo(x) [0] = "";
+ foo1<error descr="'foo1(java.util.List<? extends java.util.List<T>>)' in 'B' cannot be applied to '(java.util.List<java.util.List<?>>)'">(x)</error> [0] = "";
+ foo2<error descr="'foo2(java.util.List<java.util.List<? super java.util.List<java.lang.Object>>>)' in 'B' cannot be applied to '(java.util.List<java.util.List<java.util.List<?>>>)'">(y)</error> [0] = "";
+
+ String s = foo0(x);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67798.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67798.java
new file mode 100644
index 0000000..fb420fb
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67798.java
@@ -0,0 +1,6 @@
+class A<T> {
+ {
+ class T extends A<T> {}
+ }
+ class T extends A<T> {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67835.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67835.java
new file mode 100644
index 0000000..ce887c6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67835.java
@@ -0,0 +1,10 @@
+import java.util.List;
+
+class B {
+ void bar(List<String> x){
+ foo(x);
+ }
+ <T> T foo(List<? super T> x){
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67843.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67843.java
new file mode 100644
index 0000000..c459ab3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67843.java
@@ -0,0 +1,10 @@
+import java.util.List;
+
+class B{
+ public static void bar(){
+ <error descr="Inferred type 'java.util.List<java.lang.Comparable>' for type parameter 'T' is not within its bound; should implement 'java.util.List<java.lang.Comparable<java.util.List<java.lang.Comparable>>>'">foo(null)</error>.get(0).compareTo(null);
+ }
+ static <T extends List<Comparable<T>>> T foo(T x) {
+ return x;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67861.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67861.java
new file mode 100644
index 0000000..1feb516
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67861.java
@@ -0,0 +1,8 @@
+abstract class C {
+ <T> void foo(Object s){ }
+ abstract String foo(String s);
+
+ {
+ this.<String>foo("").toLowerCase();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67865.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67865.java
new file mode 100644
index 0000000..ab7d8cf
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67865.java
@@ -0,0 +1,11 @@
+import java.util.*;
+
+abstract class A {
+ static <T> void foo(List<T> x) { }
+ static <T extends List<?>> void foo(Collection<T> x) { }
+ public static void main(String[] args){
+ List<List<String>> x = null;
+ foo<error descr="Ambiguous method call: both 'A.foo(List<List<String>>)' and 'A.foo(Collection<List<String>>)' match">(x)</error>;
+ foo<error descr="Ambiguous method call: both 'A.foo(List<Object>)' and 'A.foo(Collection<List<?>>)' match">(null)</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67998.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67998.java
new file mode 100644
index 0000000..4db4fe0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA67998.java
@@ -0,0 +1,22 @@
+class TestClass {
+ public final class TestMapper<X> {
+
+ public <U, T extends Mapping<X, U>> T mapType() {
+ SimpleMapping<X, U> mapping = new SimpleMapping<X, U>();
+ return (T) mapping; //This is reports "Inconvertible types; cannot cast TestClass.SimpleMapping<X,U> to 'T'"
+ }
+ }
+ private final class SimpleMapping<X, U> implements Mapping<X, U> {}
+ public interface Mapping<F, U> {}
+}
+class TestClass1 {
+ public final class TestMapper<X> {
+
+ public <U, T extends Mapping<X, U>> T mapType() {
+ Mapping<X, U> mapping = new SimpleMapping<X, U>(); //Changed type to interface
+ return (T) mapping;
+ }
+ }
+ private final class SimpleMapping<X, U> implements Mapping<X, U> {}
+ public interface Mapping<F, U> {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA70370.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA70370.java
new file mode 100644
index 0000000..a1c9331
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA70370.java
@@ -0,0 +1,13 @@
+class Devk1 {
+ public void main(String args[]) {
+ foo();
+ }
+
+ private void <warning descr="Private method 'foo(java.lang.Object...)' is never used">foo</warning>(Object... objects) {
+ System.out.println("OBJECTS" + objects);
+ }
+
+ private void foo(int... ints) {
+ System.out.println("INTS" + ints);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA72912.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA72912.java
new file mode 100644
index 0000000..c57bbb5
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA72912.java
@@ -0,0 +1,16 @@
+import java.util.*;
+
+public class Test<T>
+{
+ List<Collection<T>> getList ()
+ {
+ return new ArrayList<Collection<T>> ();
+ }
+
+ public void test1 (Test<T> arg)
+ {
+ List<Collection<T>> result = arg.getList ();
+ result.add <error descr="'add(java.util.Collection<T>)' in 'java.util.List' cannot be applied to '(java.util.HashMap<java.lang.Integer,java.lang.Integer>)'">(new HashMap<Integer, Integer> ())</error>;
+ }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA74899.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA74899.java
new file mode 100644
index 0000000..8723829
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA74899.java
@@ -0,0 +1,11 @@
+import java.util.Collections;
+import java.util.Map;
+
+public class IDEA74899 {
+ void foo() {
+ Map<String, String> m = Collections.emptyMap();
+ if (<error descr="Operator '==' cannot be applied to 'java.util.Map<java.lang.String,java.lang.String>', 'java.util.Map<java.lang.Object,java.lang.Object>'">m == Collections.emptyMap()</error>) {
+ return;
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA76283.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA76283.java
new file mode 100644
index 0000000..a221d1b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA76283.java
@@ -0,0 +1,49 @@
+import java.util.*;
+public class IDEA76283 {
+}
+
+interface Parametrized<T extends Number> {
+}
+
+class Bug1<T extends Number> {
+ <I extends Number> Parametrized<I> foo(Parametrized<I> param) {
+ return null;
+ }
+
+ void bug1(Parametrized<? super T> param) {
+ foo(param);
+ }
+
+ void bug2(Set<Parametrized<? extends Number>> parametrizeds) {
+ Set<Parametrized<?>> items = parametrizeds;
+ }
+
+ void bug3(Set<Parametrized<?>> parametrizeds) {
+ Set<Parametrized<?>> items = parametrizeds;
+ }
+
+ void bug4(Set<Parametrized<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>>> parametrizeds) {
+ <error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? extends java.lang.String>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
+ }
+
+ void bug5(Set<Parametrized<? extends Integer>> parametrizeds) {
+ <error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? extends java.lang.Integer>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
+ }
+
+ void bug6(Set<Parametrized<? super Number>> parametrizeds) {
+ <error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? super java.lang.Number>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
+ }
+
+ void bug7(Set<Parametrized<? super Integer>> parametrizeds) {
+ <error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? super java.lang.Integer>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
+ }
+
+ void bug8(Set<Parametrized<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>>> parametrizeds) {
+ <error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? super java.lang.String>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
+ }
+
+ void bug9(Set<Parametrized<<error descr="Type parameter '? super Object' is not within its bound; should extend 'java.lang.Number'">? super Object</error>>> parametrizeds) {
+ <error descr="Incompatible types. Found: 'java.util.Set<Parametrized<? super java.lang.Object>>', required: 'java.util.Set<Parametrized<?>>'">Set<Parametrized<?>> items = parametrizeds;</error>
+ }
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA77128.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA77128.java
new file mode 100644
index 0000000..cc889ab
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA77128.java
@@ -0,0 +1,11 @@
+import java.util.*;
+class A {
+ public static void main(String[] args) {
+ List<String> strings = new ArrayList<>();
+
+ List<? super Integer> list = new ArrayList<>();
+ list.addAll<error descr="'addAll(java.util.Collection<? extends capture<? super java.lang.Integer>>)' in 'java.util.List' cannot be applied to '(java.util.List<java.lang.String>)'">(strings)</error>;
+
+ System.out.println(list.toString());
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA77991.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA77991.java
new file mode 100644
index 0000000..688806bc
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA77991.java
@@ -0,0 +1,26 @@
+class Test {
+ static {
+ Class<Test> testClass = get(Test.class);
+ foo(testClass);
+ Test f = foo(testClass);
+ }
+
+ static <E> Class<E> get(Class<? super E> value) {
+ return null;
+ }
+
+ static <E> E foo(Class<? super E> value) {
+ return null;
+ }
+}
+
+class Comp {
+ public static <T> boolean equal(T arg1, T arg2) {
+ return false;
+ }
+
+ void foo(String s, Object o) {
+ if (equal(s, o)) {
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA80386.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA80386.java
new file mode 100644
index 0000000..3587f4f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA80386.java
@@ -0,0 +1,33 @@
+import java.util.List;
+
+public class IDEA80386 {
+ void foo(Class<List> listClass) {
+ <error descr="Incompatible types. Found: 'java.lang.Class<java.util.List>', required: 'java.lang.Class<? extends java.util.List<?>>'">Class<? extends List<?>> cls = listClass;</error>
+ Class < ?extends List > cls1 = listClass;
+ <error descr="Incompatible types. Found: 'java.lang.Class<java.util.List>', required: 'java.lang.Class<? extends java.util.List<? extends java.util.List<?>>>'">Class<? extends List<? extends List<?>>> cls2 = listClass;</error>
+ Class<? super List<?>> clsS = listClass;
+ Class<? super List> clsS1 = listClass;
+ }
+
+ void fooE(Class<? extends List> listClass) {
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends java.util.List>>', required: 'java.lang.Class<? extends java.util.List<?>>'">Class<? extends List<?>> cls = listClass;</error>
+ Class<? extends List> cls1 = listClass;
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends java.util.List>>', required: 'java.lang.Class<? extends java.util.List<? extends java.util.List<?>>>'">Class<? extends List<? extends List<?>>> cls2 = listClass;</error>
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends java.util.List>>', required: 'java.lang.Class<? super java.util.List<?>>'">Class<? super List<?>> clsS = listClass;</error>
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends java.util.List>>', required: 'java.lang.Class<? super java.util.List>'">Class<? super List> clsS1 = listClass;</error>
+ }
+
+ void fooS(Class<? super List> listClass) {
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<? super java.util.List>>', required: 'java.lang.Class<? extends java.util.List<?>>'">Class<? extends List<?>> cls1 = listClass;</error>
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<? super java.util.List>>', required: 'java.lang.Class<? extends java.util.List<? extends java.util.List<?>>>'">Class<? extends List<? extends List<?>>> cls2 = listClass;</error>
+ Class<? super List<?>> clsS = listClass;
+ Class<? super List> clsS1 = listClass;
+ }
+
+ void fooU(Class<?> listClass) {
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<?>>', required: 'java.lang.Class<? extends java.util.List<?>>'">Class<? extends List<?>> cls1 = listClass;</error>
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<?>>', required: 'java.lang.Class<? extends java.util.List<? extends java.util.List<?>>>'">Class<? extends List<? extends List<?>>> cls2 = listClass;</error>
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<?>>', required: 'java.lang.Class<? super java.util.List<?>>'">Class<? super List<?>> clsS = listClass;</error>
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<?>>', required: 'java.lang.Class<? super java.util.List>'">Class<? super List> clsS1 = listClass;</error>
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA86875.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA86875.java
new file mode 100644
index 0000000..c5a65df
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA86875.java
@@ -0,0 +1,11 @@
+interface Base<E> {}
+interface Base2<E> {}
+
+class A<E extends Cloneable> {
+ <P, K extends Base<E>&Base2<P>> void m(K k, P p) {
+ E e = null;
+ m(k, e);
+ }
+
+ void m(Base<E> k, E e) {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA87860.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA87860.java
new file mode 100644
index 0000000..540ec4e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA87860.java
@@ -0,0 +1,11 @@
+interface A {
+ <T extends Exception> void foo() throws T;
+ <T extends Exception> void bar() throws Exception;
+ void baz() throws Exception;
+}
+
+interface B<T extends Throwable> extends A {
+ void foo() throws <error descr="'foo()' in 'B' clashes with 'foo()' in 'A'; overridden method does not throw 'T'">T</error>;
+ void bar() throws <error descr="'bar()' in 'B' clashes with 'bar()' in 'A'; overridden method does not throw 'java.lang.Throwable'">Throwable</error>;
+ void baz() throws <error descr="'baz()' in 'B' clashes with 'baz()' in 'A'; overridden method does not throw 'java.lang.Throwable'">Throwable</error>;
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA88895.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA88895.java
new file mode 100644
index 0000000..cf59c1d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA88895.java
@@ -0,0 +1,26 @@
+import java.util.Iterator;
+
+public class WildcardGenericAndPrivateField {
+
+ private Object field;
+
+ public Iterator<? extends WildcardGenericAndPrivateField> iterator() {
+ return null;
+ }
+
+ public void methodDoesNotCompile() {
+ Iterator<? extends WildcardGenericAndPrivateField> iterator = iterator();
+ while ( iterator.hasNext() ) {
+ Object o = iterator.next().<error descr="'field' has private access in 'WildcardGenericAndPrivateField'">field</error>;
+ }
+ }
+
+ public void methodCompiles() {
+ Iterator<? extends WildcardGenericAndPrivateField> iterator = iterator();
+ while ( iterator.hasNext() ) {
+ WildcardGenericAndPrivateField next = iterator.next();
+ Object o = next.field;
+ }
+ }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA89771.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA89771.java
new file mode 100644
index 0000000..f3a04de
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA89771.java
@@ -0,0 +1,3 @@
+public @interface MyAnnotation {
+ Class<? extends Enum<?>> enumClass() default <error descr="Incompatible types. Found: 'java.lang.Class<java.lang.Enum>', required: 'java.lang.Class<? extends java.lang.Enum<?>>'">Enum.class</error>;
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA89801.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA89801.java
new file mode 100644
index 0000000..aa8ba27
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA89801.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ {
+ Map<Number, String> map1 = null;
+ Map<Integer, String> map2 = <error descr="Inconvertible types; cannot cast 'java.util.Map<java.lang.Number,java.lang.String>' to 'java.util.Map<java.lang.Integer,java.lang.String>'">(Map<Integer, String>) map1</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA90802.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA90802.java
new file mode 100644
index 0000000..c679ed8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA90802.java
@@ -0,0 +1,24 @@
+import java.util.*;
+
+interface VcsRoot {
+}
+
+interface SVcsRoot extends VcsRoot {
+}
+
+interface A {
+ List<? extends VcsRoot> getVcsRoots();
+}
+
+interface B {
+ List<SVcsRoot> getVcsRoots();
+}
+
+interface F1 extends A, B {
+}
+
+class G {
+ void f(F1 o) {
+ SVcsRoot r = o.getVcsRoots().get(0);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA91626.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA91626.java
new file mode 100644
index 0000000..ff29729
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA91626.java
@@ -0,0 +1,25 @@
+class Test {
+ interface A<T> {
+ void _(T... t);
+ }
+
+ static void foo(final A<?> bar) {
+ bar._("");
+ }
+ static void foo1(final A<? extends String> bar) {
+ bar._("");
+ }
+
+ static void foo2(final A<? extends Integer> bar) {
+ bar._<error descr="'_(capture<? extends java.lang.Integer>...)' in 'Test.A' cannot be applied to '(java.lang.String)'">("")</error>;
+ }
+
+
+ public static void main(String[] args) {
+ foo(new A<Integer>() {
+ public void _(final Integer... t) {
+
+ }
+ });
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA92022.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA92022.java
new file mode 100644
index 0000000..d8d49f9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA92022.java
@@ -0,0 +1,23 @@
+class GetClassClient {
+ public void use() {
+ Class<? extends LocalGeneric> v1 = null;
+ Class<? extends LocalGeneric<Object>> v2 = null;
+ v1 = v2;
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends GetClassClient.LocalGeneric>>', required: 'java.lang.Class<? extends GetClassClient.LocalGeneric<java.lang.Object>>'">v2 = v1</error>;
+ }
+
+ public static class LocalGeneric<T> {
+ }
+}
+
+
+interface Comparable<T extends Comparable<T>> {}
+class List<T> {}
+
+class Foo implements Comparable<Foo> {
+ public static void main(String[] args){
+ List<? extends Foo> list = null;
+ List<? extends Comparable> c = null;
+ c = list;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA94011.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA94011.java
new file mode 100644
index 0000000..6d5cdfa
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA94011.java
@@ -0,0 +1,21 @@
+import java.util.*;
+class Test {
+
+ class Parent { }
+
+ interface Consumer<T> { }
+
+ interface MyConsumer<T extends Parent> extends Consumer<T> { }
+
+
+ public void test(Set<MyConsumer> set) {
+ @SuppressWarnings("unchecked")
+ Map<Parent, MyConsumer<Parent>> map = create<error descr="'create(java.util.Set<T>)' in 'Test' cannot be applied to '(java.util.Set<Test.MyConsumer>)'">(set)</error>;
+
+ }
+
+ public <S, T extends Consumer<S>> Map<S, T> create(Set<T> consumers) {
+ return null;
+ }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA97276.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA97276.java
new file mode 100644
index 0000000..625d706
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA97276.java
@@ -0,0 +1,17 @@
+interface Interf<X extends Interf> {}
+class SomeClass {
+ static <I extends Interf<? super I>> Class<I> someMethod(I i) { return null; }
+}
+
+interface OtherInterf<I1 extends Interf, I2 extends Interf> {}
+interface ImmutableSet<S> {}
+
+class SomeOtherClass {
+ static ImmutableSet<Class<? extends OtherInterf<?, ?>>> someOtherMethod() {
+ return <error descr="Inconvertible types; cannot cast 'ImmutableSet<java.lang.Class<? extends OtherInterf>>' to 'ImmutableSet<java.lang.Class<? extends OtherInterf<?,?>>>'">(ImmutableSet<Class<? extends OtherInterf<?, ?>>>)aux(OtherInterf.class)</error>;
+ }
+
+ static <T> ImmutableSet<Class<? extends T>> aux(Class<T> t) {
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA97888.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA97888.java
new file mode 100644
index 0000000..93e1217
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA97888.java
@@ -0,0 +1,23 @@
+import java.util.*;
+import java.io.File;
+class Foo {
+ public Collection<BuildTarget<?>> getDependencies(LayoutElementBuilderService builder, JpsPackagingElement element, TargetOutputIndex outputIndex) {
+ return builder.getDependencies(element, outputIndex);
+ }
+}
+
+class BuildTarget<R extends BuildRootDescriptor> {}
+
+interface TargetOutputIndex {
+ Collection<BuildTarget<?>> getTargetsByOutputFile(File file);
+}
+
+class BuildRootDescriptor {}
+
+class LayoutElementBuilderService<E extends JpsPackagingElement> {
+ public Collection<? extends BuildTarget<?>> getDependencies(E element, TargetOutputIndex outputIndex) {
+ return Collections.emptyList();
+ }
+}
+
+class JpsPackagingElement {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA98421.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA98421.java
new file mode 100644
index 0000000..28ac86b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA98421.java
@@ -0,0 +1,11 @@
+class Outer {
+ class Inner {
+ public <T> Inner(T t) { }
+ }
+
+ class Other extends Outer.Inner {
+ public Other() {
+ new Outer().<Object>super("Hi");
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA99061.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA99061.java
new file mode 100644
index 0000000..11afc6c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA99061.java
@@ -0,0 +1,11 @@
+class Test {
+ {
+ String a = cast("str");
+ Integer[] b = cast(new Integer[0]);
+ Object[] c = cast(new Object[0]);
+ }
+
+ private <T> T cast(Object obj) {
+ return (T)obj;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA99347.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA99347.java
new file mode 100644
index 0000000..9c49224
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA99347.java
@@ -0,0 +1,12 @@
+interface Errors {
+ java.util.Collection<java.lang.String> getErrorMessages();
+
+}
+
+class Test extends AbstrClass implements Errors {
+}
+
+
+abstract class AbstrClass {
+ public java.util.Collection getErrorMessages() {return null;}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV10459.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV10459.java
new file mode 100644
index 0000000..f3185c8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV10459.java
@@ -0,0 +1,31 @@
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/** @noinspection UnusedDeclaration*/
+public class GenericsTest98 {
+ public static void main(String[] args) throws Exception{
+ List<Movable<? extends Serializable>> list = new ArrayList<Movable<? extends Serializable>> ();
+ Factory factory = Factory.newInstance();
+ // Doesn't compile, but Idea doesn't complain
+ Mover<? extends Serializable> mover = factory.getNew<error descr="'getNew(java.util.List<? extends Movable<T>>)' in 'Factory' cannot be applied to '(java.util.List<Movable<? extends java.io.Serializable>>)'">(list)</error>;
+ }
+}
+
+abstract class Factory {
+ public static Factory newInstance(){
+ return null;
+ }
+
+ // This should actually be
+ // public abstract <T extends Serializable> Mover<T> getNew (List<? extends Movable<? extends T>> source);
+ public abstract <T extends Serializable> Mover<T> getNew (List<? extends Movable<T>> source);
+}
+
+/** @noinspection UnusedDeclaration*/
+interface Movable<T extends Serializable> extends Serializable {
+}
+
+/** @noinspection UnusedDeclaration*/
+interface Mover<T extends Serializable> {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV12951.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV12951.java
new file mode 100644
index 0000000..03cd4b6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV12951.java
@@ -0,0 +1,29 @@
+class ClassExt {
+
+ /** @noinspection UnusedDeclaration*/
+ public static <T, P1, P2> T newInstance(Class<T> clazz,
+ Class<? super P1> t1, P1 p1,
+ Class<? super P2> t2, P2 p2) {
+ return null;
+ }
+
+
+}
+
+abstract class TKey<T> {
+
+ protected abstract Class<T> getType();
+}
+
+
+class GoodIsRed6 {
+
+
+ public static <TK extends TKey<?>> TK createClone(TK tkey, String key) {
+
+
+ Class<TK> clazz = null;
+
+ return ClassExt.newInstance(clazz, String.class, key, Class.class, tkey.getType());
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV13011.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV13011.java
new file mode 100644
index 0000000..77b1de4
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV13011.java
@@ -0,0 +1,29 @@
+/** @noinspection UnusedDeclaration*/
+class LimitedPool<T> {
+ private int capacity;
+ private final ObjectFactory<T> factory;
+ private Object[] storage;
+ private int index = 0;
+
+ public LimitedPool(final int capacity, ObjectFactory<T> factory) {
+ this.capacity = capacity;
+ this.factory = factory;
+ storage = new Object[capacity];
+ }
+
+ interface ObjectFactory<T> {
+ T create();
+ void cleanup(T t);
+ }
+
+ public T alloc() {
+ if (index >= capacity) return factory.create();
+
+ if (storage[index] == null) {
+ storage[index] = factory.create();
+ }
+
+ <error descr="Incompatible types. Found: 'java.lang.Object[]', required: 'T'">return storage;</error>
+ }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV14006.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV14006.java
new file mode 100644
index 0000000..77cf1db
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV14006.java
@@ -0,0 +1,18 @@
+/** @noinspection UnusedDeclaration*/
+interface TestIF2<T> extends TestIF3<T> {}
+
+/** @noinspection UnusedDeclaration*/
+interface TestIF<T extends TestIF2<? extends Test2>> {
+ void run(T o1);
+}
+
+/** @noinspection UnusedDeclaration*/
+interface TestIF3<T> {}
+
+class Test2 {}
+
+class Test {
+ public void test(TestIF<?> testIF) {
+ testIF.run<error descr="'run(capture<? extends TestIF2<? extends Test2>>)' in 'TestIF' cannot be applied to '()'">()</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV14103.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV14103.java
new file mode 100644
index 0000000..77e6bb0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV14103.java
@@ -0,0 +1,52 @@
+class TestGenerics {
+
+ static interface EnumInterface {
+ public String getSomething();
+ }
+
+ static enum Enum1 implements EnumInterface {
+ A("alpha"),
+ B("beta"),
+ G("gamme"),
+ ;
+ private String text;
+
+ Enum1(String text) {
+ this.text = text;
+ }
+
+ public String getSomething() {
+ return text;
+ }
+ }
+
+ static class TestBase<I extends Enum<I> & EnumInterface> {
+
+ protected final void add(Eval eval) {
+ eval.hashCode();
+ }
+
+ abstract class Eval {
+ private I enumI;
+
+ public Eval(I enumI) {
+ this.enumI = enumI;
+ }
+
+ public final void doSomething() {
+ System.out.println(enumI.getSomething());
+ }
+ }
+
+ }
+
+
+
+
+ class Test1 extends TestBase<Enum1> {
+
+ public Test1() {
+ add(new Eval(Enum1.A) {});
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV15534.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV15534.java
new file mode 100644
index 0000000..774a2ef
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV15534.java
@@ -0,0 +1,29 @@
+import java.util.ArrayList;
+import java.util.Collections;
+
+class SortTest<R extends Comparable<R>> implements Comparable<SortTest<R>> {
+ R r;
+
+ public SortTest(R r) {
+ this.r = r;
+ }
+
+ public int compareTo(SortTest<R> o) {
+ return r.compareTo(o.r);
+ }
+
+ public static void main(String[] args) {
+ ArrayList<SortTest<?>> list = new ArrayList<SortTest<?>>();
+ SortTest<?> t1 = new SortTest<String>("");
+ list.add(t1);
+ SortTest<?> t2 = new SortTest<Integer>(0);
+ list.add(t2);
+ <error descr="Inferred type 'SortTest<?>' for type parameter 'T' is not within its bound; should implement 'java.lang.Comparable<? super SortTest<?>>'">Collections.sort(list)</error>;
+ t1.compareTo<error descr="'compareTo(SortTest<capture<? extends java.lang.Comparable<capture<?>>>>)' in 'SortTest' cannot be applied to '(SortTest<capture<?>>)'">(t2)</error>;
+
+ //this should be OK
+ SortTest<?>[] arr = new SortTest<?>[0];
+ arr[0] = new SortTest<String>("");
+ }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV23157.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV23157.java
new file mode 100644
index 0000000..eef2542
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV23157.java
@@ -0,0 +1,10 @@
+import java.util.List;
+import java.util.Arrays;
+
+public class ZZZ {
+
+ List<Class<?>> f(Class<?>[] exceptionTypes) {
+ List<Class<?>> nd = Arrays.asList(exceptionTypes);
+ return nd;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV24166.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV24166.java
new file mode 100644
index 0000000..c1952d1
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV24166.java
@@ -0,0 +1,49 @@
+import java.util.*;
+
+interface TypesafeMap<BASE> {
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public interface Key<BASE,VALUE> { }
+
+ public <VALUE, KEY extends Key<BASE,VALUE>>
+ boolean has(Class<KEY> key);
+
+ public <VALUE, KEY extends Key<BASE,VALUE>>
+ VALUE get(Class<KEY> key);
+
+ public <VALUEBASE, VALUE extends VALUEBASE, KEY extends Key<BASE,VALUEBASE>>
+ VALUE set(Class<KEY> key, VALUE value);
+
+ public <VALUE, KEY extends Key<BASE,VALUE>>
+ VALUE remove(Class<KEY> key);
+
+ public Set<Class<?>> keySet();
+
+ public <VALUE, KEY extends Key<CoreMap, VALUE>>
+ boolean containsKey(Class<KEY> key);
+}
+
+
+interface CoreMap extends TypesafeMap<CoreMap> { }
+
+interface CoreAnnotation<V>
+ extends TypesafeMap.Key<CoreMap, V> {
+
+ public Class<V> getType();
+}
+
+
+class CoreMaps {
+
+ public static <K,V> Map<K,V> toMap(Collection<CoreMap> coremaps,
+ Class<CoreAnnotation<K>> keyKey, Class<CoreAnnotation<V>> valueKey) {
+
+ Map<K,V> map = new HashMap<K,V>();
+ for (CoreMap cm : coremaps) {
+ map.put(cm.get(keyKey), cm.get(valueKey));
+ }
+
+ return map;
+ }
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV57343.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV57343.java
new file mode 100644
index 0000000..fb7e477
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV57343.java
@@ -0,0 +1,6 @@
+class D<T> {
+ void foo(D<?> x){
+ bar<error descr="'bar(D<? extends T>, D<? super T>)' in 'D' cannot be applied to '(D<capture<?>>, D<capture<?>>)'">(x,x)</error>;
+ }
+ <T> void bar(D<? extends T> x, D<? super T> y){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV7337.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV7337.java
new file mode 100644
index 0000000..bc89597
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEADEV7337.java
@@ -0,0 +1,74 @@
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Comparator;
+
+
+class TestIDEA
+{
+
+ public static class Test1<Type extends List & Serializable>
+ {
+ public void process(Serializable s)
+ {
+ }
+ public void process(Type t)
+ {
+ }
+ }
+
+ public static class Test2 extends Test1<ArrayList>
+ {
+ public void process(Serializable s)
+ {
+ super.process(s);
+ }
+
+ public void process(ArrayList t)
+ {
+ super.process(t); // this call is OK resolving to parameterized method in super
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ Test2 test=new Test2();
+ ArrayList list=new ArrayList();
+ test.process(list);
+ test.process((Serializable)list);
+ }
+}
+
+class Key<T> {
+ Object add(T v) {
+ return v;
+ }
+}
+
+class WKey<W, T> extends Key<T> {
+
+ W add(T v) {
+ return null;
+ }
+}
+
+class IBug {
+
+ public static <W, T> void addItem(WKey<W, T> key, T v) {
+ key.add(v); // --> demetra draw this in red, see attachment
+ }
+}
+
+//IDEADEV-7698
+abstract class Collator implements Comparator<Object> {
+ public abstract int compare(String source, String target);
+
+ public int compare(Object o1, Object o2) {
+ return compare((String)o1, (String)o2);
+ }
+
+ public void foo(Collator c) {
+ c.compare("foo", "bar");
+ }
+}
+//end of //IDEADEV-7698
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IllegalForwardReferenceInTypeParameterDefinition.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IllegalForwardReferenceInTypeParameterDefinition.java
new file mode 100644
index 0000000..31cdb61
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IllegalForwardReferenceInTypeParameterDefinition.java
@@ -0,0 +1,2 @@
+class A<T extends S, S> {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IllegalGenericTypeInInstanceof.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IllegalGenericTypeInInstanceof.java
new file mode 100644
index 0000000..52871e8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IllegalGenericTypeInInstanceof.java
@@ -0,0 +1,53 @@
+class A<T> {
+ public void foo(Object object) {
+ if (object instanceof <error descr="Illegal generic type for instanceof">B</error>) {}
+ if (object instanceof A.B) {}
+ if (object instanceof A<?>.B) {}
+ if (object instanceof A<?>) {}
+ if (object instanceof <error descr="Illegal generic type for instanceof">A<String></error>) {}
+ if (object instanceof A) {}
+ if (object instanceof A[]) {}
+ if (object instanceof <error descr="Illegal generic type for instanceof">B[]</error>) {}
+ if (object instanceof A.B[]) {}
+ }
+
+ private class B {
+ }
+}
+
+class A1 {
+ public void foo(Object object) {
+ if (object instanceof B1) {}
+ if (object instanceof A1.B1) {}
+ if (object instanceof B1[]) {}
+ }
+
+ private class B1 {
+ }
+}
+
+class BreakpointTree<TP> {
+ void foo(Node node) {
+ if (node instanceof BNode<?>) {
+
+ }
+ }
+
+ static class BNode<B extends XBreakpoint<?>> extends Node{}
+}
+class Node {}
+class XBreakpoint<SR>{}
+
+public class GenericInnerClass<E> {
+ private void problem( Base base ) {
+ if ( base instanceof First) {}
+ }
+
+ private class Base {
+ }
+
+ private class First<T> extends Base {
+ }
+
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ImplementAnnotation.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ImplementAnnotation.java
new file mode 100644
index 0000000..bbe1e30
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ImplementAnnotation.java
@@ -0,0 +1,15 @@
+import java.lang.annotation.Annotation;
+
+public @interface Foo {
+ String id();
+}
+
+class Bar implements Foo {
+ public String id() {
+ return null;
+ }
+
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InaccessibleThroughWildcard.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InaccessibleThroughWildcard.java
new file mode 100644
index 0000000..cc64719
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InaccessibleThroughWildcard.java
@@ -0,0 +1,13 @@
+class JavacConfiguration {
+ private final String mySettings = "";
+
+ public static void foo(Class<? extends JavacConfiguration> aClass) {
+ Object o = getService(aClass).<error descr="'mySettings' has private access in 'JavacConfiguration'">mySettings</error>;
+ JavacConfiguration configuration = getService(aClass);
+ String string = configuration.mySettings;
+ }
+
+ public static <T> T getService(Class<T> serviceClass) {
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IncompatibleReturnType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IncompatibleReturnType.java
new file mode 100644
index 0000000..3a8d3b0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IncompatibleReturnType.java
@@ -0,0 +1,20 @@
+abstract class F<A, B> {
+ public abstract B f(A a);
+
+ public final F<A, P1<B>> lazy() {
+ return new F<A, P1<B>>() {
+ public P1<B> f(final A a) {
+ return null;
+ }
+ };
+ }
+
+ private class TestClient<A, B> extends F<A, P1<B>> {
+ public P1<B> f(final A a) {
+ return null;
+ }
+ }
+}
+
+class P1<T> {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InconvertibleTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InconvertibleTypes.java
new file mode 100644
index 0000000..752453e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InconvertibleTypes.java
@@ -0,0 +1,8 @@
+import java.util.*;
+
+class Test {
+ void foo(){
+ Properties properties = System.getProperties();
+ final Map<String, String> systemProperties = <error descr="Inconvertible types; cannot cast 'java.util.Properties' to 'java.util.Map<java.lang.String,java.lang.String>'">(Map<String, String>) properties</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithBounds.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithBounds.java
new file mode 100644
index 0000000..626821e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithBounds.java
@@ -0,0 +1,61 @@
+import java.util.*;
+
+class CLS {
+ static <V extends String> void bar (V v) {}
+
+ static void foo () {
+ <error descr="Inferred type 'java.lang.Object' for type parameter 'V' is not within its bound; should extend 'java.lang.String'">bar(new Object())</error>;
+ }
+}
+//////////////////////////////
+public abstract class ZZZ<K> {
+ public abstract <T extends String> ZZZ<T> get();
+}
+class Z2<K> extends ZZZ<K> {
+ public <T extends String> Z2<T> get() {
+ return null;
+ }
+ void f() {
+ Z2 z2 = get();
+ }
+}
+/////////////////
+abstract class LeastRecentlyUsedCache {
+interface Callable<V> {
+ V call() throws Exception;
+}
+
+ <E extends A> Callable<E> e(E e) {
+ return null;
+ }
+ <T extends B> Callable<T> f(boolean b, final T t) {
+ return b ? e(t) : new Callable<T>() {
+ public T call() throws Exception {
+ return t;
+ }
+ };
+ }
+
+ void ff() {
+
+ }
+
+ class A {}
+ class B extends A {}
+}
+//////////////////////////
+public class BadCodeGreen<T, C extends Collection<? extends T>> {
+ public BadCodeGreen(C c, T t) {
+ c.add<error descr="'add(capture<? extends T>)' in 'java.util.Collection' cannot be applied to '(T)'">(t)</error>;
+ }
+}
+////////////////////////////
+abstract class A {
+ public abstract <T extends List<?>> T create();
+}
+class B extends A {
+ public <T extends List<?>> T create() {
+ return null;
+ }
+}
+///////////////////////////
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithBoxingCovariant.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithBoxingCovariant.java
new file mode 100644
index 0000000..453f82b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithBoxingCovariant.java
@@ -0,0 +1,16 @@
+import java.util.*;
+
+class Test {
+ static class Pair<A, B> {
+ Pair(A a, B b) {
+ }
+
+ static <A, B> Pair<A, B> create(A a, B b) {
+ return new Pair<A, B>(a, b);
+ }
+ }
+
+ public static void getWordsWithOffset(String s, int startInd, final List<Pair<String, Integer>> res) {
+ res.add(Pair.create(s, startInd));
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithSuperBounds.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithSuperBounds.java
new file mode 100644
index 0000000..d68f907
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithSuperBounds.java
@@ -0,0 +1,16 @@
+public class ExampleProblem {
+ <T> void asserting(T t, Simple<T> l){
+ }
+
+ <K> Simple<? super K> comp(K k){
+ return null;
+ }
+
+ public void main(String[] args) {
+ asserting(0, comp(0));
+ }
+}
+
+class Simple<SST>{
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithUpperBoundPromotion.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithUpperBoundPromotion.java
new file mode 100644
index 0000000..8b2aabe
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InferenceWithUpperBoundPromotion.java
@@ -0,0 +1,30 @@
+
+public class NestedGenericGoodCodeIsRed {
+
+ public void main( String[] args ) {
+ satisfiesAllOf(isPositive(), isEqualTo(10.9));
+ satisfiesAllOf(isPositive(), isEqualTo(10));
+
+ Number num = null;
+ satisfiesAllOf(isPositive(), isEqualTo(num));
+
+ this.<Number>satisfiesAllOf(isPositive(), isEqualTo(10));
+ }
+
+
+ public interface Predicate<T> {
+
+ }
+
+ public <ALL> void satisfiesAllOf( Predicate<? super ALL> first, Predicate<? super ALL> second ) {
+ }
+
+ public <POSITIVE extends Number> Predicate<POSITIVE> isPositive() {
+ return null;
+ }
+
+ public <EQUALTO extends Number> Predicate<EQUALTO> isEqualTo( EQUALTO target ) {
+ return null;
+ }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InheritFromTypeParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InheritFromTypeParameter.java
new file mode 100644
index 0000000..cfad53e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InheritFromTypeParameter.java
@@ -0,0 +1,2 @@
+class C<T> extends <error descr="Class cannot inherit from its type parameter">T</error>
+{}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InheritedWithDifferentArgsInTypeParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InheritedWithDifferentArgsInTypeParams.java
new file mode 100644
index 0000000..2adff2f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InheritedWithDifferentArgsInTypeParams.java
@@ -0,0 +1,24 @@
+interface IA<T> {}
+interface IB<T> extends IA<T> {}
+
+class A {
+ <<error descr="'IA' cannot be inherited with different type arguments: 'java.lang.Integer' and 'java.lang.String'"></error>T extends IA<Integer> & IB<String>> void foo(){}
+}
+
+
+
+interface IA1<T> {}
+interface IB1<T> extends IA1<T> {}
+
+class A1 {
+ <<error descr="'IA1' cannot be inherited with different type arguments: 'java.lang.Object' and 'capture<?>'"></error>T extends IA1<Object> & IB1<?>> void foo(){}
+}
+
+interface IA2<T> {}
+interface IB2<T> extends IA2<T[]> {}
+
+class A2 {
+ <T extends IA2<Object[]> & IB2<?>> void foo(){}
+}
+
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InnerClassRef.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InnerClassRef.java
new file mode 100644
index 0000000..f133292
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InnerClassRef.java
@@ -0,0 +1,19 @@
+import java.util.*;
+import Node.Details;
+
+public class Node<E> {
+ public class Details {
+ public E data;
+ }
+ public Details addNode(Node<E> child) {
+ return new Details();
+ }
+}
+
+class Test {
+ public static void main(String[] args) {
+ Map<String, Details> m = null;
+ Map<String, Node.Details> sorted1;
+ sorted1 = m;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InstanceClassInStaticContextAccess.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InstanceClassInStaticContextAccess.java
new file mode 100644
index 0000000..dcfad56b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/InstanceClassInStaticContextAccess.java
@@ -0,0 +1,62 @@
+class MyTest<K> {
+
+ class A<T> {
+ }
+
+ //not an error in java 8?!
+ static class C<T extends <error descr="'MyTest.this' cannot be referenced from a static context">A<String></error>> {
+ }
+
+ static <T extends <error descr="'MyTest.this' cannot be referenced from a static context">A<String></error>> void bar() {
+ }
+
+ static class B {
+ {
+ B.<<error descr="'MyTest.this' cannot be referenced from a static context">A</error>>bar();
+ <error descr="'MyTest.this' cannot be referenced from a static context">A</error> a;
+ }
+
+ static <T extends <error descr="'MyTest.this' cannot be referenced from a static context">A<String></error>> void bar() {
+ }
+
+ void v(C<<error descr="'MyTest.this' cannot be referenced from a static context">A<String></error>> c) {
+ }
+ }
+}
+
+class MyTest1 {
+
+ class A<T> {
+ }
+
+ static class C<T extends A<String>> {
+ }
+
+ static <T extends A<String>> void bar() {
+ }
+
+ static class B {
+ {
+ B.<A>bar();
+ A a = <error descr="'MyTest1.this' cannot be referenced from a static context">new A()</error>;
+ }
+
+ static <T extends A<String>> void bar() {
+ }
+
+ void v(C<A<String>> c) {
+ }
+ }
+}
+
+class MyTest2<T> {
+ static class A {
+ private MyTest2 myTest;
+
+ public Object foo() {
+ return myTest.new Bar();
+ }
+ }
+
+ class Bar {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IntersectionTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IntersectionTypes.java
new file mode 100644
index 0000000..48bb90c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IntersectionTypes.java
@@ -0,0 +1,221 @@
+import java.io.*;
+import java.util.*;
+
+class Test {
+ <T> List<T> asList (T... ts) {
+ ts.hashCode();
+ return null;
+ }
+
+ void foo() {
+ List<Class<? extends Serializable>> l = <warning descr="Unchecked generics array creation for varargs parameter">this.asList</warning>(String.class, Integer.class);
+ l.size();
+ List<? extends Object> objects = this.asList(new String(), new Integer(0));
+ objects.size();
+ }
+}
+
+//SUN BUG ID 5034571
+interface I1 {
+ void i1();
+}
+
+class G1 <T extends I1> {
+ T get() { return null; }
+}
+
+interface I2 {
+ void i2();
+}
+
+class Main {
+ void f2(G1<? extends I2> g1) {
+ g1.get().i1(); // this should be OK
+ g1.get().i2(); // this should also be OK
+ }
+}
+
+//IDEADEV4200: this code is OK
+interface I11 {
+ String i1();
+}
+
+interface I21 {
+ String i2();
+}
+
+interface A<T> {
+ T some();
+}
+
+interface B<T extends I11 & I21> extends A<T> {
+
+}
+
+class User {
+
+ public static void main(B<?> test) {
+ System.out.println(test.some().i1());
+ System.out.println(test.some().i2());
+ }
+}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//end of IDEADEV4200
+
+//IDEADEV-4214
+interface Keyable<K> {
+ /**
+ * @return the key for the instance.
+ */
+ public K getKey();
+}
+
+abstract class Date implements java.io.Serializable, Cloneable, Comparable<Date> {
+
+}
+
+class Maps {
+ public static class MapEntry<K, V> implements Map.Entry<K, V> {
+ K k;
+ V v;
+
+ public K getKey() {
+ return k;
+ }
+
+ public V getValue() {
+ return v;
+ }
+
+ public V setValue(V value) {
+ return v = value;
+ }
+
+ public MapEntry(K k, V v) {
+ this.k = k;
+ this.v = v;
+ }
+ }
+
+ public static <K, V> Map.Entry<K, V> entry(K key, V value) {
+ return new MapEntry<K, V>(key, value);
+ }
+
+ public static <K, V> Map<K, V> asMap(Map.Entry<? extends K, ? extends V> ... <warning descr="Parameter 'entries' is never used">entries</warning>) {
+ return null;
+ }
+
+ public static <K, V extends Keyable<K>> Map<K, V> asMap(V ... <warning descr="Parameter 'entries' is never used">entries</warning>) {
+ return null;
+ }
+}
+
+class Client {
+ void f(Date d) {
+ //this call should be OK
+ <warning descr="Unchecked generics array creation for varargs parameter">Maps.asMap</warning>(Maps.entry(fieldName(), "Test"),
+ Maps.entry(fieldName(), 1),
+ Maps.entry(fieldName(), d));
+ }
+
+ String fieldName() {
+ return null;
+ }
+}
+//end of IDEADEV-4214
+
+class IDEADEV25515 {
+ static <T> List<T> asList (T... ts) {
+ ts.hashCode();
+ return null;
+ }
+
+ public static final
+ List<Class<? extends Serializable>> SIMPLE_TYPES =
+<warning descr="Unchecked generics array creation for varargs parameter">asList</warning>(String.class, Integer.class ,Long.class, Double.class, /*Date.class,*/
+Boolean.class, Boolean.TYPE /*,String[].class */ /*,BigDecimal.class*/);
+
+
+ public static final List<Class<? extends Serializable>> SIMPLE_TYPES_INFERRED =
+ <warning descr="Unchecked generics array creation for varargs parameter">asList</warning>(String.class, Integer.class ,Long.class, Double.class, /*Date.class,*/
+ Boolean.class, Boolean.TYPE ,String[].class /*,BigDecimal.class*/);
+
+
+}
+///////////////////////
+class Axx {
+ <T extends Runnable> T a() {
+ String s = a();
+ s.hashCode();
+ return null;
+ }
+}
+///////////////
+interface L {}
+public class MaximalType {
+ public static <T> T getParentOfType(Class<? extends T>... classes) {
+ classes.hashCode();
+ return null;
+ }
+ {
+ <warning descr="Unchecked generics array creation for varargs parameter">getParentOfType</warning>(M2.class, M.class);
+ }
+}
+class M extends MaximalType implements L{}
+class M2 extends MaximalType implements L{}
+/////////////
+
+
+class IDEA67676 {
+ interface I<<warning descr="Type parameter 'T' is never used">T</warning>> {}
+ interface A<T> extends I<A<T>>{}
+ interface Com2<T, U> {
+ void foo(T t, U u);
+ }
+ interface Com1<T> {
+ void foo(T t);
+ }
+
+ abstract class X {
+ abstract <T> T foo(T x, T y);
+
+ void bar(A<A2> x, A<B2> y) {
+ A<? extends Com2<? extends Com2<?, ?>, ? extends Com2<?, ?>>> f = foo(x, y);
+ f.hashCode();
+ }
+
+ void boo(A<A3> x, A<B3> y) {
+ A<? extends Com2<? extends Com2<?, ?>, ? extends Com2<?, ?>>> f = foo(x, y);
+ f.hashCode();
+ }
+
+ void baz(A<A1> x, A<B1> y) {
+ A<? extends Com1<? extends Com1<?>>> f = foo(x, y);
+ f.hashCode();
+ }
+ }
+
+ abstract class A1 implements Com1<A1> {}
+ abstract class B1 implements Com1<B1> {}
+
+ abstract class A2 implements Com2<A2, A2> {}
+ abstract class B2 implements Com2<B2, B2> {}
+
+ abstract class A3 implements Com2<A3, B3> {}
+ abstract class B3 implements Com2<B3, A3> {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodCallOnRawTypesExtended.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodCallOnRawTypesExtended.java
new file mode 100644
index 0000000..42e1c42
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodCallOnRawTypesExtended.java
@@ -0,0 +1,17 @@
+import java.util.Collections;
+import java.util.List;
+
+class Bar {
+ private List<Property> getChildren(Property property, PropertiesContainer c) {
+ return property.getChildren(c);
+ }
+
+ static class PropertiesContainer<M extends Property> {}
+
+}
+
+class Property<K> {
+ public List<? extends Property<K>> getChildren(K container) {
+ return Collections.emptyList();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodCallParamsOnRawType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodCallParamsOnRawType.java
new file mode 100644
index 0000000..e399e5a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodCallParamsOnRawType.java
@@ -0,0 +1,32 @@
+class TestOnRawType {
+ public static void main(String[] args) {
+ new FooGenerator().process(TestOnRawType.class);
+ new FooGenerator().process(AFoo.class);
+ new FooGenerator().process(MFoo.class);
+ new FooGenerator<String>().process<error descr="'process(java.lang.Class<TestOnRawType.AFoo>)' in 'TestOnRawType.FooGenerator' cannot be applied to '(java.lang.Class<TestOnRawType>)'">(TestOnRawType.class)</error>;
+ new FooGenerator<String>().process(AFoo.class);
+ new FooGenerator<String>().process<error descr="'process(java.lang.Class<TestOnRawType.AFoo>)' in 'TestOnRawType.FooGenerator' cannot be applied to '(java.lang.Class<TestOnRawType.MFoo>)'">(MFoo.class)</error>;
+ }
+
+ static class AFoo {}
+ static class MFoo extends AFoo {}
+ static class FooGenerator<T> {
+ public void process(Class<AFoo> cls) {
+ }
+ }
+}
+
+class TestNonGenericType {
+ public static void main(String[] args) {
+ new FooGenerator().process<error descr="'process(java.lang.Class<TestNonGenericType.AFoo>)' in 'TestNonGenericType.FooGenerator' cannot be applied to '(java.lang.Class<TestNonGenericType>)'">(TestNonGenericType.class)</error>;
+ new FooGenerator().process(AFoo.class);
+ new FooGenerator().process<error descr="'process(java.lang.Class<TestNonGenericType.AFoo>)' in 'TestNonGenericType.FooGenerator' cannot be applied to '(java.lang.Class<TestNonGenericType.MFoo>)'">(MFoo.class)</error>;
+ }
+
+ static class AFoo {}
+ static class MFoo extends AFoo {}
+ static class FooGenerator {
+ public void process(Class<AFoo> cls) {
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodSignatureEquality.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodSignatureEquality.java
new file mode 100644
index 0000000..cabf948
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MethodSignatureEquality.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.io.*;
+class Test {
+ interface InterfA {
+ <T extends Cloneable & Iterable> void foo(T x);
+
+ <T extends Iterable & Cloneable> void foo(T x);
+ }
+
+ class ANotSame {
+ <T extends Cloneable & Iterable> void foo(T x){}
+
+ <T extends Iterable & Cloneable> void foo(T x){}
+ }
+
+ class BNotSame extends ANotSame {
+ @Override
+ <T extends Cloneable & Iterable> void foo(T x){}
+ }
+
+ abstract class A<T extends Throwable> {
+ abstract <T extends Comparable<?> & Serializable> void foo(T x, A<?> y);
+
+ abstract <T extends Serializable & Comparable<?>> void foo(T x, A<? extends Cloneable> y);
+ }
+
+ /* abstract class B<T extends Throwable> {
+ abstract <T extends Comparable<?> & Serializable> void foo(T x, B<?> y);
+
+ abstract <T extends Serializable & Comparable<?>> void foo(T x, B<? extends Throwable> y);
+ }
+
+
+ abstract class C<T extends Throwable & Serializable> {
+ abstract <T extends Comparable<?> & Serializable> void foo(T x, C<? extends Serializable> y);
+
+ abstract <T extends Serializable & Comparable<?>> void foo(T x, C<? extends Throwable> y);
+ }*/
+
+ abstract class D<T extends Throwable & Runnable> {
+ <error descr="'foo(T, D<? extends Runnable>)' clashes with 'foo(T, D<? extends Throwable>)'; both methods have same erasure">abstract <T extends Serializable & Comparable<?>> void foo(T x, D<? extends Runnable> y)</error>;
+
+ abstract <T extends Serializable & Comparable<?>> void foo(T x, D<? extends Throwable> y);
+ }
+
+
+ interface IA {}
+ interface IB {}
+ void testExtendsOrder() {
+ class E<T extends IA & IB> {
+ <error descr="'foo(E<? extends IA>)' clashes with 'foo(E<? extends IB>)'; both methods have same erasure">void foo(E<? extends IA> x)</error> {}
+ void foo(E<? extends IB> x) {}
+ }
+ }
+
+ abstract class F<T extends Throwable> {
+ <error descr="'foo(F<?>)' is already defined in 'Test.F'">abstract void foo(F<?> y)</error>;
+
+ <error descr="'foo(F<? extends Throwable>)' is already defined in 'Test.F'">abstract void foo(F<? extends Throwable> y)</error>;
+ }
+}
+
+class Ao {}
+
+class Bo extends Ao {}
+
+class SettingsEditor<T> {
+}
+
+abstract class RunConfigurationExtension<T extends Ao> {
+ protected abstract <P extends T> SettingsEditor<P> createEditor(final P configuration);
+}
+
+class F extends RunConfigurationExtension<Bo> {
+
+ @Override
+ protected <P extends Bo> SettingsEditor<P> createEditor(P configuration) {
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Methods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Methods.java
new file mode 100644
index 0000000..d0f994e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Methods.java
@@ -0,0 +1,38 @@
+import java.util.*;
+
+interface Base {
+}
+
+class Derived implements Base {
+}
+
+class X {
+ void method(int i, Base b) { }
+ void method(int i, Derived b) { }
+
+ {
+ Derived d = new Derived();
+ method(10, d);
+ }
+}
+
+class Temp<T> {}
+
+class A {
+ <error descr="'A(T)' clashes with 'A(T)'; both methods have same erasure">public <T extends Temp<String>> A(T list)</error> {}
+ public <T extends Temp<Integer>> A(T list) {}
+}
+class B {
+ public <T extends A> B(T list) {}
+ public <T extends Temp<Integer>> B(T list) {}
+}
+
+
+
+//////////////////////////////////////////
+class IdeaBug {
+
+ static <T> T cloneMe(T arg) throws CloneNotSupportedException {
+ return (T) arg.<error descr="'clone()' has protected access in 'java.lang.Object'">clone</error>();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/NoInferenceFromTypeCast.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/NoInferenceFromTypeCast.java
new file mode 100644
index 0000000..636556d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/NoInferenceFromTypeCast.java
@@ -0,0 +1,23 @@
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+
+interface A {}
+
+interface B extends A {}
+
+class Foo {
+ public <TA extends A> List<TA> getAs() {
+ return (List<TA>) getBs();
+ }
+
+ public <T extends B> List<T> getBs() {
+ return null;
+ }
+
+ void foo(Set<String> s) {}
+ {
+ foo(<error descr="Inconvertible types; cannot cast 'java.util.Set<java.lang.Object>' to 'java.util.Set<java.lang.String>'">(Set<String>)Collections.emptySet()</error>);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/OverrideAtLanguageLevel6.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/OverrideAtLanguageLevel6.java
new file mode 100644
index 0000000..d83cf65
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/OverrideAtLanguageLevel6.java
@@ -0,0 +1,13 @@
+interface I {
+ void f();
+}
+interface II extends I {
+ @Override
+ void f();
+}
+class C implements I {
+ @Override
+ public void f() {
+
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/OverrideWithMoreSpecificReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/OverrideWithMoreSpecificReturn.java
new file mode 100644
index 0000000..c2f6877
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/OverrideWithMoreSpecificReturn.java
@@ -0,0 +1,15 @@
+import java.util.List;
+
+interface ExampleInterface {
+ public List exampleMethod();
+}
+
+class ExampleSuperClass {
+ public List<String> exampleMethod() {
+ return null;
+ }
+}
+
+
+public class ExampleSubClass extends ExampleSuperClass implements ExampleInterface {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ParameterizedParameterBound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ParameterizedParameterBound.java
new file mode 100644
index 0000000..50e117b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ParameterizedParameterBound.java
@@ -0,0 +1,6 @@
+import java.util.*;
+class ParamHolder<T extends List<String>> {}
+class HolderUsage {
+ public void fail(ParamHolder<<error descr="Type parameter 'java.util.List' is not within its bound; should extend 'java.util.List<java.lang.String>'">List</error>> p) { }
+ public void success(ParamHolder<ArrayList<String>> p) { }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/PrivateInnerClassRef.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/PrivateInnerClassRef.java
new file mode 100644
index 0000000..5647b1d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/PrivateInnerClassRef.java
@@ -0,0 +1,30 @@
+import java.util.Comparator;
+
+public abstract class A implements <error descr="'A.B' has private access in 'A'">Comparator<A.B></error> {
+
+ private static class B {
+ }
+
+ private interface I extends Comparator<I>{}
+ private interface I1 extends Comparator<I>{}
+}
+
+//abstract class C implements error descr="'C.D' has private access in 'C'">C.D error {
+// private static class D {}
+//}
+
+class JSReferenceSet {
+ static class MyResolver implements JSResolveUtil.Resolver<M> {}
+ class M extends JSResolveUtil.F {}
+}
+class JSResolveUtil {
+ static interface Resolver<T extends F> {}
+ static class F {}
+}
+
+
+class TestIDEA62515 {
+ public static interface Model<T> {}
+ public class Inner {}
+ public static class Foo implements Model<Inner> {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Raw.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Raw.java
new file mode 100644
index 0000000..25ef682
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Raw.java
@@ -0,0 +1,177 @@
+import java.util.ArrayList;
+
+class Reference<<warning descr="Type parameter 'T' is never used">T</warning>> {
+}
+class WeakReference<T> extends Reference<T> {
+}
+class Item<<warning descr="Type parameter 'Key' is never used">Key</warning>, T> extends WeakReference<T> {
+ {
+ Reference<T> ref = null;
+ Item item = (Item) ref;
+ equals(item);
+ }
+}
+
+// assign raw to generic are allowed
+class a<E> {
+ void f(a<E> t){
+ t.hashCode();
+ }
+}
+class b {
+ a<b> f(a raw) {
+ a<?> unbound = raw;
+ raw = unbound;
+
+ a<Integer> generic = <warning descr="Unchecked assignment: 'a' to 'a<java.lang.Integer>'">raw</warning>;
+ <warning descr="Unchecked call to 'f(a<E>)' as a member of raw type 'a'">raw.f</warning>(raw);
+ <warning descr="Unchecked call to 'f(a<E>)' as a member of raw type 'a'">raw.f</warning>(generic);
+ generic.f(<warning descr="Unchecked assignment: 'a' to 'a<java.lang.Integer>'">raw</warning>);
+ generic.f(generic);
+ generic.f<error descr="'f(a<java.lang.Integer>)' in 'a' cannot be applied to '(a<java.lang.String>)'">(new a<String>())</error>;
+ generic = <warning descr="Unchecked assignment: 'a' to 'a<java.lang.Integer>'">raw</warning>;
+
+
+ return <warning descr="Unchecked assignment: 'a' to 'a<b>'">raw</warning>;
+ }
+}
+
+class List<T> {
+ <V> V[] toArray (V[] vs) { return vs; }
+ void add(T t) {
+ t.hashCode();
+ }
+}
+
+class c {
+ /*String[] f () {
+ List l = new List();
+ error descr="Incompatible types. Found: 'java.lang.Object[]', required: 'java.lang.String[]'">return l.toArray (new String[0]);</error
+ }*/
+
+ String[] g () {
+ List<String> l = new List<String>();
+ return l.toArray (new String[0]);
+ }
+}
+
+class d {
+ class Y <<warning descr="Type parameter 'T' is never used">T</warning>> {
+ }
+
+ class Z <<warning descr="Type parameter 'T' is never used">T</warning>> extends Y<Y> {
+ }
+
+ class Pair <X> {
+ void foo(Y<? extends X> y) {
+ y.hashCode();
+ }
+ }
+
+ Pair<Z> pair;
+
+ void bar(Y<? extends Y> y) {
+ pair.foo<error descr="'foo(d.Y<? extends d.Z>)' in 'd.Pair' cannot be applied to '(d.Y<capture<? extends d.Y>>)'">(y)</error>;
+ }
+}
+
+class e {
+ String foo () {
+ MyList myList = new MyList();
+ <error descr="Incompatible types. Found: 'java.lang.Object', required: 'java.lang.String'">return myList.get(0);</error>
+ }
+
+ static class MyList<<warning descr="Type parameter 'T' is never used">T</warning>> extends ArrayList<String>{
+ }
+}
+
+class ccc {
+ static Comparable<? super ccc> f() {
+ return <warning descr="Unchecked assignment: 'java.lang.Comparable' to 'java.lang.Comparable<? super ccc>'">new Comparable () {
+ public int compareTo(final Object o) {
+ return 0;
+ }
+ }</warning>;
+ }
+}
+
+class ddd<COMP extends ddd> {
+ COMP comp;
+ ddd foo() {
+ return comp; //no unchecked warning is signalled here
+ }
+}
+
+class G1<T> {
+ T t;
+}
+class G2<T> {
+ T t;
+
+ static ArrayList<G1> f() {
+ return null;
+ }
+}
+
+class Inst {
+ static void f () {
+ G2<G1<String>> g2 = new G2<G1<String>>();
+ for (<warning descr="Unchecked assignment: 'G1' to 'G1<java.lang.String>'">G1<String> g1</warning> : g2.f()) {
+ g1.toString();
+ }
+ }
+}
+
+class A111<T> {
+ T t;
+ <V> V f(V v) {
+ return v;
+ }
+
+ String g(A111 a) {
+ //noinspection unchecked
+ <error descr="Incompatible types. Found: 'java.lang.Object', required: 'java.lang.String'">return a.f("");</error>
+ }
+}
+
+class A1 {
+ <V> V f(V v) {
+ return v;
+ }
+}
+
+class A11<T> extends A1 {
+ T t;
+
+ //this is OK, type parameters of base class are not raw
+ String s = new A11().f("");
+}
+
+//IDEADEV-26163
+class Test1<X> {
+ X x;
+ java.util.ArrayList<Number> foo = new java.util.ArrayList<Number>();
+ public static Number foo() {
+ <error descr="Incompatible types. Found: 'java.lang.Object', required: 'java.lang.Number'">return new Test1().foo.get(0);</error>
+ }
+}
+//end of IDEADEV-26163
+
+
+/////////////// signatures in non-parameterized class are not erased
+public class C3 {
+ public int get(Class<?> c) {
+ return 0;
+ }
+}
+
+class Cp<T> extends C3 {
+ public T i;
+}
+class C extends Cp/*<C>*/ {
+ @Override
+ public int get(Class<?> c) {
+ return 0;
+ }
+}
+//////////////
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawAssignments.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawAssignments.java
new file mode 100644
index 0000000..bd2af72
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawAssignments.java
@@ -0,0 +1,18 @@
+import java.io.*;
+import java.util.*;
+
+interface Foo {
+ String getText(Map attributes) throws IOException;
+ String getText(Properties attributes) throws IOException;
+}
+
+class Bar {
+ void foo(Foo foo, Properties prop) throws IOException {
+ foo.getText(prop);
+ }
+}
+public abstract class Hashtable<K,V> implements Map<K,V>, Cloneable {
+}
+
+public abstract class Properties extends Hashtable<Object,Object> {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawOnParameterized.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawOnParameterized.java
new file mode 100644
index 0000000..ebdeca9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawOnParameterized.java
@@ -0,0 +1,29 @@
+class GenericOuter<T> {
+ public class GenericInner<U> {
+ }
+
+ public static class StaticGenericInner<U> {
+ }
+
+ public class SimpleInner {
+ }
+}
+
+class OuterClient {
+ public void context() {
+ <error descr="Improper formed type; some type parameters are missing">GenericOuter<String>.GenericInner</error> v1 = null;
+ GenericOuter.GenericInner<error descr="Type arguments given on a raw type"><String></error> v2 = null;
+ GenericOuter.GenericInner v3 = null;
+ GenericOuter<String>.GenericInner<String> v4 = null;
+
+ GenericOuter<error descr="Cannot select static class 'GenericOuter.StaticGenericInner' from parameterized type"><String></error>.StaticGenericInner sv1 = null;
+ GenericOuter.StaticGenericInner<String> sv2 = null;
+ GenericOuter.StaticGenericInner sv3 = null;
+ GenericOuter<error descr="Cannot select static class 'GenericOuter.StaticGenericInner' from parameterized type"><String></error>.StaticGenericInner<String> sv4 = null;
+
+ GenericOuter<String>.SimpleInner iv1 = null;
+ GenericOuter.SimpleInner<error descr="Type arguments given on a raw type"><String></error> iv2 = null;
+ GenericOuter.SimpleInner iv3 = null;
+ GenericOuter<String>.SimpleInner<error descr="Type 'GenericOuter.SimpleInner' does not have type parameters"><String></error> iv4 = null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawOverridingMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawOverridingMethods.java
new file mode 100644
index 0000000..1934012
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/RawOverridingMethods.java
@@ -0,0 +1,271 @@
+import java.util.*;
+
+class Base<T> {
+ public void method(Base<?> base) { }
+ public void method1(Base<Base<?>> base) { }
+ public <V> Base<V> foo() { return null; }
+ public Base<?> bar() { return null; }
+ public Base<Base<?>> far() { return null; }
+}
+
+class Derived extends Base {
+ public void method(Base base) { }
+ public Base foo() { return null; }
+ public Base bar() { return null; }
+}
+
+class Derived1 extends Base {
+ <error descr="'method1(Base<String>)' in 'Derived1' clashes with 'method1(Base<Base<?>>)' in 'Base'; both methods have same erasure, yet neither overrides the other">public void method1(Base<String> base)</error> { }
+ public Base<String> far() { return null; } // Acceptable construct as of JDK 1.5 beta 2 may 2004
+}
+
+class X <T> {
+ public <V> void foo () {}
+}
+
+class YY extends X {
+ <error descr="'foo()' in 'YY' clashes with 'foo()' in 'X'; both methods have same erasure, yet neither overrides the other">public <V> void foo()</error> {}
+}
+
+interface List<Y> {
+ public <T> T[] toArray(T[] ts);
+}
+class AbstractList<Y> {
+ public <T> T[] toArray(T[] ts) {return null;}
+}
+//Signatures from List and AbstractList are equal
+class ArrayList extends AbstractList implements List {}
+
+//SCR 39485: the following overriding is OK
+abstract class Doer {
+ abstract <X> void go(X x);
+}
+
+class MyList <X>
+ extends Doer {
+ X x;
+ <Y> void go(Y y) {}
+}
+
+class MyListRaw
+ extends MyList {
+}
+
+//See IDEADEV-1125
+//The following two classes are OK
+class A1 {
+ <T> void foo(T t) {}
+}
+
+class A2 extends A1 {
+ void foo(Object o) {}
+}
+
+//While these are not
+class A3 {
+ void foo(Object o) {}
+}
+
+class A4 extends A3 {
+ <error descr="'foo(T)' in 'A4' clashes with 'foo(Object)' in 'A3'; both methods have same erasure, yet neither overrides the other"><T> void foo(T t)</error> {}
+}
+
+//This sibling override is OK
+class A5 {
+ public void foo(Object o) {}
+}
+
+interface I1 {
+ <T> void foo(T t);
+}
+
+class A6 extends A5 implements I1 {}
+
+//While this is not
+class A7 {
+ public <T> void foo(T t) {}
+}
+
+interface I2 {
+ public void foo(Object o);
+}
+
+<error descr="Class 'A8' must either be declared abstract or implement abstract method 'foo(Object)' in 'I2'">class A8 extends A7 implements I2</error> {}
+
+//IDEA-9321
+abstract class MyMap<K, V> implements java.util.Map<K, V> {
+ public <error descr="'put(K, V)' in 'MyMap' clashes with 'put(K, V)' in 'java.util.Map'; attempting to use incompatible return type">Object</error> put(K key, V value) {
+ return null;
+ }
+}
+//end of IDEA-9321
+
+abstract class AA <T> {
+ abstract void foo(T t);
+}
+
+abstract class BB<T> extends AA<BB> {
+ void foo(BB b) {}
+}
+
+class CC extends BB {
+ //foo is correctly seen from BB
+}
+
+class QQQ {}
+
+abstract class GrandParent<T> {
+ public abstract void paint(T object);
+}
+
+class Parent<T extends QQQ> extends GrandParent<T> {
+ public void paint(T component) {
+ }
+}
+
+// this overriding should be OK
+class Child2 extends Parent {
+
+}
+
+class IDEA16494 {
+ class Base<B> {
+ public List<B> elements() {
+ return null;
+ }
+ }
+
+ class Derived<T> extends Base<T[]> {
+ }
+
+ class MostDerived extends Derived {
+
+ public List<MostDerived[]> elements() {
+ return null;
+ }
+ }
+}
+class IDEA16494Original {
+ class Base<B> {
+ public List<B> elements() {
+ return null;
+ }
+ }
+
+ class Derived<T> extends Base<T> {
+ }
+
+ class MostDerived extends Derived {
+
+ public List<MostDerived> elements() {
+ return null;
+ }
+ }
+}
+class IDEADEV23176Example {
+ public abstract class AbstractBase<E> extends AbstractParent<E> implements Interface<E> {
+ }
+ public abstract class AbstractParent<E> {
+ public void Implemented(Collection<?> c) {
+ }
+ public abstract void mustImplement();
+ }
+ public class Baseclass extends AbstractBase implements Interface {
+ public void mustImplement() {
+ }
+ }
+ public interface Interface<E> {
+ void Implemented(Collection<?> c);
+ }
+}
+
+/** @noinspection UnusedDeclaration*/
+class IDEADEV26185
+{
+ public static abstract class SuperAbstract<Owner, Type>
+ {
+ public abstract Object foo(Type other);
+ }
+
+ public static abstract class HalfGenericSuper<Owner> extends SuperAbstract<Owner, String>
+ {
+ public abstract Object foo(String other);
+ }
+
+ public static abstract class AbstractImpl<Owner> extends HalfGenericSuper<Owner>
+ {
+ public Object foo(String other)
+ {
+ return null;
+ }
+ }
+
+ public static class Concrete extends AbstractImpl
+ {
+ }
+}
+
+class ideadev30090 {
+ abstract class MyBeanContext
+ implements MyListInterface/*<MyListMember>*/ {
+ public Object get(int index) {
+ return null;
+ }
+ }
+
+ interface MyListInterface<E extends MyListMember>
+ extends List<E> {
+ }
+ interface MyListMember {
+ void f();
+ }
+}
+//////////////////////////////////////////
+class IDEADEV32421 {
+ interface InterfaceWithFoo {
+ Class<?> foo();
+ }
+
+ class ParentWithFoo implements InterfaceWithFoo {
+ public Class foo() {
+ return null;
+ }
+ }
+
+ class TestII extends ParentWithFoo implements InterfaceWithFoo {
+ }
+}
+
+class IDEADEV32421_TheOtherWay {
+ interface InterfaceWithFoo {
+ Class foo();
+ }
+
+ class ParentWithFoo implements InterfaceWithFoo {
+ public Class<?> foo() {
+ return null;
+ }
+ }
+
+ class TestII extends ParentWithFoo implements InterfaceWithFoo {
+ }
+}
+//////////////////////////////////////
+class SBBug {
+ abstract class A<T> implements Comparable<A<T>> {}
+
+ class B extends A {
+ public int compareTo(Object o) {
+ return 0;
+ }
+ }
+}
+class SBBug2 {
+ abstract class A<T> implements Comparable<A<T>> {}
+
+ <error descr="Class 'B' must either be declared abstract or implement abstract method 'compareTo(T)' in 'Comparable'">class B extends A</error> {
+ public int compareTo(A o) {
+ return 0;
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ReferenceTypeParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ReferenceTypeParams.java
new file mode 100644
index 0000000..2d64d7c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ReferenceTypeParams.java
@@ -0,0 +1,152 @@
+import java.lang.Object;
+import java.util.*;
+
+class C<T,U> {
+
+ C c1 = new C<error descr="Wrong number of type arguments: 1; required: 2"><Integer></error>();
+ C c2 = new C<error descr="Wrong number of type arguments: 3; required: 2"><Integer, Float, Object></error>();
+ Object o = new Object<error descr="Type 'java.lang.Object' does not have type parameters"><C></error>();
+
+ C c3 = new C();
+ C c4 = new C<Object, C>();
+ C<Integer, Float> c5 = new C<Integer, Float>();
+}
+
+class D<T extends C> {
+ {
+ new D<<error descr="Type parameter 'java.lang.Integer' is not within its bound; should extend 'C'">Integer</error>>();
+ new D<C>();
+ class CC extends C {};
+ new D<CC>();
+ new D<T>();
+ }
+
+ T field = new <error descr="Type parameter 'T' cannot be instantiated directly">T</error>();
+ T field2 = new <error descr="Type parameter 'T' cannot be instantiated directly">T</error>() { };
+ T[] array = new <error descr="Type parameter 'T' cannot be instantiated directly">T</error>[10];
+}
+
+class Primitives<T> {
+ Object a = new Primitives<<error descr="Type argument cannot be of primitive type">? extends int</error>>();
+ Object o = new Primitives<<error descr="Type argument cannot be of primitive type">int</error>>();
+ void f(Primitives<<error descr="Type argument cannot be of primitive type">boolean</error>> param) {
+ if (this instanceof Primitives<<error descr="Type argument cannot be of primitive type">double</error>>) {
+ return;
+ }
+ }
+}
+
+
+/////// calling super on generic bound class
+public class Generic<T> {
+ Generic(T t){}
+}
+public class Bound extends Generic<String>{
+ public Bound(String s) {
+ super(s);
+ }
+}
+
+////
+class Generic2<T1,T2> {
+ class A {}
+ class B {}
+ private <error descr="Incompatible types. Found: 'Generic2<java.lang.String,Generic2.B>', required: 'Generic2<java.lang.String,Generic2.A>'">Generic2<String, A> map = new Generic2<String,B>();</error>
+ {
+ <error descr="Incompatible types. Found: 'Generic2<java.lang.String,java.lang.String>', required: 'Generic2<java.lang.String,Generic2.A>'">map = new Generic2<String,String>()</error>;
+ map = new Generic2<String,A>();
+ }
+}
+
+class DummyList<T> {}
+abstract class GenericTest3 implements DummyList<<error descr="No wildcard expected">? extends String</error>> {
+ DummyList<DummyList<? extends DummyList>> l;
+ <T> void foo () {}
+ void bar () {
+ this.<DummyList<? extends DummyList>>foo();
+ DummyList<DummyList<? super String>>[] l = <error descr="Generic array creation">new DummyList<DummyList<? super String>>[0]</error>;
+ DummyList<String>[] l1 = <error descr="Generic array creation">{}</error>;
+ }
+
+ public <T> T[] getComponents (Class<T> baseInterfaceClass) {
+ T[] ts = <error descr="Generic array creation">{}</error>;
+
+ return ts;
+ }
+}
+
+class mylist<T> {}
+class myAList<T> extends mylist<T> {
+ {
+ mylist<String> l = <error descr="Inconvertible types; cannot cast 'myAList<java.lang.Integer>' to 'mylist<java.lang.String>'">(mylist<String>) new myAList<Integer>()</error>;
+ boolean b = <error descr="Operator '==' cannot be applied to 'myAList<java.lang.Integer>', 'myAList<java.lang.String>'">new myAList<Integer>() == new myAList<String>()</error>;
+
+ if (l instanceof <error descr="Illegal generic type for instanceof">myAList<String></error>);
+ Object o = new Object();
+ if (o instanceof <error descr="Class or array expected">T</error>);
+ }
+
+ Class<T> foo (Class<T> clazz) {
+ Class<String> clazz1 = (Class<String>)clazz; //Should be unchecked warning
+ return <error descr="Cannot select from a type variable">T</error>.class;
+ }
+}
+
+class testDup<T, <error descr="Duplicate type parameter: 'T'">T</error>> { // CAN IT BE HIGHLIGHTED? b
+ public <T, <error descr="Duplicate type parameter: 'T'">T</error>> void foo() { // CAN IT BE HIGHLIGHTED?
+ }
+}
+
+class aaaa {
+ {
+ <error descr="Incompatible types. Found: 'java.lang.Class<java.lang.String>', required: 'java.lang.Class<? super java.lang.Object>'">Class<? super Object> c = String.class;</error>
+ }
+}
+
+//IDEADEV-6103: this code is OK
+class Foo {
+ mylist<Test> foo;
+
+ public Foo(mylist<Test> foo) {
+ this.foo = foo;
+ }
+
+ public Foo() {
+ this(new mylist<Test>());
+ }
+
+ private class Test {
+ }
+}
+//end of IDEADEV-6103
+
+class IDontCompile {
+ Map<error descr="Cannot select static class 'java.util.Map.Entry' from parameterized type"><?, ?></error>.Entry map;
+}
+
+abstract class GenericTest99<E extends Enum<E>> {
+ GenericTest99<<error descr="Type parameter 'java.lang.Enum' is not within its bound; should extend 'java.lang.Enum<java.lang.Enum>'">Enum</error>> local;
+}
+
+class ClassLiteral<T> {
+ {
+ Object c1 = <error descr="Cannot select from a type variable">T</error>.class;
+ Object c2 = <error descr="Cannot select from a type variable">T[]</error>.class;
+
+ Object c3 = <error descr="Cannot select from parameterized type">List<String></error>.class;
+ Object c4 = <error descr="Cannot select from parameterized type">List<String>[]</error>.class;
+ Object c5 = List[].class;
+ Object c6 = List.class;
+ }
+}
+
+class Outer<E> {
+ final Inner[] i = <error descr="Generic array creation">new Inner[10]</error>;
+ class Inner {
+ }
+}
+class Outer1<E> {
+ final Inner[] i = new Inner[10];
+ static class Inner {
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SOE.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SOE.java
new file mode 100644
index 0000000..85aeee7
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SOE.java
@@ -0,0 +1,24 @@
+public class SOE {
+}
+abstract class VersionEntity<V extends Version<V, R>, R extends Ref<V, R>>
+ implements Version<V, R>{}
+
+interface Version<V extends Version<V, R>, R extends Ref<V, R>>{}
+
+abstract class RefEntity<V extends Version<V, R>, R extends Ref<V, R>>
+ implements Ref<V, R> {}
+
+interface Ref<V extends Version<V, R>, R extends Ref<V, R>>{}
+
+
+abstract class Node<G extends Node<G, GR>,
+ GR extends NodeRef<G, GR>> extends VersionEntity<G, GR> {}
+
+abstract class NodeRef<G extends Node<G, GR>, GR extends NodeRef<G, GR>> extends RefEntity<G, GR> {}
+
+
+class D {
+ void f() {
+ Version v = new Node<<error descr="Wildcard type '?' cannot be instantiated directly">?</error>, <error descr="Wildcard type '?' cannot be instantiated directly">?</error>>(){}<EOLError descr="';' expected"></EOLError>
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SOEInLeastUpperClass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SOEInLeastUpperClass.java
new file mode 100644
index 0000000..70ad266
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SOEInLeastUpperClass.java
@@ -0,0 +1,12 @@
+<error descr="Cyclic inheritance involving 'A'">interface A extends A</error> {}
+interface B {}
+
+<error descr="Cyclic inheritance involving 'A'">class T implements A, B</error>{
+ <T1> T1 foo(A a, B b) {
+ return null;
+ }
+
+ void bar (boolean a, A a1, B b1){
+ <error descr="Incompatible types. Found: 'java.lang.Object', required: 'T'">T t = a ? a1 : b1;</error>
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SameErasure.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SameErasure.java
new file mode 100644
index 0000000..9bb49b2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SameErasure.java
@@ -0,0 +1,34 @@
+import java.util.*;
+
+class SameSignatureTest {
+ <error descr="'sameErasure(List<String>)' clashes with 'sameErasure(List<Integer>)'; both methods have same erasure">public static void sameErasure(List<String> strings)</error> {
+ }
+
+ public static void sameErasure(List<Integer> integers) {
+ }
+}
+
+ class CCC {
+ <error descr="'f(Object)' clashes with 'f(Object)'; both methods have same erasure"><T> void f(Object o)</error> {}
+
+ void f(Object o) {}
+}
+
+public class Test1 {
+ <error descr="'bug(String)' clashes with 'bug(String)'; both methods have same erasure">public void bug(String s)</error> {
+ }
+
+ public static <T> T bug(String s) {
+ return null;
+ }
+}
+////////////////////////////////
+class Test {
+ <error descr="'test()' clashes with 'test()'; both methods have same erasure">public static <K, V> HashMap<K, V> test()</error> {
+ return new HashMap<K, V>();
+ }
+
+ public static String test() {
+ return "";
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SameErasureDifferentReturnTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SameErasureDifferentReturnTypes.java
new file mode 100644
index 0000000..8bbd7b6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SameErasureDifferentReturnTypes.java
@@ -0,0 +1,53 @@
+/** @noinspection UnusedDeclaration*/
+interface Matcher<T> {
+
+ boolean matches(java.lang.Object object);
+
+ void _dont_implement_Matcher___instead_extend_BaseMatcher_();
+}
+
+interface ArgumentConstraintPhrases {
+ <error descr="'with(Matcher<T>)' clashes with 'with(Matcher<Boolean>)'; both methods have same erasure"><T> T with(Matcher<T> matcher)</error>;
+ boolean with(Matcher<Boolean> matcher);
+ byte with(Matcher<Byte> matcher);
+ short with(Matcher<Short> matcher);
+ int with(Matcher<Integer> matcher);
+ long with(Matcher<Long> matcher);
+ float with(Matcher<Float> matcher);
+ double with(Matcher<Double> matcher);
+}
+
+class ExpectationGroupBuilder implements ArgumentConstraintPhrases {
+
+ <error descr="'with(Matcher<T>)' clashes with 'with(Matcher<Boolean>)'; both methods have same erasure">public <T> T with(final Matcher<T> matcher)</error> {
+ return null;
+ }
+
+ public boolean with(final Matcher<Boolean> matcher) {
+ return false;
+ }
+
+ public byte with(final Matcher<Byte> matcher) {
+ return 0;
+ }
+
+ public short with(final Matcher<Short> matcher) {
+ return 0;
+ }
+
+ public int with(final Matcher<Integer> matcher) {
+ return 0;
+ }
+
+ public long with(final Matcher<Long> matcher) {
+ return 0;
+ }
+
+ public float with(final Matcher<Float> matcher) {
+ return 0;
+ }
+
+ public double with(final Matcher<Double> matcher) {
+ return 0;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SelectFromTypeParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SelectFromTypeParameter.java
new file mode 100644
index 0000000..79229dd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SelectFromTypeParameter.java
@@ -0,0 +1,16 @@
+import java.util.List;
+interface Builder<T> {
+ T build();
+}
+
+interface Test<D extends Test<D, X>, X> {
+ static interface TestBuilder<D extends Test<D, X>, X> extends Builder<D> {}
+}
+
+interface Algorithm<T, B extends Builder<T>> {}
+
+class SelectFromVariableType<X, T extends Test<T, X>>
+ implements Algorithm<T,<error descr="Cannot select from a type parameter">T</error>.TestBuilder<T, X>> {
+ List<T.TestBuilder<T, X>> b;
+ T.TestBuilder<T, X> b1;
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SelfRef.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SelfRef.java
new file mode 100644
index 0000000..e1f415c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SelfRef.java
@@ -0,0 +1,13 @@
+import java.util.*;
+class Node<K> {
+ List<Node<K>> getNodes() {
+ return null;
+ }
+
+ private static <T> int strongConnect(Node<T> currentNode) {
+ for (Node<T> dependantNode : currentNode.getNodes()) {
+ strongConnect(dependantNode);
+ }
+ return 0;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SpecificReturnType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SpecificReturnType.java
new file mode 100644
index 0000000..2edfece
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SpecificReturnType.java
@@ -0,0 +1,13 @@
+abstract class Field<D> {
+ public D getValue(){return null;}
+}
+
+class LabelField extends Field<Object> {
+ public Object getValue() { return null; }
+}
+interface MyInterface<D> {
+ D getValue();
+}
+
+class MyLabelField extends LabelField implements MyInterface<Object> {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/StaticImports.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/StaticImports.java
new file mode 100644
index 0000000..047391d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/StaticImports.java
@@ -0,0 +1,16 @@
+
+import static java.util.Arrays.asList;
+import static java.util.Arrays.sort;
+<warning descr="Unused import statement">import static java.util.Arrays.binarySearch;</warning>
+
+public class StaticImports {
+ {
+ asList(new Object[]{});
+ }
+
+ void method() {
+ sort(new long[0]);
+// sort< error descr="Cannot resolve method 'sort()'">()< /error>;
+ }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/StaticOverride.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/StaticOverride.java
new file mode 100644
index 0000000..d020968
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/StaticOverride.java
@@ -0,0 +1,8 @@
+import java.util.*;
+
+public class MyClass implements Comparator<String> {
+
+ <error descr="Static method 'compare(String, String)' in 'MyClass' cannot override instance method 'compare(T, T)' in 'java.util.Comparator'">public static int compare(String a, String b)</error> {
+ return 42;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperMethodCallWithErasure.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperMethodCallWithErasure.java
new file mode 100644
index 0000000..4bd51c0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperMethodCallWithErasure.java
@@ -0,0 +1,18 @@
+import java.util.Set;
+
+interface Interface {
+ void method(Set<?> s);
+}
+
+class SuperClass implements Interface {
+ public void method(Set s) {
+ // do nothing
+ }
+}
+
+class SubClass extends SuperClass {
+ public void method(Set s) {
+ super.method(s); //ERROR: Abstract method 'method(Set<?>)' cannot be accessed directly
+ }
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardIsNotWithinItsBound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardIsNotWithinItsBound.java
new file mode 100644
index 0000000..8035e37
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardIsNotWithinItsBound.java
@@ -0,0 +1,20 @@
+
+class TopGene<T> {
+}
+
+class MidRaw extends TopGene {
+}
+
+class BottomGene<T> extends MidRaw {
+}
+
+class GeneType<T extends TopGene<String>> {
+}
+
+class GeneUser {
+ public void success(GeneType<? extends BottomGene<String>> p) {
+ }
+
+ public void fail(GeneType<<error descr="Type parameter '? super BottomGene<String>' is not within its bound; should extend 'TopGene<java.lang.String>'">? super BottomGene<String></error>> p) {
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ThisAsAccessObject.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ThisAsAccessObject.java
new file mode 100644
index 0000000..ea3ecf0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ThisAsAccessObject.java
@@ -0,0 +1,9 @@
+class Outer {
+ private void foo() {}
+ class Inner extends Outer {
+ {
+ this.<error descr="'foo()' has private access in 'Outer'">foo</error>();
+ foo();
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgsOnRaw.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgsOnRaw.java
new file mode 100644
index 0000000..f8e48b2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgsOnRaw.java
@@ -0,0 +1,21 @@
+class GenericsTest {
+
+ static class SomeClass<U> {
+ public <T> T getX() {
+ return null;
+ }
+ public String f() {
+ return this.<String>getX();
+ }
+ }
+
+
+
+ public static void main(String[] args) {
+
+ String v1 = new SomeClass().<error descr="Type arguments given on a raw method"><String></error>getX();
+ String v2 = new SomeClass().f(); //
+
+ }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsGivenOnAnonymousClassCreation.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsGivenOnAnonymousClassCreation.java
new file mode 100644
index 0000000..249c3ae
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsGivenOnAnonymousClassCreation.java
@@ -0,0 +1,12 @@
+class C
+{
+ Object x = new <error descr="Anonymous class implements interface; cannot have type arguments"><Integer></error> D() { };
+ Object x1 = new <Integer> P() { };
+ Object x2 = new <Integer> U() { };
+ Object x3 = new <error descr="Anonymous class implements interface; cannot have type arguments"><Integer></error> I() { };
+ interface D{}
+ abstract class P {}
+}
+
+interface I {}
+class U {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsGivenOnRawType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsGivenOnRawType.java
new file mode 100644
index 0000000..09ff35b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsGivenOnRawType.java
@@ -0,0 +1,49 @@
+import java.util.List;
+class A<D> {
+ abstract class C<S> {
+ <T extends A> void foo(T.C<Integer> x) {
+ Integer bar = x.bar();
+ }
+
+ <T extends A> void foo1(A.C<error descr="Type arguments given on a raw type"><Integer></error> x) {
+ Integer bar = x.bar();
+ }
+
+ <T extends A> void foo2(A<String>.C<Integer> x) {
+ Integer bar = x.bar();
+ }
+
+ abstract S bar();
+ }
+}
+
+class A1 {
+ abstract class C<S> {
+ <T extends A1> void foo(T.C<Integer> x) {
+ Integer bar = x.bar();
+ }
+
+ <T extends A1> void foo1(A1.C<Integer> x) {
+ Integer bar = x.bar();
+ }
+
+ abstract S bar();
+ }
+}
+
+interface Builder<T> {
+ T build();
+}
+
+interface Test<D extends Test<D, X>, X> {
+ static interface TestBuilder<D extends Test<D, X>, X> extends Builder<D> {}
+}
+
+interface Algorithm<T, B extends Builder<T>> {}
+
+class SelectFromVariableType<X, T extends Test<T, X>>
+ implements Algorithm<T, <error descr="Cannot select from a type parameter">T</error>.TestBuilder<T, X>> {
+
+ List<T.TestBuilder<T, X>> b;
+ T.TestBuilder<T, X> b1;
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsOnRawType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsOnRawType.java
new file mode 100644
index 0000000..7f38140
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsOnRawType.java
@@ -0,0 +1,43 @@
+interface I{
+ <T extends Iterable<String>> void foo();
+}
+
+abstract class A<S> implements I {
+ public abstract <T extends Iterable<String>> void foo();
+ <T extends A> void bar(T x){
+ A a = null;
+ a.<Iterable<String>> foo();
+ x.<Iterable<String>> foo();
+ }
+}
+
+abstract class B<S> {
+ public abstract <T extends Iterable<String>> void foo();
+ <T extends B> void bar(T x){
+ B a = null;
+ a.<Iterable<String>>foo();
+ x.<Iterable<String>> foo();
+ }
+}
+
+abstract class C<S> {
+ public abstract <T extends Iterable<String>> void foo();
+ <T extends C & I> void bar(T x){
+ x.<Iterable<String>> foo();
+ }
+}
+
+//---------------------------------------------------------------
+interface I1 {
+ void foo();
+}
+
+
+abstract class B1<S> {
+ public abstract <T extends Iterable<String>> void foo();
+ <T extends B1 & I1> void bar(T x){
+ B1 a = null;
+ a.<Iterable<String>>foo();
+ x.<Iterable<String>>foo();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsOnRawType17.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsOnRawType17.java
new file mode 100644
index 0000000..f586b18
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeArgumentsOnRawType17.java
@@ -0,0 +1,43 @@
+interface I{
+ <T extends Iterable<String>> void foo();
+}
+
+abstract class A<S> implements I {
+ public abstract <T extends Iterable<String>> void foo();
+ <T extends A> void bar(T x){
+ A a = null;
+ a.<Iterable<String>> foo();
+ x.<Iterable<String>> foo();
+ }
+}
+
+abstract class B<S> {
+ public abstract <T extends Iterable<String>> void foo();
+ <T extends B> void bar(T x){
+ B a = null;
+ a.<error descr="Type arguments given on a raw method"><Iterable<String>></error> foo();
+ x.<Iterable<String>> foo();
+ }
+}
+
+abstract class C<S> {
+ public abstract <T extends Iterable<String>> void foo();
+ <T extends C & I> void bar(T x){
+ x.<Iterable<String>> foo();
+ }
+}
+
+//---------------------------------------------------------------
+interface I1 {
+ void foo();
+}
+
+
+abstract class B1<S> {
+ public abstract <T extends Iterable<String>> void foo();
+ <T extends B1 & I1> void bar(T x){
+ B1 a = null;
+ a.<error descr="Type arguments given on a raw method"><Iterable<String>></error> foo();
+ x.<Iterable<String>> foo();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeInference.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeInference.java
new file mode 100644
index 0000000..0156c75
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeInference.java
@@ -0,0 +1,95 @@
+import java.io.FileNotFoundException;
+import java.util.*;
+
+interface PrivilegedExceptionAction <E extends Exception> {
+ void run() throws E;
+}
+
+class AccessController {
+ public static <E extends Exception> Object doPrivileged(PrivilegedExceptionAction<E> action) throws E {
+ return null;
+ }
+}
+class Test {
+ public static void main(String[] args) {
+ try {
+ AccessController.doPrivileged(
+ new PrivilegedExceptionAction<FileNotFoundException>() {
+ public void run() throws FileNotFoundException {
+ }
+ });
+ } catch (FileNotFoundException f) {
+ }
+ }
+
+// @#@! mock JDK Class does not take params
+// static <T> T create(Class<T> t) throws InstantiationException, IllegalAccessException {
+// return t.newInstance();
+// }
+}
+
+//IDEADEV-6390
+class Printer<T> {
+ private final List<T> _elements;
+
+ private Printer(final Collection<? extends T> col) {
+ _elements = new ArrayList<T>(col);
+ }
+
+ public static <T> Printer<T> build(final Collection<? extends T> col) {
+ return new Printer<T>(col);
+ }
+
+ public static <T, S extends T> Printer<T> build(final S... elements) {
+ return new Printer<T>(Arrays.asList(elements));
+ }
+
+ public void print() {
+ for (final T element : _elements) {
+ System.out.println(element);
+ }
+
+ }
+
+ public static void main(final String[] args) {
+ final Printer<?> objects = build(Integer.valueOf(5), Boolean.TRUE, "A String!"); //this is OK
+ objects.print();
+ }
+
+}
+//end of IDEADEV-6390
+
+//IDEADEV-6738
+interface I1<P1 extends I1<P1,P2>, P2 extends I2<P1,P2>>{}
+interface I2<P1 extends I1<P1,P2>, P2 extends I2<P1,P2>>{}
+
+class C1 implements I1<C1,C2>{}
+class C2 implements I2<C1,C2>{}
+
+class U {
+ public static <P1 extends I1<P1,P2>, P2 extends I2<P1,P2>> P1 test(P1 p1) {
+ return null;
+ }
+ {
+ C1 c = new C1();
+ U.test(c); //this should be OK
+ }
+}
+//end of IDEADEV-6738
+
+///////////////////////////////////
+public class Err {
+ void f() {
+ Decl[] extensions = getExtensions(Decl.EXTENSION_POINT_NAME);
+ }
+
+ static <T> T[] getExtensions(List<T> tExtensionPointName) {
+ return null;
+ }
+
+ public static class Decl<K,V> {
+ public static List<Decl> EXTENSION_POINT_NAME = null;
+ }
+
+}
+/////////////////////////////////////
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParameterBoundVisibility.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParameterBoundVisibility.java
new file mode 100644
index 0000000..68c2337
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParameterBoundVisibility.java
@@ -0,0 +1,50 @@
+class A {
+ private int value = 1;
+
+ static class B<T extends A> {
+ void print(T t) {
+ System.out.println(t.<error descr="'value' has private access in 'A'">value</error>);
+ }
+ }
+}
+
+abstract class Foo<T extends Foo<T>> {
+ private int field;
+
+ public int bar(T t){
+ return t.<error descr="'field' has private access in 'Foo'">field</error>;
+ }
+}
+
+public class Bug {
+ // Idea incorrectly analyses this code with JDK 7
+ public <T extends Bug> void doit(T other) {
+ // Oops, was legal with JDK 6, no longer legal with JDK 7
+ other.<error descr="'mPrivate()' has private access in 'Bug'">mPrivate</error>();
+ // Redundant with JDK 6, not a redundant cast with JDK 7
+ ((Bug)other).mPrivate();
+ }
+
+ // Idea correctly analyses this code
+ public void doit2(SubClass other) {
+ // Not legal with JDK 6 or 7
+ other.<error descr="'mPrivate()' has private access in 'Bug'">mPrivate</error>();
+ // Not redundant with JDK 6 or 7
+ ((Bug)other).mPrivate();
+ }
+
+ private void mPrivate() {
+ }
+}
+
+class SubClass extends Bug {
+}
+
+class A67678
+{
+ private void foo(){}
+ <T extends A67678 & Cloneable> void bar(T x)
+ {
+ x.<error descr="'foo()' has private access in 'A67678'">foo</error>();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParameterBoundsList.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParameterBoundsList.java
new file mode 100644
index 0000000..506add0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParameterBoundsList.java
@@ -0,0 +1,33 @@
+class C<T extends Runnable&<error descr="Interface expected here">Exception</error>,U> {
+
+}
+
+class Stuff<X extends Stuff & Runnable> {
+ <T, V extends T & <error descr="Type parameter cannot be followed by other bounds">Runnable</error>> T method(V v) {
+ return null;
+ }
+
+ <T extends X & <error descr="Type parameter cannot be followed by other bounds">Runnable</error> & <error descr="Type parameter cannot be followed by other bounds">Comparable</error>> void f(T t) {
+
+ }
+
+ <T extends Stuff & Runnable & Comparable> void f2(T t) {
+
+ }
+ <T extends Runnable & Comparable> void f3(T t) {
+
+ }
+}
+
+////////////////
+public class TypeParameters {
+ class X {}
+ static <T extends X> void f(Class<T> t){}
+
+ static {
+ f(X.class);
+ }
+}
+class Typr {
+ <T extends TypeParameters.X> void f() {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParamsCyclicInference.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParamsCyclicInference.java
new file mode 100644
index 0000000..a560911
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeParamsCyclicInference.java
@@ -0,0 +1,2 @@
+class Test<<error descr="Cyclic inheritance involving 'T'"></error>T extends T> {}
+class Test1<<error descr="Cyclic inheritance involving 'T'"></error>T extends S, S extends T> {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeWithinItsWildcardBound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeWithinItsWildcardBound.java
new file mode 100644
index 0000000..47ecb3b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/TypeWithinItsWildcardBound.java
@@ -0,0 +1,317 @@
+public class WithingBounds {
+ interface I {
+ }
+ interface I1 {
+ }
+
+ void testE1() {
+ class A {
+ }
+ class B extends A {
+ }
+ class ToCheckExtends<TTT extends A> {
+ }
+
+ ToCheckExtends<? extends B> pr;
+ }
+
+ void testERec1() {
+ class A {
+ }
+ class B<K> extends A {
+ }
+ class C<Y>{}
+ class ToCheckExtends<TTT extends A> {
+ }
+
+ ToCheckExtends<<error descr="Type parameter '? extends C<? extends C>' is not within its bound; should extend 'A'">? extends C<? extends C></error>> pr;
+ ToCheckExtends<? extends B<? extends C>> pr1;
+ }
+
+
+ void testE2() {
+ class A {
+ }
+ class B {
+ }
+ class ToCheckExtends<TTT extends A> {
+ }
+
+ ToCheckExtends<<error descr="Type parameter '? extends B' is not within its bound; should extend 'A'">? extends B</error>> pr;
+ }
+
+ void testE22() {
+ class B {
+ }
+ class A extends B {
+ }
+ class ToCheckExtends<TTT extends A> {
+ }
+
+ ToCheckExtends<? extends B> pr;
+ }
+
+
+ void testE23() {
+ class A {
+ }
+ class ToCheckExtends<TTT extends A> {
+ }
+
+ ToCheckExtends<? extends I> pr;
+ }
+
+ void testE24() {
+ final class A {
+ }
+ class ToCheckExtends<TTT extends A> {
+ }
+
+ ToCheckExtends<<error descr="Type parameter '? extends I' is not within its bound; should extend 'A'">? extends I</error>> pr;
+ }
+
+
+ void testE25() {
+ class B {
+ void foo() {
+ this.<Iterable>bar();
+ }
+
+ <T extends Iterable<String>> void bar() {
+ }
+ }
+ }
+
+ void testE26() {
+ class A<T>{}
+ class B {
+ void foo() {
+ this.<A>bar();
+ }
+
+ <T extends A<String>> void bar() {
+ }
+ }
+ }
+
+ //---------------------------------
+
+ void testE3() {
+ class A {
+ }
+ class ToCheckExtends<TTT extends I> {
+ }
+
+ ToCheckExtends<? extends A> pr;
+ }
+
+ void testE4() {
+ final class A {
+ }
+ class ToCheckExtends<TTT extends I> {
+ }
+
+ ToCheckExtends<<error descr="Type parameter '? extends A' is not within its bound; should extend 'WithingBounds.I'">? extends A</error>> pr;
+ }
+
+ void testE5() {
+ final class A implements I {
+ }
+ class ToCheckExtends<TTT extends I> {
+ }
+
+ ToCheckExtends<? extends A> pr;
+ }
+
+
+ interface AInterface {
+ }
+ void testE6() {
+
+ class ToCheckExtends<TTT extends I> {
+ }
+
+ ToCheckExtends<? extends AInterface> pr;
+ }
+
+ //-----------------------------
+
+ void testS1() {
+ class A {
+ }
+ class B extends A {
+ }
+ class ToCheckExtends<TTT extends A> {
+ }
+
+ ToCheckExtends<? super B> pr;
+ }
+
+ void testS2() {
+ class A {
+ }
+ class B {
+ }
+ class ToCheckExtends<TTT extends A> {
+ }
+
+ ToCheckExtends<<error descr="Type parameter '? super B' is not within its bound; should extend 'A'">? super B</error>> pr;
+ }
+
+ void testS3() {
+ class A {
+ }
+ class B extends A {
+ }
+ class ToCheckExtends<TTT extends B> {
+ }
+
+ ToCheckExtends<<error descr="Type parameter '? super A' is not within its bound; should extend 'B'">? super A</error>> pr;
+ }
+
+ void testMisc() {
+ class A<T, S extends T> {}
+ class i {}
+ final class ii extends i {}
+
+ A<String, String> pr4;
+ A<Integer, <error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Integer'">String</error>> pr5;
+ A<String, ? extends String> pr51;
+ A<Integer, <error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Integer'">? extends String</error>> pr52;
+ A<String, ? super String> pr53;
+ A<ii, <error descr="Type parameter 'i' is not within its bound; should extend 'ii'">i</error>> pr54;
+ A<i, ii> pr55;
+ A<i, ? extends ii> pr56;
+ A<ii, ? extends i> pr57;
+ A<i, ? super ii> pr58;
+ A<ii, <error descr="Type parameter '? super i' is not within its bound; should extend 'ii'">? super i</error>> pr59;
+ A<i, <error descr="Type parameter '? extends A<i, i>' is not within its bound; should extend 'i'">? extends A<i, i></error>> pr510;
+ A<i, <error descr="Type parameter 'ii[]' is not within its bound; should extend 'i'">ii[]</error>> pr511;
+ A<i, ?> pr512;
+
+ A<?, ?> pr30;
+ A<?, <error descr="Type parameter 'i' is not within its bound; should extend '?'">i</error>> pr3;
+ A<? extends Object, i> pr330;
+ A<?, ? extends ii> pr2;
+ A<?, <error descr="Type parameter '? super String' is not within its bound; should extend '?'">? super String</error>> pr10;
+ A<?, <error descr="Type parameter 'A' is not within its bound; should extend '?'">A<?, ?></error>> pr31;
+ A<?, <error descr="Type parameter 'ii[]' is not within its bound; should extend '?'">ii[]</error>> pr32;
+ A<?, <error descr="Type parameter 'A' is not within its bound; should extend '?'">A<i, i></error>> pr33;
+
+ A<? extends i, i> pr6;
+ A<? extends ii, <error descr="Type parameter 'i' is not within its bound; should extend '? extends ii'">i</error>> pr6x1;
+ A<? extends i, ii> pr6x2;
+ A<? extends ii, ii> pr6x3;
+ A<? extends i, <error descr="Type parameter 'java.lang.Integer' is not within its bound; should extend '? extends i'">Integer</error>> pr8;
+
+ A<? extends i, <error descr="Type parameter '? extends String' is not within its bound; should extend '? extends i'">? extends String</error>> pr12;
+ A<? extends i, ? extends i> pr13;
+ A<? extends i, ? extends ii> pr14;
+ A<? extends ii, ? extends i> pr13x3;
+ A<? extends ii, ? extends ii> pr13x4;
+
+
+ A<? extends i, ? super i> pr19;
+ A<? extends i, ? super ii> pr110;
+ A<? extends ii, ? super ii> pr11x0;
+ A<? extends ii, <error descr="Type parameter '? super i' is not within its bound; should extend '? extends ii'">? super i</error>> pr111;
+
+ A<? extends i, ?> pr15;
+ A<? extends i, <error descr="Type parameter 'ii[]' is not within its bound; should extend '? extends i'">ii[]</error>> pr16;
+ A<? extends i, <error descr="Type parameter 'A' is not within its bound; should extend '? extends i'">A<?, ?></error>> pr17;
+ A<? extends i, <error descr="Type parameter 'A' is not within its bound; should extend '? extends i'">A<ii, ii></error>> pr18;
+ A<? extends ii, <error descr="Type parameter '? super String' is not within its bound; should extend '? extends ii'">? super String</error>> pr112;
+ A<? extends ii, <error descr="Type parameter '? super A<i, i>' is not within its bound; should extend '? extends ii'">? super A<i, i></error>> pr113;
+
+ A<? super i, i> pr701;
+ A<? super i, <error descr="Type parameter 'java.lang.String' is not within its bound; should extend '? super i'">String</error>> pr72;
+ A<? super i, ?> pr73;
+ A<? super i, <error descr="Type parameter 'ii[]' is not within its bound; should extend '? super i'">ii[]</error>> pr74;
+ A<? super i, <error descr="Type parameter '? extends String' is not within its bound; should extend '? super i'">? extends String</error>> pr75;
+ A<? super i, ? extends i> pr76;
+ A<? super ii, ? extends i> pr77;
+ A<? super ii, ? extends ii> pr78;
+ A<? super i, ? super i> pr79;
+ A<? super i, ? super ii> pr791;
+ A<? super ii, ? super ii> pr713;
+ A<? super i, <error descr="Type parameter '? super String' is not within its bound; should extend '? super i'">? super String</error>> pr712;
+ A<? super ii, <error descr="Type parameter '? super i' is not within its bound; should extend '? super ii'">? super i</error>> pr710;
+ A<? super ii, <error descr="Type parameter 'i' is not within its bound; should extend '? super ii'">i</error>> pr70;
+ A<? super i, ii> pr71;
+ A<? super i, ? extends ii> pr711;
+
+ A<i[], i[]> a1;
+ A<i[], <error descr="Type parameter 'java.lang.Object' is not within its bound; should extend 'i[]'">Object</error>> a2;
+ A<i[], ii[]> a3;
+ A<ii[], <error descr="Type parameter 'i[]' is not within its bound; should extend 'ii[]'">i[]</error>> a4;
+
+ A<i[], <error descr="Type parameter 'int[]' is not within its bound; should extend 'i[]'">int[]</error>> a5;
+ A<Object, int[]> a6;
+ A<Cloneable, int[]> a7;
+ A<java.io.Serializable, int[]> a8;
+ A<Cloneable[], <error descr="Type parameter 'int[]' is not within its bound; should extend 'java.lang.Cloneable[]'">int[]</error>> a9;
+ A<Cloneable[], int[][]> a10;
+ A<Cloneable[][], int[][][]> a11;
+ A<Cloneable[], <error descr="Type parameter 'i[]' is not within its bound; should extend 'java.lang.Cloneable[]'">i[]</error>> a12;
+ A<Cloneable[], i[][]> a13;
+
+ A<? super i[], ii[]> a14;
+ A<? super i[], i[]> a140;
+ A<? super ii[], <error descr="Type parameter 'i[]' is not within its bound; should extend '? super ii[]'">i[]</error>> a141;
+ A<? super i[], <error descr="Type parameter 'i' is not within its bound; should extend '? super i[]'">i</error>> a142;
+ A<? super i[], <error descr="Type parameter 'java.lang.String' is not within its bound; should extend '? super i[]'">String</error>> a143;
+ A<? super i[], <error descr="Type parameter 'i[][]' is not within its bound; should extend '? super i[]'">i[][]</error>> a144;
+ A<? super i[], ? extends i[]> a145;
+ A<? super i[], ? extends ii[]> a146;
+ A<? super ii[], ? extends i[]> a147;
+ A<? super i[], <error descr="Type parameter '? extends i' is not within its bound; should extend '? super i[]'">? extends i</error>> a148;
+ A<? super i[], <error descr="Type parameter '? extends String' is not within its bound; should extend '? super i[]'">? extends String</error>> a149;
+ A<? super i[], ?> a1410;
+ A<? super i[], <error descr="Type parameter '? extends i[][]' is not within its bound; should extend '? super i[]'">? extends i[][]</error>> a1411;
+ A<? super i[], ? super i[]> a1412;
+ A<? super i[], ? super ii[]> a1413;
+ A<? super ii[], <error descr="Type parameter '? super i[]' is not within its bound; should extend '? super ii[]'">? super i[]</error>> a1414;
+ A<? super i[], <error descr="Type parameter '? super i' is not within its bound; should extend '? super i[]'">? super i</error>> a1415;
+ A<? super i[], <error descr="Type parameter '? super String' is not within its bound; should extend '? super i[]'">? super String</error>> a1416;
+ A<? super i[], <error descr="Type parameter '? super i[][]' is not within its bound; should extend '? super i[]'">? super i[][]</error>> a1417;
+
+ A<? extends i[], ii[]> a15;
+ A<? extends i[], i[]> a150;
+ A<? extends ii[],<error descr="Type parameter 'i[]' is not within its bound; should extend '? extends ii[]'">i[]</error>> a151;
+ A<? extends i[], <error descr="Type parameter 'i' is not within its bound; should extend '? extends i[]'">i</error>> a152;
+ A<? extends i[], <error descr="Type parameter 'java.lang.String' is not within its bound; should extend '? extends i[]'">String</error>> a153;
+ A<? extends i[], <error descr="Type parameter 'i[][]' is not within its bound; should extend '? extends i[]'">i[][]</error>> a154;
+ A<? extends i[], ? extends i[]> a155;
+ A<? extends i[], ? extends ii[]> a156;
+ A<? extends ii[], ? extends i[]> a157;
+ A<? extends i[], <error descr="Type parameter '? extends i' is not within its bound; should extend '? extends i[]'">? extends i</error>> a158;
+ A<? extends i[], <error descr="Type parameter '? extends String' is not within its bound; should extend '? extends i[]'">? extends String</error>> a159;
+ A<? extends i[], ?> a1510;
+ A<? extends i[], <error descr="Type parameter '? extends i[][]' is not within its bound; should extend '? extends i[]'">? extends i[][]</error>> a1511;
+ A<? extends i[], ? super i[]> a1512;
+ A<? extends i[], ? super ii[]> a1513;
+ A<? extends ii[], <error descr="Type parameter '? super i[]' is not within its bound; should extend '? extends ii[]'">? super i[]</error>> a1514;
+ A<? extends i[], <error descr="Type parameter '? super i' is not within its bound; should extend '? extends i[]'">? super i</error>> a1515;
+ A<? extends i[], <error descr="Type parameter '? super String' is not within its bound; should extend '? extends i[]'">? super String</error>> a1516;
+ A<? extends i[], <error descr="Type parameter '? super i[][]' is not within its bound; should extend '? extends i[]'">? super i[][]</error>> a1517;
+
+ A<? extends Cloneable, ? extends i[]> a16;
+ A<? extends Cloneable[], ? extends i[][]> a160;
+ A<Cloneable, ? extends i[]> a161;
+ A<? super Cloneable, ? extends i[]> a162;
+ A< I1[], ? extends I[]> cl;
+
+ }
+
+ void testRawTypes() {
+ class A<T extends A<T>> {}
+ A a;
+ A<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'A<java.lang.String>'">String</error>> a1;
+ A<<error descr="Type parameter 'A' is not within its bound; should extend 'A<A>'">A</error>> a2;
+ A<A<<error descr="Type parameter 'A' is not within its bound; should extend 'A<A>'">A</error>>> a3;
+
+ A<? extends A> a4;
+ A<<error descr="Type parameter '? super A' is not within its bound; should extend 'A<? super A>'">? super A</error>> a5;
+ A<<error descr="Type parameter 'A[]' is not within its bound; should extend 'A<A[]>'">A[]</error>> a7;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedCasts.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedCasts.java
new file mode 100644
index 0000000..0532d1f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedCasts.java
@@ -0,0 +1,108 @@
+import java.util.*;
+
+class X<<warning descr="Type parameter 'T' is never used">T</warning>> {
+
+}
+
+class XX<T> extends X<T> {
+ Object f(X<String> x) {
+ if (x != null) {
+ XX<String> xx = <warning descr="Unchecked cast: 'XX' to 'XX<java.lang.String>'">(XX<String>)new XX()</warning>;
+ return xx;
+ }
+ if (1 == 1) {
+ XX<String> xx = (XX<String>)x;
+ return xx;
+ }
+ return null;
+ }
+}
+
+class eee<COMP extends eee> {
+ COMP comp;
+ COMP foo() {
+ return <warning descr="Unchecked cast: 'eee' to 'COMP'">(COMP) new eee()</warning>;
+ }
+}
+
+class AllPredicate<T>
+ {
+ private List<Set<? super T>> lists;
+
+ public void e(AllPredicate that)
+ {
+ lists = <warning descr="Unchecked cast: 'java.util.List' to 'java.util.List<java.util.Set<? super T>>'">(List<Set<? super T>>)that.lists</warning>;
+ }
+
+ public static List<String> fff() {
+ Collection<String> c = new ArrayList<String>();
+ return (List<String>) c; //not unchecked
+ }
+
+ public static Comparable<Object> ggg() {
+ Object time = new Object();
+ return <warning descr="Unchecked cast: 'java.lang.Object' to 'java.lang.Comparable<java.lang.Object>'">(Comparable<Object>) time</warning>;
+ }
+
+ public static void foo(SortedMap<?, ?> sourceSortedMap) {
+ new TreeMap<Object, Object>(<warning descr="Unchecked cast: 'java.util.Comparator<capture<?>>' to 'java.util.Comparator<? super java.lang.Object>'">(Comparator<? super Object>) sourceSortedMap.comparator()</warning>);
+ }
+}
+
+class K { }
+class L extends K { }
+class M {
+ public static <T extends K> L f(T t) {
+ return (L) t; //this should NOT generate unchecked cast
+ }
+}
+
+class UncheckedCastFalsePositive {
+
+ public static void method(Object something) {
+ if (something instanceof NumberList) {
+ NumberList<? extends Number> <warning descr="Variable 'numberList' is never used">numberList</warning> = (NumberList<? extends Number>) something;
+ }
+
+ }
+
+ public static class NumberList<E extends Number> extends ArrayList<E> {
+ }
+
+}
+
+class IDEA21547 {
+ class O {}
+ class A<<warning descr="Type parameter 'T' is never used">T</warning>> {}
+ class B<K extends O> extends A<K>{}
+
+ public void bar(A<? extends O> a, B<O> b) {
+ b = <warning descr="Unchecked cast: 'IDEA21547.A<capture<? extends IDEA21547.O>>' to 'IDEA21547.B<IDEA21547.O>'">(B<O>)a</warning>;
+ System.out.println(b);
+ }
+
+ public void bar1(A<?> a, B<O> b) {
+ b = <warning descr="Unchecked cast: 'IDEA21547.A<capture<?>>' to 'IDEA21547.B<IDEA21547.O>'">(B<O>)a</warning>;
+ System.out.println(b);
+ }
+
+ public void bar2(A<?> a, B<?> b) {
+ b = <warning descr="Unchecked cast: 'IDEA21547.A<capture<?>>' to 'IDEA21547.B<IDEA21547.O>'">(B<O>)a</warning>;
+ System.out.println(b);
+ }
+
+ public void bar4(A<? extends O> a, B<?> b) {
+ b = <warning descr="Unchecked cast: 'IDEA21547.A<capture<? extends IDEA21547.O>>' to 'IDEA21547.B<IDEA21547.O>'">(B<O>)a</warning>;
+ System.out.println(b);
+ }
+
+ public void bar5(A<? super O> a, B<?> b) {
+ b = <warning descr="Unchecked cast: 'IDEA21547.A<capture<? super IDEA21547.O>>' to 'IDEA21547.B<IDEA21547.O>'">(B<O>)a</warning>;
+ System.out.println(b);
+ }
+
+ public void bar6(A a, B<?> b) {
+ b = <warning descr="Unchecked cast: 'IDEA21547.A' to 'IDEA21547.B<IDEA21547.O>'">(B<O>)a</warning>;
+ System.out.println(b);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedOverriding.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedOverriding.java
new file mode 100644
index 0000000..9f71e16b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedOverriding.java
@@ -0,0 +1,45 @@
+class List<T> { T t;}
+
+class Base<T> {
+ List<T> getList(List<T> l) {
+ return null;
+ }
+
+
+}
+
+class Derived extends Base <String> {
+ <warning descr="Unchecked overriding: return type requires unchecked conversion. Found 'List', required 'List<java.lang.String>'">List</warning> getList(List<String> l) {
+ return null;
+ }
+}
+
+class A1 {
+ <T> T foo(T t) {
+ return null;
+ }
+}
+
+class A2 extends A1 {
+ <warning descr="Unchecked overriding: return type requires unchecked conversion. Found 'java.lang.Object', required 'T'">Object</warning> foo(Object o) {
+ return null;
+ }
+}
+
+//IDEADEV-15918
+abstract class Outer<U> {
+ public abstract Inner m(U u);
+
+ public class Inner {
+ }
+}
+
+class Other extends Outer<Other> {
+ public Ither m(Other other) {
+ return new Ither();
+ }
+
+ public class Ither extends Inner {
+ }
+}
+//end of IDEADEV-15918
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedWarningsLevel6.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedWarningsLevel6.java
new file mode 100644
index 0000000..e9ff21b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/UncheckedWarningsLevel6.java
@@ -0,0 +1,128 @@
+import java.lang.Override;
+import java.util.*;
+class GenericsTest<T> {
+
+ static <S> S next(GenericsTest<S> test)
+ {
+ System.out.println(test);
+ return null;
+ }
+
+ public Iterator<T> iterator()
+ {
+ return new Iterator<T>() {
+ @Override
+ public boolean hasNext()
+ {
+ return false;
+ }
+
+ @Override
+ public T next()
+ {
+ return GenericsTest.next(GenericsTest.this);
+ }
+
+ @Override
+ public void remove()
+ {
+ }
+ };
+ }
+}
+
+class GenericsTest1<T> {
+
+ static <S> S next1(GenericsTest1<S> test)
+ {
+ System.out.println(test);
+ return null;
+ }
+
+ public Iterator<T> iterator()
+ {
+ return new Iterator<T>() {
+ @Override
+ public boolean hasNext()
+ {
+ return false;
+ }
+
+ @Override
+ public T next()
+ {
+ return GenericsTest1.next1(GenericsTest1.this);
+ }
+
+ @Override
+ public void remove()
+ {
+ }
+ };
+ }
+}
+
+
+class GenericsTest2<T> {
+
+ static <S> S next2(GenericsTest2<S> test)
+ {
+ System.out.println(test);
+ return null;
+ }
+
+ public Iterator<T> iterator()
+ {
+ return new Iterator<T>() {
+ @Override
+ public boolean hasNext()
+ {
+ return false;
+ }
+
+ @Override
+ public T next()
+ {
+ return next2(GenericsTest2.this);
+ }
+
+ @Override
+ public void remove()
+ {
+ }
+ };
+ }
+}
+class Example {
+ private static <T> void assertThat(T actual, Matcher<? super T> matcher) {
+ assert actual != null;
+ assert matcher != null;
+ }
+
+ private static <E> Matcher<? super Collection<? extends E>> hasSize(int size) {
+ assert size >=0;
+ return new Matcher<Collection<? extends E>>() {
+ @Override
+ public void foo(Collection<? extends E> es) {
+ System.out.println(es);
+ }
+ };
+ }
+
+ public static void main(String[] args) {
+ List<Boolean> list = <warning descr="Unchecked assignment: 'java.util.ArrayList' to 'java.util.List<java.lang.Boolean>'">new ArrayList()</warning>;
+ System.out.println(list);
+ assertThat(new ArrayList<Boolean>(), hasSize(0));
+ }
+
+ private interface Matcher<T> {
+ void foo(T t);
+ }
+}
+
+abstract class IDEA57337<<warning descr="Type parameter 'S' is never used">S</warning>> {
+ abstract <T> void foo(IDEA57337<? super IDEA57337<T>> x);
+ void bar(IDEA57337<? super IDEA57337<?>> x){
+ foo(x);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Unused.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Unused.java
new file mode 100644
index 0000000..7b75df1
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Unused.java
@@ -0,0 +1,11 @@
+enum e {
+ A("xxx");
+
+ private String s;
+ e(String str) {
+ s = str;
+ }
+ public String getS() {
+ return s;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Varargs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Varargs.java
new file mode 100644
index 0000000..5ba94fb
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Varargs.java
@@ -0,0 +1,33 @@
+class clazz1 {
+ clazz1(int... args) { args = null; }
+ public static class Myclazz1 extends clazz1 {}
+}
+
+class AmbiguousReference {
+ void test() {
+ doSomething<error descr="Ambiguous method call: both 'AmbiguousReference.doSomething(String, Number...)' and 'AmbiguousReference.doSomething(Number...)' match">(null, 1)</error>;
+ }
+
+ void doSomething(String s, Number... n) {
+ s+=n;
+ }
+
+ void doSomething(Number... n) {
+ n.hashCode();
+ }
+}
+
+class OK {
+ protected void fff() {
+ find("");
+ }
+ public void find(String queryString) {
+ queryString.hashCode();
+ }
+
+ public void find(final String queryString, final Object... values) {
+ queryString.hashCode();
+ values.hashCode();
+ }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Variance.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Variance.java
new file mode 100644
index 0000000..67f89f9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Variance.java
@@ -0,0 +1,285 @@
+import java.util.*;
+import java.util.Comparator;
+
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dsl
+ * Date: Mar 25, 2004
+ * Time: 8:08:44 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class VarianceTesting {
+ void method(List<? extends VarianceTesting> l) {
+// l.add(new VarianceTesting());
+ l.add(null);
+ }
+
+ static void shuffle(Collection<?> c) {}
+
+ static class X<T> {
+ T field;
+ T[] arrayField;
+ T[] method() {return arrayField;};
+ void putAll(Collection<? super T> c) {}
+ }
+
+ void method1(List<? super VarianceTesting> l) {
+ List<? extends VarianceTesting> l1 = new ArrayList<VarianceTesting>();
+ l1.add<error descr="'add(capture<? extends VarianceTesting>)' in 'java.util.List' cannot be applied to '(VarianceTesting)'">(new VarianceTesting())</error>;
+ List<List<? extends VarianceTesting>> lll = null;
+ lll.add(l1);
+ X<? extends VarianceTesting> x = new X<VarianceTesting>();
+ VarianceTesting z = x.field;
+ VarianceTesting[] v = x.arrayField;
+ VarianceTesting v1 = x.arrayField[0];
+ x.arrayField[0] = new VarianceTesting();
+ <error descr="Incompatible types. Found: 'VarianceTesting', required: 'capture<? extends VarianceTesting>'">x.field = new VarianceTesting()</error>;
+ VarianceTesting[] k = x.method();
+ k[0] = new VarianceTesting();
+ x.method()[0] = new VarianceTesting();
+ <error descr="Incompatible types. Found: 'VarianceTesting[]', required: 'capture<? extends VarianceTesting>[]'">x.arrayField = new VarianceTesting[10]</error>;
+ l1.addAll<error descr="'addAll(java.util.Collection<capture<? extends VarianceTesting>>)' in 'java.util.List' cannot be applied to '(java.util.ArrayList<VarianceTesting>)'">(new ArrayList<VarianceTesting>())</error>;
+ <error descr="Incompatible types. Found: 'java.util.ArrayList<java.lang.String>', required: 'java.util.List<? extends VarianceTesting>'">List<? extends VarianceTesting> l2 = new ArrayList<String>();</error>
+ List<? extends VarianceTesting> l3 = l2;
+ VarianceTesting t = l1.get(0);
+ l.add(new VarianceTesting());
+ l.add(null);
+ <error descr="Incompatible types. Found: 'java.lang.Object', required: 'VarianceTesting'">VarianceTesting t1 = l.get(0);</error>
+ X<? extends VarianceTesting> x1 = null;
+ x1.putAll(new ArrayList<VarianceTesting>());
+ List<?> unknownlist = l;
+ List<?> unknownlist1 = new ArrayList<VarianceTesting>();
+ List<?> unknownlist2 = new ArrayList<<error descr="Wildcard type '?' cannot be instantiated directly">?</error>>();
+ shuffle(l);
+ shuffle(new ArrayList<VarianceTesting>());
+ List<VarianceTesting> lllll = new ArrayList<VarianceTesting>();
+ lllll.removeAll(new ArrayList<String>());
+ }
+
+}
+
+class SuperTester <U> {
+ void go(Acceptor<? super U> acceptor, U u) {
+ acceptor.accept<error descr="'accept(SuperTester<capture<? super U>>, capture<? super U>)' in 'SuperTester.Acceptor' cannot be applied to '(SuperTester<U>, U)'">(this, u)</error>;
+ }
+
+ static class Acceptor <V> {
+ void accept(SuperTester<V> tester, V v) { }
+ }
+}
+
+class SCR40202 {
+ void foo(Map<?, String> map) {
+ for (<error descr="Incompatible types. Found: 'java.util.Iterator<java.util.Map.Entry<capture<?>,java.lang.String>>', required: 'java.util.Iterator<java.util.Map.Entry<?,java.lang.String>>'">Iterator<Map.Entry<?, String>> it = map.entrySet().iterator();</error> it.hasNext();) {
+
+ }
+ }
+}
+
+class CaptureTest {
+ static class Emum<T> {
+ T t;
+ public static <T extends Emum<T>> T valueOf(Class<T> enumType,
+ String name) {
+ return null;
+ }
+ }
+
+ void foo (Class<? extends Emum<CaptureTest>> clazz) {
+ Emum.valueOf<error descr="'valueOf(java.lang.Class<T>, java.lang.String)' in 'CaptureTest.Emum' cannot be applied to '(java.lang.Class<capture<? extends CaptureTest.Emum<CaptureTest>>>, java.lang.String)'">(clazz, "CCC")</error>;
+ }
+}
+
+class SuperTest {
+ public List<List<? extends SuperTest>> waitingList;
+
+ public Comparator<List<?>> SIZE_COMPARATOR;
+
+ {
+ //This call has its type arguments inferred alright: T -> List<capture<? extends SuperTest>>
+ Collections.sort(waitingList, SIZE_COMPARATOR);
+ }
+}
+
+class Bug<A> {
+ static class B<C> {
+ }
+
+ static class D<E> {
+ B<E> f() {
+ return null;
+ }
+ }
+
+ <G extends A> void h(B<G> b) {
+ }
+
+ void foo(D<? extends A> d) {
+ h(d.f()); //This call is OK as a result of reopening captured wildcard for calling "h"
+ }
+}
+
+//IDEA-4215
+class Case2 {
+ class A {}
+
+ class B extends A {}
+
+ Comparator<A> aComparator;
+ Case2() {
+
+ ArrayList<B> blist = new ArrayList<B>();
+
+ // this call is OK: T -> B
+ Collections.sort(blist, aComparator);
+ }
+}
+
+class S1 {
+ <T> void f(List<T> l1, T l2) {
+
+ }
+
+ void bar(List<? extends S1> k) {
+ f<error descr="'f(java.util.List<capture<? extends S1>>, capture<? extends S1>)' in 'S1' cannot be applied to '(java.util.List<capture<? extends S1>>, S1)'">(k, k.get(0))</error>;
+ }
+}
+
+class S2 {
+ <T> void f(List<T> l1, List<T> l2) {
+
+ }
+
+ void bar(List<? extends S2> k) {
+ f<error descr="'f(java.util.List<T>, java.util.List<T>)' in 'S2' cannot be applied to '(java.util.List<capture<? extends S2>>, java.util.List<capture<? extends S2>>)'">(k, k)</error>;
+ }
+}
+
+class S3 {
+ <T> void f(Map<T,T> l2) {
+
+ }
+
+ void bar(Map<? extends S3, ? extends S3> k) {
+ f<error descr="'f(java.util.Map<T,T>)' in 'S3' cannot be applied to '(java.util.Map<capture<? extends S3>,capture<? extends S3>>)'">(k)</error>;
+ }
+}
+
+class TypeBug {
+ private static class ValueHolder<T> {
+ public T value;
+ }
+
+ public static void main(final String[] args) {
+ List<ValueHolder<?>> multiList = new ArrayList<ValueHolder<?>>();
+
+ ValueHolder<Integer> intHolder = new ValueHolder<Integer>();
+ intHolder.value = 1;
+
+ ValueHolder<Double> doubleHolder = new ValueHolder<Double>();
+ doubleHolder.value = 1.5;
+
+ multiList.add(intHolder);
+ multiList.add(doubleHolder);
+ swapFirstTwoValues<error descr="'swapFirstTwoValues(java.util.List<TypeBug.ValueHolder<T>>)' in 'TypeBug' cannot be applied to '(java.util.List<TypeBug.ValueHolder<?>>)'">(multiList)</error>; //need to be highlighted
+
+ // this line causes a ClassCastException when checked.
+ Integer value = intHolder.value;
+ System.out.println(value);
+ }
+
+ private static <T> void swapFirstTwoValues(List<ValueHolder<T>> multiList) {
+ ValueHolder<T> intHolder = multiList.get(0);
+ ValueHolder<T> doubleHolder = multiList.get(1);
+
+ intHolder.value = doubleHolder.value;
+ }
+}
+
+class OtherBug {
+public static void foo(List<? extends Foo> foos) {
+ final Comparator<Foo> comparator = createComparator();
+ Collections.sort(foos, comparator); //this call is OK
+ }
+
+ private static Comparator<Foo> createComparator() {
+ return null;
+ }
+
+ public interface Foo {
+ }
+}
+
+class OtherBug1 {
+ public static void foo(List<? super Foo> foos) {
+ final Comparator<Foo> comparator = createComparator();
+ Collections.sort<error descr="'sort(java.util.List<capture<? super OtherBug1.Foo>>, java.util.Comparator<capture<? super OtherBug1.Foo>>)' in 'java.util.Collections' cannot be applied to '(java.util.List<capture<? super OtherBug1.Foo>>, java.util.Comparator<OtherBug1.Foo>)'">(foos, comparator)</error>;
+ }
+
+ private static Comparator<Foo> createComparator() {
+ return null;
+ }
+
+ public interface Foo {
+ }
+}
+
+//IDEADEV-7187
+class AA <B extends AA<B,C>, C extends AA<C, ?>>{}
+//end of IDEADEV-7187
+
+//IDEADEV-8697
+class GenericTest99<E extends GenericTest99<E, F>,F> {
+}
+class GenericTest99D<E extends GenericTest99D<E>> extends GenericTest99<E,Double> {
+}
+class Use99<U extends GenericTest99<?,F>,F> {
+}
+class Use99n extends Use99<GenericTest99D<?>,Double> {
+}
+//end of IDEADEV-8697
+
+class IDEA79360 {
+ public static void main(Map<?, ?> map, Map<Object, Object> test) {
+ map.putAll<error descr="'putAll(java.util.Map<capture<?>,capture<?>>)' in 'java.util.Map' cannot be applied to '(java.util.Map<java.lang.Object,java.lang.Object>)'">(test)</error>;
+ map.put<error descr="'put(capture<?>, capture<?>)' in 'java.util.Map' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ map.put<error descr="'put(capture<?>, capture<?>)' in 'java.util.Map' cannot be applied to '(java.lang.Object, java.lang.Object)'">(new Object(), new Object())</error>;
+ map = new HashMap<Object, Object>(test);
+ }
+}
+
+class GenericFailureExample {
+
+ interface Descriptor<T extends Comparable<T>> {
+ Class<T> getType();
+ }
+
+ void isMarkedFaultyButCompilesClean(Descriptor<?> n) {
+ bar(n.getType());
+ }
+
+ <T extends Comparable<T>> void butThisWorks(Descriptor<T> n) {
+ bar(n.getType());
+ }
+
+ <T extends Comparable<T>> Comparator<T> bar(Class<T> type) {
+ return null;
+ }
+}
+
+//IDEA-67675
+abstract class A67675<T>
+{
+ abstract T foo();
+}
+
+abstract class B67675<T> extends A67675<T[]> { }
+
+class C67675<T extends B67675<?>>
+{
+ void foo(T x)
+ {
+ x.foo()[0] = "";
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WideningCastToTypeParam.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WideningCastToTypeParam.java
new file mode 100644
index 0000000..7615d72
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WideningCastToTypeParam.java
@@ -0,0 +1,51 @@
+import java.lang.Double;
+
+interface IConverter<C> {
+}
+
+abstract class AbstractNumberConverter<N extends Number> implements IConverter<N> {
+}
+
+class DoubleConverter extends AbstractNumberConverter<Double> {
+}
+
+public class Test {
+ public static <C> IConverter<C> getConverter(Class<C> type) {
+ return (IConverter<C>)new DoubleConverter() {
+ };
+ }
+
+ public static <C extends String> IConverter<C> getConverter1(Class<C> type) {
+ return <error descr="Inconvertible types; cannot cast 'DoubleConverter' to 'IConverter<C>'">(IConverter<C>)new DoubleConverter() {
+ }</error>;
+ }
+
+ public static <C extends Double> IConverter<C> getConverter2(Class<C> type) {
+ return (IConverter<C>)new DoubleConverter() {
+ };
+ }
+
+ public static void main(String[] args) {
+ IConverter<String> converter = getConverter(String.class);
+ IConverter<String> converter1 = getConverter1(String.class);
+ IConverter<String> converter2 = <error descr="Inferred type 'java.lang.String' for type parameter 'C' is not within its bound; should extend 'java.lang.Double'">getConverter2(String.class)</error>;
+ }
+}
+
+
+class Z {
+
+}
+
+class TestNonNarrowingConversion<T extends Z> {
+ public TestNonNarrowingConversion(T u) {
+
+ }
+
+ public T z = null;
+
+ public int a() {
+ <error descr="Incompatible types. Found: 'TestNonNarrowingConversion<Z>', required: 'TestNonNarrowingConversion<T>'">TestNonNarrowingConversion<T> x = new TestNonNarrowingConversion<Z>(new Z());</error>
+ return 1;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardCastConversion.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardCastConversion.java
new file mode 100644
index 0000000..f610bac
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardCastConversion.java
@@ -0,0 +1,548 @@
+public class Test {
+ interface A {}
+ interface B {}
+
+ //? extends A, ? extends B -----------------------------------------
+ void testEE1() {
+ class A {}
+ class B {}
+
+ W<? extends A> xx = null;
+ W<? extends B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A>>' to 'W<? extends B>'">(W<? extends B>) xx</error>;
+ }
+
+ void testEE2() {
+ class A {}
+ class B extends A {}
+
+ W<? extends A> xx = null;
+ W<? extends B> y = (W<? extends B>) xx;
+ }
+
+ void testEE21() {
+ class A {}
+ class B extends A {}
+
+ W<? extends B> xx = null;
+ W<? extends A> y = (W<? extends A>) xx;
+ }
+
+ void testEE211() {
+ class A {}
+ final class B extends A {}
+
+ W<? extends A> xx = null;
+ W<? extends B> y = (W<? extends B>) xx;
+ }
+
+ void test3EE() {
+ W<? extends A> xx = null;
+ W<? extends B> y = (W<? extends B>) xx;
+ }
+
+ void test4EE() {
+ class A {}
+ W<? extends A> xx = null;
+ W<? extends B> y = (W<? extends B>) xx;
+ }
+
+ void test41EE() {
+ class A {}
+ W<? extends B> xx = null;
+ W<? extends A> y = (W<? extends A>) xx;
+ }
+
+ void test411EE() {
+ final class A {}
+ W<? extends B> xx = null;
+ W<? extends A> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends Test.B>>' to 'W<? extends A>'">(W<? extends A>) xx</error>;
+ }
+
+ void test412EE() {
+ final class A implements B {}
+ W<? extends B> xx = null;
+ W<? extends A> y = (W<? extends A>) xx;
+ }
+
+ void test1() {
+ class A {}
+ class B {}
+
+ W<? super A> xx = null;
+ W<? super B> y = (W<? super B>) xx;
+ }
+
+ void test2() {
+ final class A {}
+ final class B {}
+
+ W<? super A> xx = null;
+ W<? super B> y = (W<? super B>) xx;
+ }
+
+ //? super A, ? super B -------------------------
+ void test3SS() {
+ W<? super A> xx = null;
+ W<? super B> y = (W<? super B>) xx;
+ }
+
+ //? extends A, ? super B -------------------------
+ void test1ES() {
+ class A {}
+ class B {}
+
+ W<? extends A> x = null;
+ W<? super B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A>>' to 'W<? super B>'">(W<? super B>) x</error>;
+ }
+
+ void test2ES() {
+ class A {}
+ class B extends A {}
+
+ W<? extends A> x = null;
+ W<? super B> y = (W<? super B>) x;
+ }
+
+ void test3ES() {
+ class A {}
+ class B extends A {}
+
+ W<? extends B> x = null;
+ W<? super A> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends B>>' to 'W<? super A>'">(W<? super A>) x</error>;
+ }
+
+
+ void test4ES() {
+ W<? extends B> x = null;
+ W<? super A> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends Test.B>>' to 'W<? super Test.A>'">(W<? super A>) x</error>;
+ }
+
+ void test5ES() {
+ final class B implements A {}
+
+ W<? extends A> x = null;
+ W<? super B> y = (W<? super B>) x;
+ }
+
+ void test6ES() {
+ final class B implements A {}
+
+ W<? extends B> x = null;
+ W<? super A> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends B>>' to 'W<? super Test.A>'">(W<? super A>) x</error>;
+ }
+
+ // ? extends A, B -----------------------
+ void test1EWC() {
+ class A {
+ }
+ class B {
+ }
+
+ W<? extends A> xx = null;
+ W<B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A>>' to 'W<B>'">(W<B>) xx</error>;
+ }
+
+ void test2EWC() {
+ class A {
+ }
+
+ W<? extends A> xx = null;
+ W<?> y = (W<?>) xx;
+ }
+
+ void test3EWC() {
+ class A {
+ }
+ class B extends A {
+ }
+
+ W<? extends A> xx = null;
+ W<B> y = (W<B>) xx;
+ }
+
+ // ? super A, B -----------------------
+ void test1SWC() {
+ class A {
+ }
+ class B {
+ }
+
+ W<? super A> xx = null;
+ W<B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? super A>>' to 'W<B>'">(W<B>) xx</error>;
+ }
+
+ void test2SWC() {
+ class A {
+ }
+
+ W<? super A> xx = null;
+ W<?> y = (W<?>) xx;
+ }
+
+ void test3SWC() {
+ class A {
+ }
+ class B extends A {
+ }
+
+ W<? super B> xx = null;
+ W<A> y = (W<A>) xx;
+ }
+
+ // ?, ? ------------------------------------------
+ void test1WWW() {
+ W<?> xx = null;
+ W<?> y = xx;
+ }
+
+ //? extends P<? extends A>, B --------------------
+
+ void test1EEWC() {
+ class A {
+ }
+ class B {
+ }
+
+ W<? extends P<? extends A>> xx = null;
+ W<? extends B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends P<? extends A>>>' to 'W<? extends B>'">(W<? extends B>) xx</error>;
+ }
+
+ void test2EEWC() {
+ class A {
+ }
+ class B extends P {
+ }
+
+ W<? extends P<? extends A>> xx = null;
+ W<? extends B> y = (W<? extends B>) xx;
+ }
+
+ void test3EEWC() {
+ class A {
+ }
+ class B<TB> extends P<TB> {
+ }
+
+ W<? extends P<? extends A>> xx = null;
+ W<? extends B<? super A>> y = (W<? extends B<? super A>>) xx;
+ }
+
+
+ void test4EEWC() {
+ class A {
+ }
+ class B<TB> extends P<TB> {
+ }
+
+ W<? extends P<? extends A>> xx = null;
+ W<? extends B<?>> y = (W<? extends B<?>>) xx;
+ }
+
+ void test5EEWC() {
+ class A {
+ }
+ class B<TB> extends P<TB> {
+ }
+ class C {}
+
+ W<? extends P<? extends A>> xx = null;
+ W<? extends B<? extends C>> y = (W<? extends B<? extends C>>) xx;
+ }
+
+ //Array Types inside wildcards
+ void test1AE() {
+ class A {}
+ class B {}
+
+ W<? extends A[]> xx = null;
+ W<? extends B[]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A[]>>' to 'W<? extends B[]>'">(W<? extends B[]>) xx</error>;
+ }
+
+ void test11AE() {
+ class A {}
+ class B {}
+
+ W<? extends A[]> xx = null;
+ W<? extends B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A[]>>' to 'W<? extends B>'">(W<? extends B>) xx</error>;
+ }
+
+ void test2AE() {
+ class A {}
+ class B extends A {}
+
+ W<? extends A[]> xx = null;
+ W<? extends B[]> y = (W<? extends B[]>) xx;
+ }
+
+ void test21AE() {
+ class A {}
+ class B extends A {}
+
+ W<? extends A[]> xx = null;
+ W<? extends B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A[]>>' to 'W<? extends B>'">(W<? extends B>) xx</error>;
+ }
+
+
+
+ void testIntAE() {
+
+ W<? extends A[]> xx = null;
+ W<? extends B[]> y = (W<? extends B[]>) xx;
+ }
+
+ void testInt1AE() {
+
+ W<? extends A[]> xx = null;
+ W<? extends B[][]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends Test.A[]>>' to 'W<? extends Test.B[][]>'">(W<? extends B[][]>) xx</error>;
+ }
+
+ void testASS() {
+ class A {}
+ class B {}
+
+ W<? super A[]> xx = null;
+ W<? super B[]> y = (W<? super B[]>) xx;
+ }
+
+ void test1AES() {
+ class A {}
+ class B {}
+
+ W<? extends A[]> x = null;
+ W<? super B[]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A[]>>' to 'W<? super B[]>'">(W<? super B[]>) x</error>;
+ }
+
+ void test2AES() {
+ class A {}
+ class B extends A {}
+
+ W<? extends A[]> x = null;
+ W<? super B[]> y = (W<? super B[]>) x;
+ }
+
+ void test3AES() {
+ class A {}
+ class B extends A {}
+
+ W<? extends B[]> x = null;
+ W<? super A[]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends B[]>>' to 'W<? super A[]>'">(W<? super A[]>) x</error>;
+ }
+
+
+
+ void test4AES() {
+ W<? extends B[]> x = null;
+ W<? super A[]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends Test.B[]>>' to 'W<? super Test.A[]>'">(W<? super A[]>) x</error>;
+ }
+
+ void test5AES() {
+ final class B implements A {}
+
+ W<? extends A[]> x = null;
+ W<? super B[]> y = (W<? super B[]>) x;
+ }
+
+ void test6AES() {
+ final class B implements A {}
+
+ W<? extends B[]> x = null;
+ W<? super A[]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends B[]>>' to 'W<? super Test.A[]>'">(W<? super A[]>) x</error>;
+ }
+
+ // type parameters extensions: D<T extends A>
+ void testT3() {
+ class A {
+ }
+ class D<T extends A > {
+ class B extends A {
+ }
+
+ void foo() {
+ D<? extends T> x = null;
+ D<? extends B> y = (D<? extends B>) x;
+ }
+
+ }
+
+ }
+
+ void testT4() {
+ class A {
+ }
+ class D<T extends A> {
+ class B {
+ }
+
+ void foo() {
+ D<? extends T> x = null;
+ D<<error descr="Type parameter '? extends B' is not within its bound; should extend 'A'">? extends B</error>> y = (D<<error descr="Type parameter '? extends B' is not within its bound; should extend 'A'">? extends B</error>>) x;
+ }
+
+ }
+
+ }
+
+
+ void testT5() {
+ class D<T> {
+ class B {
+ }
+
+ void foo() {
+ D<? extends T> x = null;
+ D<? extends B> y = (D<? extends B>) x;
+ }
+
+ }
+
+ }
+
+ void testT6() {
+ class A {
+ }
+ class D<T extends A> {
+ class B extends A {
+ }
+
+ void foo() {
+ D<? super T> x = null;
+ D<? super B> y = (D<? super B>) x;
+ }
+
+ }
+
+ }
+
+ void testT7() {
+ class A {
+ }
+ class D<T extends A> {
+ class B extends A {
+ }
+
+ void foo() {
+ D<? extends T> x = null;
+ D<? super B> y = (D<? super B>) x;
+ }
+
+ }
+
+ }
+
+ void testT8() {
+ class A {
+ }
+ class D<T extends A> {
+ class B extends A {
+ }
+
+ void foo() {
+ D<? super T> x = null;
+ D<? extends B> y = (D<? extends B>) x;
+ }
+
+ }
+
+ }
+
+ void testT9() {
+ class A {
+ }
+ class D<T> {
+ class B extends A {
+ }
+
+ void foo() {
+ D<? super T> x = null;
+ D<? extends A> y = (D<? extends B>) x;
+ }
+
+ }
+
+ }
+
+ void testUnbounded() {
+ W<?> x = null;
+ W<? extends A> y = ( W<? extends A>) x;
+ W<?> y1 = (W<?>)x;
+ }
+
+ void testTypeParams() {
+ class MyClass<K, V> {
+ MyClass<K, V> convert(MyClass<? super K, ? super V> arg) {
+ MyClass<K, V> result = (MyClass<K, V>)arg;
+ return result;
+ }
+ }
+ }
+
+ //IDEA-63447
+ void testUnboundWildcardWithArrayTypes() {
+ class IUWWAT{
+ private <T> void method1(T[][] matrix) {
+ final Class<T[]> type = (Class<T[]>) matrix.getClass().getComponentType();
+ }
+
+ private <T> void method2(T[][] matrix) {
+ final Class<Object> type = (Class<Object>) matrix.getClass().getComponentType();
+ }
+
+ private <T> void method3(T[][] matrix) {
+ final Class<Object[]> type = (Class<Object[]>) matrix.getClass().getComponentType();
+ }
+
+ private <T> void method4(T[][] matrix) {
+ final Class<Object[][]> type = (Class<Object[][]>) matrix.getClass().getComponentType();
+ }
+ }
+ }
+}
+
+class W<T> {}
+class P<L> {}
+
+// IDEA-62529
+class Refx<T> {
+ Class<? super T> get() { return null; }
+ boolean f() {
+ if (get() == Enum.class) return false;
+ return (Class<Enum>)get() == Enum.class;
+ }
+}
+
+
+//hierarchy of type param bound
+abstract class DomInvocationHandler<T extends AbstractDomChildDescriptionImpl> {
+ void f() {
+ if (this instanceof IndexedElementInvocationHandler) {
+ }
+ }
+}
+
+interface AbstractDomChildrenDescription {
+}
+
+class AbstractDomChildDescriptionImpl implements AbstractDomChildrenDescription {
+}
+
+class IndexedElementInvocationHandler extends DomInvocationHandler<FixedChildDescriptionImpl> {
+}
+
+class FixedChildDescriptionImpl extends AbstractDomChildDescriptionImpl {
+}
+
+class CaptureSymmetry {
+ interface Collection<A> {}
+ interface List<A> extends Collection<A>{}
+ class ArrayList<A> implements List<A> {}
+
+ public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
+ return null;
+ }
+
+ public <B extends List<?>> Collection<? extends B> getBreakpoints (List<B> b) {
+ Collection<? extends ArrayList<?>> breakpoints = null;
+ Collection<? extends B> regular = breakpoints != null ? unmodifiableCollection((Collection<? extends B>)breakpoints) : b;
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardTypes.java
new file mode 100644
index 0000000..d55e641
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardTypes.java
@@ -0,0 +1,246 @@
+import java.util.*;
+
+class a {
+ public void printList(List<?> list) {
+ for (Iterator<?> i = list.iterator(); i.hasNext();) {
+ System.out.println(i.next().toString());
+ }
+ }
+}
+
+class b<<warning descr="Type parameter 'T' is never used">T</warning>> {
+ public interface Lst <E, Self extends Lst<E, Self>> {
+ Self subList(int fromIndex, int toIndex);
+ }
+
+ public static Lst<?, ?> foo(Lst<?, ?> lst) {
+ Lst<?, ?> myl = lst.subList(0, 2);
+ return myl;
+ }
+}
+
+class ThingUser <V> {
+ V v;
+ {
+ new ThingUser<<error descr="Wildcard type '?' cannot be instantiated directly">?</error>>() {
+ };
+ }
+}
+
+class SuperWildcardTest {
+ static void method(List<?> list) {
+ <error descr="Incompatible types. Found: 'java.util.List<capture<?>>', required: 'java.util.List<? super java.lang.String>'">List<? super String> l = list;</error>
+ l.size();
+ }
+}
+
+class IdeaDev4166 {
+ Map<String, Object> f( Map<String, ?> fieldsTemplate) {
+ return new HashMap<String, Object>( fieldsTemplate);
+ }
+}
+
+//IDEADEV-5816
+class TwoD {
+ int x, y;
+ TwoD(int a, int b) {
+ x = a;
+ y = b;
+ }
+}
+// Three-dimensional coordinates.
+class ThreeD extends TwoD {
+ int z;
+ ThreeD(int a, int b, int c) {
+ super(a, b);
+ z = c;
+ }
+}
+// Four-dimensional coordinates.
+class FourD extends ThreeD {
+ int t;
+ FourD(int a, int b, int c, int d) {
+ super(a, b, c);
+ t = d;
+ }
+}
+// This class holds an array of coordinate objects.
+class Coords<T extends TwoD> {
+ T[] coords;
+ Coords(T[] o) { coords = o; }
+}
+
+// Demonstrate a bounded wildcard.
+class BoundedWildcard {
+
+ static void showXY(Coords<? extends TwoD> c) {
+ System.out.println("X Y Coordinates:");
+ for(int i=0; i < c.coords.length; i++) {
+ System.out.println(c.coords[i].x + " " + c.coords[i].y);
+ }
+ System.out.println();
+ }
+
+ static void showXYZ(Coords<? extends ThreeD> c) {
+ System.out.println("X Y Z Coordinates:");
+ for(int i=0; i < c.coords.length; i++)
+ System.out.println(c.coords[i].x + " " +
+ c.coords[i].y + " " +
+ c.coords[i].z);
+ System.out.println();
+ }
+
+ static void showAll(Coords<? extends FourD> c) {
+ System.out.println("X Y Z T Coordinates:");
+ for(int i=0; i < c.coords.length; i++)
+ System.out.println(c.coords[i].x + " " +
+ c.coords[i].y + " " +
+ c.coords[i].z + " " +
+ c.coords[i].t);
+ System.out.println();
+ }
+
+ public static void main(String args[]) {
+ TwoD td[] = {
+ new TwoD(0, 0),
+ new TwoD(7, 9),
+ new TwoD(18, 4),
+ new TwoD(-1, -23)
+ };
+ Coords<TwoD> tdlocs = new Coords<TwoD>(td);
+ System.out.println("Contents of tdlocs.");
+ showXY(tdlocs); // OK, is a TwoD
+ showXYZ<error descr="'showXYZ(Coords<? extends ThreeD>)' in 'BoundedWildcard' cannot be applied to '(Coords<TwoD>)'">(tdlocs)</error>;
+ showAll<error descr="'showAll(Coords<? extends FourD>)' in 'BoundedWildcard' cannot be applied to '(Coords<TwoD>)'">(tdlocs)</error>;
+ // Now, create some FourD objects.
+ FourD fd[] = {
+ new FourD(1, 2, 3, 4),
+ new FourD(6, 8, 14, 8),
+ new FourD(22, 9, 4, 9),
+ new FourD(3, -2, -23, 17)
+ };
+ Coords<FourD> fdlocs = new Coords<FourD>(fd);
+ System.out.println("Contents of fdlocs.");
+ // These are all OK.
+ showXY(fdlocs);
+ showXYZ(fdlocs);
+ showAll(fdlocs);
+ }
+}
+//end of IDEADEV-5816
+
+interface I33 {}
+public class Q<T extends I33> {
+ T t;
+ <V extends I33> List<V> foo(Q<V> v) {
+ v.hashCode();
+ return null;
+ }
+
+ List<? extends I33> g (Q<?> q) {
+ return foo(q);
+ }
+}
+
+//IDEADEV-16628
+class CollectionHelper {
+ public static <A> Collection<A> convertDown(Collection<? super A> collection) {
+ return collection == null ? null : null;
+ }
+ public static <A> Collection<A> convertUp(Collection<? extends A> collection) {
+ return collection == null ? null : null;
+ }
+
+ public static void main(String[] args) {
+ // Downcast examples
+ final Collection<Number> numbers1 = new ArrayList<Number>(1);
+ Collection<Integer> integers1 = CollectionHelper.convertDown(numbers1);
+ integers1.hashCode();
+ // Upcast example
+ final Collection<Integer> integers4 = new ArrayList<Integer>(1);
+ final Collection<Number> numbers4 = CollectionHelper.<Number>convertUp(integers4);
+ numbers4.hashCode();
+ }
+}
+
+//IDEA-62529
+class My<T> {
+ private Class<? super T> getSuperclass(){
+ return null;
+ }
+
+ public void test() {
+ if (getSuperclass() == List.class);
+ }
+}
+
+class IDEA75178 {
+ void test(Set<String> labels) {
+ final Matcher<? super Object> empty = isEmpty();
+ assertThat(labels, empty);
+ assertAlsoThat(empty, labels);
+ }
+
+ public static <T> void assertThat(T actual, Matcher<T> matcher) { throw new AssertionError(actual.toString() + matcher.toString());}
+ public static <T> void assertAlsoThat(Matcher<T> matcher, T actual) { throw new AssertionError(actual.toString() + matcher.toString());}
+
+ public static <T> Matcher<? super T> isEmpty() {
+ return null;
+ }
+
+ static class Matcher<<warning descr="Type parameter 'T' is never used">T</warning>>{}
+
+ class Foo {}
+ void testComment() {
+ Set<Foo> foos = Collections.emptySet();
+ assertThatComment(foos, hasSize(0));
+ }
+
+ <E> Matcher<? super Collection<? extends E>> hasSize(int size) {return size == 0 ? null : null;}
+ <T> void assertThatComment(T actual, Matcher<? super T> matcher){ throw new AssertionError(actual.toString() + matcher.toString());}
+}
+
+class IDEA66750 {
+ public void test() {
+ List<List<String>> data = new ArrayList<List<String>>();
+ List<List<?>> y = <error descr="Inconvertible types; cannot cast 'java.util.List<java.util.List<java.lang.String>>' to 'java.util.List<java.util.List<?>>'">(List<List<?>>)data</error>;
+ System.out.println(y);
+
+ ArrayList<Number> al = <error descr="Inconvertible types; cannot cast 'java.util.ArrayList<java.lang.Integer>' to 'java.util.ArrayList<java.lang.Number>'">(ArrayList<Number>) new ArrayList<Integer>(1)</error>;
+ System.out.println(al);
+ }
+}
+
+class IDEA73377 {
+ public Iterator<Map.Entry<Map.Entry<?, ?>, ?>> iterator(Map<?, ?> map) {
+ //noinspection unchecked
+ return <error descr="Inconvertible types; cannot cast 'java.util.Iterator<java.util.Map.Entry<capture<?>,capture<?>>>' to 'java.util.Iterator<java.util.Map.Entry<java.util.Map.Entry<?,?>,?>>'">(Iterator<Map.Entry<Map.Entry<?, ?>, ?>>)map.entrySet().iterator()</error>;
+ }
+}
+
+class IDEA91481 {
+ void bar(){
+ BeanBuilder<? extends DirectBean> builder = <warning descr="Unchecked cast: 'IDEA91481.BeanBuilder<capture<? extends IDEA91481.Bean>>' to 'IDEA91481.BeanBuilder<? extends IDEA91481.DirectBean>'">(BeanBuilder<? extends DirectBean>) builder()</warning>;
+ System.out.println(builder);
+ }
+
+ BeanBuilder<? extends Bean> builder() {
+ return null;
+ }
+
+ class BeanBuilder<<warning descr="Type parameter 'T' is never used">T</warning>> {}
+ class Bean {}
+ class DirectBean extends Bean {}
+}
+
+class IDEA89640 {
+ interface X {}
+ class Y<<warning descr="Type parameter 'T' is never used">T</warning> extends X> {}
+
+ public static void main(String[] args) {
+ Y<? extends X> a = null;
+ Y<? extends X> b = null;
+ boolean flag = a != b;
+ System.out.println(flag);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsBoundsIntersection.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsBoundsIntersection.java
new file mode 100644
index 0000000..3fc74e5
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsBoundsIntersection.java
@@ -0,0 +1,15 @@
+class NodeProperty<A, B> {}
+
+class NodeType {}
+class NumberExpression extends NodeType {}
+class Node<NodeTypeT extends NodeType> {
+ public <ValueT> ValueT get(NodeProperty<? super NodeTypeT, ValueT> prop) {
+ return null;
+ }
+}
+
+class Main {
+ public static void main(NodeProperty<NumberExpression, Integer> nval, Node<? extends NodeType> expr) {
+ int val = expr.get<error descr="'get(NodeProperty<? super capture<? extends NodeType>,ValueT>)' in 'Node' cannot be applied to '(NodeProperty<NumberExpression,java.lang.Integer>)'">(nval)</error>;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsOnRawTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsOnRawTypes.java
new file mode 100644
index 0000000..ed1aa05
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsOnRawTypes.java
@@ -0,0 +1,15 @@
+import java.util.List;
+
+public class Main<T> {
+ Object get(List<DiagramNode<T>> nodes, A a) {
+ return null;
+ }
+}
+class DiagramNode<T> {}
+
+class A {
+ static void f(Main m, List<DiagramNode<?>> nodes){
+ final Object data = m.get(nodes, new A());
+ final <error descr="Incompatible types. Found: 'java.util.List<DiagramNode<?>>', required: 'java.util.List<DiagramNode>'">List<DiagramNode> n = nodes;</error>
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/exceptions/LambdaParamExceptionVariable.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/exceptions/LambdaParamExceptionVariable.java
index 80d78a4..ad62864 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/exceptions/LambdaParamExceptionVariable.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/exceptions/LambdaParamExceptionVariable.java
@@ -5,7 +5,7 @@
<K extends Throwable> void foo(F<K> f) throws K { }
{
- foo(<error descr="Cyclic inference">(t)->{}</error>);
+ <error descr="Unhandled exception: java.lang.Throwable">foo((t)->{});</error>
<error descr="Unhandled exception: java.lang.ClassNotFoundException">foo((ClassNotFoundException t)->{});</error>
}
}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/DefaultConstructorAsArgument.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/DefaultConstructorAsArgument.java
new file mode 100644
index 0000000..9846267
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/DefaultConstructorAsArgument.java
@@ -0,0 +1,21 @@
+class Main2 {
+
+ <R> void bar(Fun<Integer, R> collector) { }
+
+ <T, D> Fun<T, Integer> foo(D d) { return null; }
+
+ public void test() {
+ bar(new Foo<>());
+ }
+
+ interface Fun<T, R> {
+ R _(T t);
+ }
+
+ class Foo<K> implements Fun<K, Integer> {
+ @Override
+ public Integer _(K k) {
+ return null;
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution.java
index 43c4ba9..57f194d 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution.java
@@ -1,6 +1,6 @@
public interface IDEA99969 {
default IntStream distinct(Stream s) {
- return s.map(i -> (int) i);
+ return s.map<error descr="Ambiguous method call: both 'Stream.map(Function)' and 'Stream.map(IntFunction)' match">(i -> <error descr="Inconvertible types; cannot cast '<lambda parameter>' to 'int'">(int) i</error>)</error>;
}
}
interface Stream<T> {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution2.java
index c89c855..a178b4d 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution2.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution2.java
@@ -8,19 +8,19 @@
}
- private void foo(IO<? extends A> <warning descr="Parameter 'p' is never used">p</warning>) {}
+ private void <warning descr="Private method 'foo(Test.IO<? extends A>)' is never used">foo</warning>(IO<? extends A> <warning descr="Parameter 'p' is never used">p</warning>) {}
private void <warning descr="Private method 'foo(Test.IN<? extends B>)' is never used">foo</warning>(IN<? extends B> <warning descr="Parameter 'p' is never used">p</warning>) {}
private static class Inner<A extends Object, B extends Number> {
private void <warning descr="Private method 'm8(Test.IO<? extends A>)' is never used">m8</warning>(IO<? extends A> <warning descr="Parameter 'p' is never used">p</warning>) {}
- private void m8(IN<? extends B> <warning descr="Parameter 'p' is never used">p</warning>) {}
+ private void <warning descr="Private method 'm8(Test.IN<? extends B>)' is never used">m8</warning>(IN<? extends B> <warning descr="Parameter 'p' is never used">p</warning>) {}
}
public static void main(String[] args) {
Inner<Number, Double> inn = new Inner<>();
- inn.m8(p -> 1.0);
- new Test<Number, Integer>().foo(p -> 1.0);
+ inn.m8<error descr="Ambiguous method call: both 'Inner.m8(IO<? extends Number>)' and 'Inner.m8(IN<? extends Double>)' match">(p -> 1.0)</error>;
+ new Test<Number, Integer>().foo<error descr="Ambiguous method call: both 'Test.foo(IO<? extends Number>)' and 'Test.foo(IN<? extends Integer>)' match">(p -> 1.0)</error>;
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution3.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution3.java
index 435e10d..6f7e6d0 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution3.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution3.java
@@ -8,8 +8,8 @@
IntStream mi = sp.map(Inner::foo);
Stream<Integer> mI = sp.map(Inner::fooBoxed);
- IntStream li = sp.map(inner->inner.foo());
- Stream<Integer> lI = sp.map(inner -> inner.fooBoxed());
+ IntStream li = sp.map<error descr="Ambiguous method call: both 'Stream.map(Function<? super Inner,?>)' and 'Stream.map(IntFunction<? super Inner>)' match">(inner->inner.<error descr="Cannot resolve method 'foo()'">foo</error>())</error>;
+ Stream<Integer> lI = sp.map<error descr="Ambiguous method call: both 'Stream.map(Function<? super Inner,? extends Integer>)' and 'Stream.map(IntFunction<? super Inner>)' match">(inner -> inner.<error descr="Cannot resolve method 'fooBoxed()'">fooBoxed</error>())</error>;
}
interface Stream<T> {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguitySpecificReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguitySpecificReturn.java
index c090878..738dd66 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguitySpecificReturn.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguitySpecificReturn.java
@@ -1,15 +1,15 @@
class IntStream {
private void foo(IntStream s) {
- s.map(i -> 1 << i);
- s.map(i -> 1);
- s.map(i -> i);
+ s.map<error descr="Ambiguous method call: both 'IntStream.map(IntUnaryOperator)' and 'IntStream.map(ObjIntFunction<Integer>)' match">(i -> <error descr="Operator '<<' cannot be applied to 'int', '<lambda parameter>'">1 << i</error>)</error>;
+ s.map<error descr="Ambiguous method call: both 'IntStream.map(IntUnaryOperator)' and 'IntStream.map(ObjIntFunction<Integer>)' match">(i -> 1)</error>;
+ s.map<error descr="Ambiguous method call: both 'IntStream.map(IntUnaryOperator)' and 'IntStream.map(ObjIntFunction<Integer>)' match">(i -> i)</error>;
}
public static void main(String[] args) {
new IntStream().foo(null);
}
- private IntStream map(IntUnaryOperator mapper) {
+ private IntStream <warning descr="Private method 'map(IntUnaryOperator)' is never used">map</warning>(IntUnaryOperator mapper) {
System.out.println(mapper);
return null;
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/InferenceFromArgs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/InferenceFromArgs.java
index 2febfc5..2c5ca5e 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/InferenceFromArgs.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/InferenceFromArgs.java
@@ -15,13 +15,13 @@
private static <E> void bazz(I<? super E, Integer> i) { }
void foo(B<Integer> b) {
- bar(null, <error descr="Cyclic inference">(k, v) -> v</error>);
+ bar(null, (k, v) -> v);
bar(null, null);
bar(b, (k, v) -> {return v;});
bar(b, (k, v) -> {<error descr="Incompatible types. Found: 'java.lang.Integer', required: 'java.lang.String'">String i = k;</error> return v;});
bar(b, (k, v) -> {Integer i = k; return v;});
- bazz(<error descr="Cyclic inference">(k, v) -> v</error>);
+ bazz((k, v) -> v);
bazz((k, v) -> {<error descr="Incompatible types. Found: 'java.lang.Object', required: 'int'">int i = k;</error> return v;});
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaRawOrNot.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaRawOrNot.java
index 4b9b085..774c555 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaRawOrNot.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaRawOrNot.java
@@ -12,7 +12,7 @@
class Test2 {
protected <T, U> U exerciseOps(TestData<T> data, TerminalOp<T, U> terminal, IntermediateOp... ops) {
- return exerciseOps(data, <error descr="Cyclic inference">(u, v) -> u.equals(v)</error>, terminal);
+ <error descr="Incompatible types. Found: 'java.lang.Object', required: 'U'">return exerciseOps(data, (u, v) -> u.equals(v), terminal);</error>
}
}
@@ -23,15 +23,15 @@
static <T> void bar(I<T> i, List<T> l){
bar(x -> {}, l);
- bar(<error descr="Cyclic inference">x -> {}</error>, null);
+ bar(x -> {}, null);
bar((I<T>)x -> {}, null);
bar((T x) -> {}, null);
bar(x -> {}, new ArrayList<T>());
- bar(<error descr="Cyclic inference">x -> {}</error>, new ArrayList());
+ bar(x -> {}, new ArrayList());
}
static {
- bar(<error descr="Cyclic inference">x->{}</error>, new ArrayList());
+ bar(x->{}, new ArrayList());
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/NoInferenceResult.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/NoInferenceResult.java
index 7af6276..53e96c39 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/NoInferenceResult.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/NoInferenceResult.java
@@ -21,7 +21,7 @@
m((String s1) -> s1.length());
m((String s1) -> s1);
- m1(<error descr="Cyclic inference">() -> { }</error>);
+ m1<error descr="'m1(T)' in 'NoInferenceResult' cannot be applied to '(<lambda expression>)'">(() -> { })</error>;
Foo<String> foo = new Foo<String>();
foo.map(v -> null);
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java
index 4ca8cb3..a922039 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java
@@ -25,7 +25,7 @@
}
public static void main(String[] args) {
- call(i-> {return i;});
+ call<error descr="Ambiguous method call: both 'ReturnTypeIncompatibility.call(I1<Integer>)' and 'ReturnTypeIncompatibility.call(I2<String>)' match">(i-> {return i;})</error>;
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java
index d34d61f..8daa44f 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java
@@ -21,9 +21,9 @@
}
void foo(Foo<String> as, final Foo<Character> ac) {
- boolean b1 = as.forAll(s -> ac.forAll(c -> false));
- String s1 = as.forAll(s -> ac.forAll(c -> ""));
- <error descr="Incompatible types. Found: 'java.lang.String', required: 'boolean'">boolean b2 = as.forAll(s -> ac.forAll(c -> ""));</error>
+ boolean b1 = as.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<String,Boolean>)' and 'Foo.forAll(II<String,String>)' match">(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character,Boolean>)' and 'Foo.forAll(II<Character,String>)' match">(c -> false)</error>)</error>;
+ String s1 = as.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<String,Boolean>)' and 'Foo.forAll(II<String,String>)' match">(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character,Boolean>)' and 'Foo.forAll(II<Character,String>)' match">(c -> "")</error>)</error>;
+ boolean b2 = as.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<String,Boolean>)' and 'Foo.forAll(II<String,String>)' match">(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character,Boolean>)' and 'Foo.forAll(II<Character,String>)' match">(c -> "")</error>)</error>;
String s2 = as.forAll2(s -> ac.forAll2(<error descr="Incompatible return type boolean in lambda expression">c -> false</error>));
boolean b3 = as.forAll((I<String, Boolean>)s -> ac.forAll((I<Character, Boolean>)<error descr="Incompatible return type String in lambda expression">c -> ""</error>));
String s3 = as.forAll((II<String, String>)s -> ac.forAll((II<Character, String>)<error descr="Incompatible return type boolean in lambda expression">c -> false</error>));
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/TypeArgsConsistencyMisc1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/TypeArgsConsistencyMisc1.java
index 613bbeb..be5128f 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/TypeArgsConsistencyMisc1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/TypeArgsConsistencyMisc1.java
@@ -64,8 +64,8 @@
static <T> void bar3(I<T> i, T t){}
{
- bar(<error descr="Cyclic inference">x -> x</error>);
- bar1(<error descr="Cyclic inference">x -> x</error>);
+ bar(x -> x);
+ bar1(x -> x);
bar2(1, <error descr="Incompatible return type List<Integer> in lambda expression">x -> x</error>);
bar2("", <error descr="Incompatible return type List<String> in lambda expression">x -> x</error>);
bar3(<error descr="Incompatible return type List<String> in lambda expression">x -> x</error>, "");
@@ -84,8 +84,8 @@
static <T> void bar3(I<T> i, T t){}
{
- bar(<error descr="Cyclic inference">x -> x</error>);
- bar1(<error descr="Cyclic inference">x -> x</error>);
+ bar(x -> x);
+ bar1(x -> x);
bar2(1, x -> x);
bar2("", x -> x);
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/WildcardsAndFormalLambdaParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/WildcardsAndFormalLambdaParams.java
new file mode 100644
index 0000000..3dda1b4
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/WildcardsAndFormalLambdaParams.java
@@ -0,0 +1,11 @@
+public class Test {
+ interface Predicate<T> {
+ boolean test(T t);
+ }
+
+ {
+ Predicate<? super Integer> p = (Number n) -> n.equals(23);
+ Predicate<Integer> p1 = (<error descr="Incompatible parameter types in lambda expression">Number n</error>) -> n.equals(23);
+ Predicate<Number> p2 = (Number n) -> n.equals(23);
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/inference/SimpleCyclicInference.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/inference/SimpleCyclicInference.java
index d344665..400c469 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/inference/SimpleCyclicInference.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/inference/SimpleCyclicInference.java
@@ -8,13 +8,13 @@
void bazz() {
bar(null);
- bar(<error descr="Cyclic inference">(z)-> {System.out.println();}</error>);
+ bar((z)-> {System.out.println();});
}
static <T> T id(T i2) {return i2;}
{
- id(<error descr="Cyclic inference">() -> {System.out.println("hi");}</error>);
+ id<error descr="'id(T)' in 'NoLambda' cannot be applied to '(<lambda expression>)'">(() -> {System.out.println("hi");})</error>;
NoLambda.<Runnable>id(() -> {System.out.println("hi");});
}
}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/FormalParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/FormalParams.java
index 8ecb69a..5fffb89 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/FormalParams.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/FormalParams.java
@@ -30,8 +30,8 @@
public static void main(String[] args) {
call((String i)->{ return i;});
- call(<error descr="Cyclic inference">i->{ return i;}</error>);
- call(<error descr="Cyclic inference">i->""</error>);
- call<error descr="'call(ReturnTypeCompatibility.I1<java.lang.Integer>)' in 'ReturnTypeCompatibility' cannot be applied to '(<lambda expression>)'">((int i)->{ return i;})</error>;
+ call(i->{ return i;});
+ call(i->"");
+ call((<error descr="Incompatible parameter types in lambda expression">int i</error>)->{ return i;});
}
}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterFormalTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterFormalTypes.java
index b39fca9..a5358d3 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterFormalTypes.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterFormalTypes.java
@@ -9,6 +9,6 @@
static <T> I<T> bar(I<T> i){return i;}
{
- bar((List<String> list) -> null);
+ bar(list -> null);
}
}
diff --git a/java/java-tests/testData/codeInsight/parameterInfo/AnnotationWithGenerics.java b/java/java-tests/testData/codeInsight/parameterInfo/AnnotationWithGenerics.java
new file mode 100644
index 0000000..7dcc9bc
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/parameterInfo/AnnotationWithGenerics.java
@@ -0,0 +1,10 @@
+import java.util.List;
+
+@interface PrepareForTest {
+ Class<List<String[]>> value();
+}
+
+abstract class A implements List<String>{}
+
+@PrepareForTest({A<caret>.class})
+class Main {}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ContractAnnotation.java b/java/java-tests/testData/inspection/dataFlow/fixture/ContractAnnotation.java
index c39c022..a5c27dd 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/ContractAnnotation.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/ContractAnnotation.java
@@ -6,14 +6,22 @@
import java.lang.IllegalArgumentException;
public class AssertIsNotNull {
- void bar(String s) {
+ void bar(String s, String s1) {
if (<warning descr="Condition 's == null && trimIfNotNull(s) != null' is always 'false'">s == null && <warning descr="Condition 'trimIfNotNull(s) != null' is always 'false' when reached">trimIfNotNull(s) != null</warning></warning>) {
throw new AssertionError();
}
final Object o = call();
assertIsNotNull(o);
+ System.out.println(o.toString());
if(<warning descr="Condition 'o == null' is always 'false'">o == null</warning>) {}
+
+ if (trimIfNotNull(s1) != null) {
+ System.out.println(s1.charAt(0));
+ if (<warning descr="Condition 's1 == null' is always 'false'">s1 == null</warning>) {
+
+ }
+ }
}
@Contract("null -> fail")
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ContractPreservesUnknownNullability.java b/java/java-tests/testData/inspection/dataFlow/fixture/ContractPreservesUnknownNullability.java
new file mode 100644
index 0000000..d829f23
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/ContractPreservesUnknownNullability.java
@@ -0,0 +1,27 @@
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+
+public class Foo {
+
+ @Contract("null->null")
+ String foo(String s){
+ return s;
+ }
+
+ void bar(String s, String s2) {
+ foo(s);
+ s.hashCode();
+ goo(foo(s2));
+ }
+
+ void bar2(String s, String s2) {
+ foo(s);
+ if (equals(s2)) {
+ s.hashCode();
+ }
+ }
+
+
+ void goo(@NotNull String s) {}
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/FinalGetter.java b/java/java-tests/testData/inspection/dataFlow/fixture/FinalGetter.java
new file mode 100644
index 0000000..839452a
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/FinalGetter.java
@@ -0,0 +1,14 @@
+class Some {
+ final boolean getFoo() { return equals(2); }
+ void changeEverything() {}
+
+ void bar() {
+ if (getFoo()) {
+ changeEverything();
+ if (getFoo()) {
+
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ForeachOverWildcards.java b/java/java-tests/testData/inspection/dataFlow/fixture/ForeachOverWildcards.java
new file mode 100644
index 0000000..152c9ea
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/ForeachOverWildcards.java
@@ -0,0 +1,12 @@
+import org.jetbrains.annotations.Nullable;
+
+class Some {
+ void bar2(@Nullable Iterable<? extends String> dirs) {
+ if (dirs != null) {
+ for (String dir : dirs) {
+
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/IsNullCheck.java b/java/java-tests/testData/inspection/dataFlow/fixture/IsNullCheck.java
index 1b2c485..f87e0de 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/IsNullCheck.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/IsNullCheck.java
@@ -2,8 +2,9 @@
void bar() {
final Value v = call();
if (Value.isNull(v)) {
- if(<warning descr="Condition 'v == null' is always 'true'">v == null</warning>) {}
+ return;
}
+ if(<warning descr="Condition 'v == null' is always 'false'">v == null</warning>) {}
}
Value call() {return new Value();}
}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/LongDisjunctionsNotComplex.java b/java/java-tests/testData/inspection/dataFlow/fixture/LongDisjunctionsNotComplex.java
new file mode 100644
index 0000000..affd67c
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/LongDisjunctionsNotComplex.java
@@ -0,0 +1,47 @@
+class Some {
+ void getName(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10) {
+ if (i1 == 1 ||
+ i1 == 2 ||
+ i1 == 3 ||
+ i1 == 4) { }
+ if (i2 == 1 ||
+ i2 == 2 ||
+ i2 == 3 ||
+ i2 == 4) { }
+ if (i3 == 1 ||
+ i3 == 2 ||
+ i3 == 3 ||
+ i3 == 4) { }
+ if (i4 == 1 ||
+ i4 == 2 ||
+ i4 == 3 ||
+ i4 == 4) { }
+ if (i5 == 1 ||
+ i5 == 2 ||
+ i5 == 3 ||
+ i5 == 4) { }
+ if (i6 == 1 ||
+ i6 == 2 ||
+ i6 == 3 ||
+ i6 == 4) { }
+ if (i7 == 1 ||
+ i7 == 2 ||
+ i7 == 3 ||
+ i7 == 4) { }
+ if (i8 == 1 ||
+ i8 == 2 ||
+ i8 == 3 ||
+ i8 == 4) { }
+ if (i9 == 1 ||
+ i9 == 2 ||
+ i9 == 3 ||
+ i9 == 4) { }
+ if (i10 == 1 ||
+ i10 == 2 ||
+ i10 == 3 ||
+ i10 == 4) { }
+ }
+
+}
+
+
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ManySequentialIfsNotComplex.java b/java/java-tests/testData/inspection/dataFlow/fixture/ManySequentialIfsNotComplex.java
new file mode 100644
index 0000000..605636b
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/ManySequentialIfsNotComplex.java
@@ -0,0 +1,37 @@
+class Some {
+ void foo(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, int i11, int i12, int i13, Foo foo) {
+ if (i1 == 0) {
+ i3 = 2;
+ System.out.println(foo.getBar1().length());
+ }
+ if (i2 == 0) System.out.println(foo.getBar2().length());
+ if (i3 == 0) System.out.println(foo.getBar3().length());
+ if (i4 == 0) System.out.println(foo.getBar4().length());
+ if (i5 == 0) System.out.println(foo.getBar5().length());
+ if (i6 == 0) System.out.println(foo.getBar6().length());
+ if (i7 == 0) System.out.println(foo.getBar7().length());
+ if (i8 == 0) System.out.println(foo.getBar8().length());
+ if (i9 == 0) System.out.println(foo.getBar9().length());
+ if (i10 == 0) System.out.println(foo.getBar10().length());
+ if (i11 == 0) System.out.println(foo.getBar11().length());
+ if (i12 == 0) System.out.println(foo.getBar12().length());
+ if (i13 == 0) System.out.println(foo.getBar13().length());
+ }
+
+}
+
+interface Foo {
+ String getBar1();
+ String getBar2();
+ String getBar3();
+ String getBar4();
+ String getBar5();
+ String getBar6();
+ String getBar7();
+ String getBar8();
+ String getBar9();
+ String getBar10();
+ String getBar11();
+ String getBar12();
+ String getBar13();
+}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/WhileNotComplex.java b/java/java-tests/testData/inspection/dataFlow/fixture/WhileNotComplex.java
new file mode 100644
index 0000000..65d32c3
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/WhileNotComplex.java
@@ -0,0 +1,14 @@
+import java.io.File;
+
+class Some {
+ private File findRepository(File file) {
+ while (file != null) {
+ file = file.getParentFile();
+ }
+
+ return new File("foo");
+ }
+
+}
+
+
diff --git a/java/java-tests/testData/inspection/dataFlow/unboxingNPE/expected.xml b/java/java-tests/testData/inspection/dataFlow/unboxingNPE/expected.xml
index caab45d3..000168e 100644
--- a/java/java-tests/testData/inspection/dataFlow/unboxingNPE/expected.xml
+++ b/java/java-tests/testData/inspection/dataFlow/unboxingNPE/expected.xml
@@ -384,10 +384,4 @@
<description>Condition <code>i</code> is always <code>true</code> when reached</description>
</problem>
- <problem>
- <file>Test.java</file>
- <line>62</line>
- <module>testUnboxingNPE_7454908424878253728</module>
- <description>Switch label<code>case 0:</code> is unreachable</description>
- </problem>
</problems>
diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll3.java b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll3.java
new file mode 100644
index 0000000..6c73f83
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll3.java
@@ -0,0 +1,12 @@
+class C {
+ static enum E {
+ A
+ }
+
+ void x(String s1, String s2) {}
+
+ private void y() {
+ x(E.A.toString(), E.<caret>A.toString());
+
+ }
+}
diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll3_after.java b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll3_after.java
new file mode 100644
index 0000000..8d7703c
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll3_after.java
@@ -0,0 +1,12 @@
+class C {
+ static enum E {
+ A
+ }
+
+ void x(String s1, String s2) {}
+
+ private void y(E a) {
+ x(a.toString(), a.toString());
+
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java
index 1ccef12..607b1b4 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/ParameterInfoTest.java
@@ -1,6 +1,7 @@
package com.intellij.codeInsight;
import com.intellij.codeInsight.hint.ParameterInfoComponent;
+import com.intellij.codeInsight.hint.api.impls.AnnotationParameterInfoHandler;
import com.intellij.codeInsight.hint.api.impls.MethodParameterInfoHandler;
import com.intellij.lang.parameterInfo.CreateParameterInfoContext;
import com.intellij.lang.parameterInfo.ParameterInfoUIContextEx;
@@ -74,4 +75,25 @@
MethodParameterInfoHandler
.updateMethodPresentation(method, ((MethodCandidateInfo)itemsToShow[0]).getSubstitutor(), parameterContext));
}
+
+ public void testAnnotationWithGenerics() throws Exception {
+ doTestAnnotationPresentation("<html>Class<List<String[]>> <b>value</b>()</html>");
+ }
+
+ private void doTestAnnotationPresentation(String expectedString) {
+ configureByFile(BASE_PATH + getTestName(false) + ".java");
+
+ final AnnotationParameterInfoHandler handler = new AnnotationParameterInfoHandler();
+ final CreateParameterInfoContext context = new MockCreateParameterInfoContext(myEditor, myFile);
+ final PsiAnnotationParameterList list = handler.findElementForParameterInfo(context);
+ assertNotNull(list);
+ final Object[] itemsToShow = context.getItemsToShow();
+ assertNotNull(itemsToShow);
+ assertTrue(itemsToShow.length == 1);
+ assertTrue(itemsToShow[0] instanceof PsiAnnotationMethod);
+ final PsiAnnotationMethod method = (PsiAnnotationMethod)itemsToShow[0];
+ final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler);
+ Assert.assertEquals(expectedString,
+ AnnotationParameterInfoHandler.updateUIText(method, parameterContext));
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HippieCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HippieCompletionTest.groovy
index dde4d05..e1250ef 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HippieCompletionTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HippieCompletionTest.groovy
@@ -27,11 +27,75 @@
$some_long_variable_name = Obj::instance();
$some_lon<caret>
'''
- myFixture.performEditorAction(IdeActions.ACTION_HIPPIE_COMPLETION)
+ complete()
myFixture.checkResult '''
$some_long_variable_name = Obj::instance();
$some_long_variable_name<caret>
'''
}
+ public void testFromAnotherFile() {
+ myFixture.configureByText "b.txt", '''
+$some_long_variable_name = Obj::instance();
+'''
+ myFixture.configureByText "a.txt", '''
+$some_lon<caret>
+'''
+
+ complete()
+ myFixture.checkResult '''
+$some_long_variable_name<caret>
+'''
+ }
+
+ public void "test no middle matching"() {
+ myFixture.configureByText "a.txt", '''
+fooExpression
+exp<caret>
+'''
+ complete()
+ myFixture.checkResult '''
+fooExpression
+exp<caret>
+'''
+ }
+
+ public void "test words from javadoc"() {
+ myFixture.configureByText "a.java", '''
+/** some comment */
+com<caret>
+'''
+ complete()
+ myFixture.checkResult '''
+/** some comment */
+comment<caret>
+'''
+ }
+
+ public void "test words from line comments"() {
+ myFixture.configureByText "a.java", '''
+// some comment2
+com<caret>
+'''
+ complete()
+ myFixture.checkResult '''
+// some comment2
+comment2<caret>
+'''
+ }
+ public void "test words from block comments"() {
+ myFixture.configureByText "a.java", '''
+/* some comment3 */
+com<caret>
+'''
+ complete()
+ myFixture.checkResult '''
+/* some comment3 */
+comment3<caret>
+'''
+ }
+
+ private void complete() {
+ myFixture.performEditorAction(IdeActions.ACTION_HIPPIE_COMPLETION)
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
index 697e534..aad87e8 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
@@ -880,7 +880,9 @@
void foo(int aaa, int aaaaa) { }
void bar(int aaa, int aaaaa) { foo(<caret>) }
} """)
- type 'a,'
+ type 'a'
+ println myFixture.lookupElementStrings
+ type ','
assert myFixture.editor.document.text.contains('foo(aaa, )')
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
index 5380c7e..8e04d87 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
@@ -994,6 +994,7 @@
public void testNewGenericClass() throws Throwable { doTest('\n') }
public void testNewGenericInterface() throws Throwable { doTest() }
public void testEnumPrivateFinal() throws Throwable { doTest() }
+ public void testNoFieldsInImplements() throws Throwable { doTest() }
public void testSwitchConstantsFromReferencedClass() throws Throwable { doTest('\n') }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlighting8Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlighting8Test.java
new file mode 100644
index 0000000..2b87ecf
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlighting8Test.java
@@ -0,0 +1,775 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http:www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.daemon;
+
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
+import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection;
+import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.impl.source.resolve.PsiResolveHelperImpl;
+import com.intellij.psi.impl.source.resolve.graphInference.PsiGraphInferenceHelper;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.testFramework.IdeaTestUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
+ @NonNls private static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/genericsHighlighting8";
+
+ @NotNull
+ @Override
+ protected LocalInspectionTool[] configureLocalInspectionTools() {
+ return new LocalInspectionTool[]{new UncheckedWarningLocalInspection(), new UnusedSymbolLocalInspection(), new UnusedImportLocalInspection()};
+ }
+
+ @Override
+ protected Sdk getProjectJDK() {
+ return getTestName(false).contains("Jdk14") ? IdeaTestUtil.getMockJdk14() : super.getProjectJDK();
+ }
+
+ public void testReferenceTypeParams() {
+ doTest();
+ }
+ public void testTypeParameterBoundsList() {
+ doTest();
+ }
+ public void testClassInheritance() {
+ doTest();
+ }
+ public void testTypeInference() {
+ doTest();
+ }
+ public void testRaw() {
+ doTest(true);
+ }
+ public void testExceptions() {
+ doTest();
+ }
+ public void testExplicitMethodParameters() {
+ doTest();
+ }
+ public void testInferenceWithBounds() {
+ doTest();
+ }
+ public void testInferenceWithSuperBounds() {
+ doTest();
+ }
+ public void testInferenceWithUpperBoundPromotion() {
+ doTest();
+ }
+ public void _testVariance() {//todo
+ doTest();
+ }
+ public void testForeachTypes() {
+ doTest();
+ }
+ public void testRawOverridingMethods() {
+ doTest();
+ }
+ public void _testAutoboxing() { //todo
+ doTest();
+ }
+ public void testAutoboxingMethods() {
+ doTest();
+ }
+ public void testAutoboxingConstructors() {
+ doTest();
+ }
+ public void testEnumWithAbstractMethods() {
+ doTest();
+ }
+ public void _testEnum() { doTest(); } //todo
+ public void testEnum56239() {
+ doTest();
+ }
+ public void testSameErasure() {
+ doTest();
+ }
+ public void testMethods() {
+ doTest();
+ }
+ public void testFields() {
+ doTest();
+ }
+ public void testStaticImports() {
+ doTest(true);
+ }
+ public void testUncheckedCasts() {
+ doTest(true);
+ }
+ public void testUncheckedOverriding() {
+ doTest(true);
+ }
+ public void testWildcardTypes() {
+ doTest(true);
+ }
+ public void testConvertibleTypes() {
+ doTest(true);
+ }
+ public void testIntersectionTypes() {
+ doTest(true);
+ }
+ public void testVarargs() {
+ doTest(true);
+ }
+ public void testTypeArgsOnRaw() {
+ doTest();
+ }
+ public void testConditionalExpression() {
+ doTest();
+ }
+ public void testUnused() {
+ doTest(true);
+ }
+ public void testIDEADEV7337() {
+ doTest(true);
+ }
+ public void testIDEADEV10459() {
+ doTest(true);
+ }
+ public void testIDEADEV12951() {
+ doTest(true);
+ }
+ public void testIDEADEV13011() {
+ doTest(true);
+ }
+ public void testIDEADEV14006() {
+ doTest(true);
+ }
+ public void testIDEADEV14103() {
+ doTest(true);
+ }
+ public void testIDEADEV15534() {
+ doTest(true);
+ }
+ public void testIDEADEV23157() {
+ doTest(true);
+ }
+ public void testIDEADEV24166() {
+ doTest(true);
+ }
+ public void testIDEADEV57343() {
+ doTest();
+ }
+ public void testSOE() {
+ doTest(true);
+ }
+ public void testGenericExtendException() {
+ doTest();
+ }
+ public void testSameErasureDifferentReturnTypes() {
+ doTest();
+ }
+ public void testDeepConflictingReturnTypes() {
+ doTest();
+ }
+ public void testInheritFromTypeParameter() {
+ doTest();
+ }
+ public void testAnnotationsAsPartOfModifierList() {
+ doTest();
+ }
+ public void testImplementAnnotation() {
+ doTest();
+ }
+ public void testOverrideAtLanguageLevel6() {
+ doTest();
+ }
+ public void testSuperMethodCallWithErasure() {
+ doTest();
+ }
+ public void testWildcardCastConversion() {
+ doTest();
+ }
+ public void testTypeWithinItsWildcardBound() {
+ doTest();
+ }
+ public void testMethodSignatureEquality() {
+ doTest();
+ }
+ public void testInnerClassRef() {
+ doTest();
+ }
+ public void testPrivateInnerClassRef() {
+ doTest();
+ }
+ public void testWideningCastToTypeParam() {
+ doTest();
+ }
+ public void testCapturedWildcardAssignments() {
+ doTest();
+ }
+ public void testTypeParameterBoundVisibility() {
+ doTest();
+ }
+ public void testUncheckedWarningsLevel6() {
+ doTest(true);
+ }
+ public void testIDEA77991() {
+ doTest();
+ }
+ public void testIDEA80386() {
+ doTest();
+ }
+ public void testIDEA66311() {
+ doTest();
+ }
+ public void testIDEA67672() {
+ doTest();
+ }
+ public void testIDEA88895() {
+ doTest();
+ }
+ public void testIDEA67667() {
+ doTest();
+ }
+ public void testIDEA66311_16() {
+ doTest();
+ }
+ public void _testIDEA76283() {//todo bounds
+ doTest();
+ }
+ public void testIDEA74899() {
+ doTest();
+ }
+ public void testIDEA63291() {
+ doTest();
+ }
+ public void testIDEA72912() {
+ doTest();
+ }
+ public void testIllegalGenericTypeInInstanceof() {
+ doTest();
+ }
+ public void testIDEA57339() {
+ doTest();
+ }
+ public void testIDEA57340() {
+ doTest();
+ }
+ public void testIDEA89771() {
+ doTest();
+ }
+ public void testIDEA89801() {
+ doTest();
+ }
+ public void testIDEA67681() {
+ doTest();
+ }
+ public void testIDEA67599() {
+ doTest();
+ }
+ public void testIDEA57668() {
+ doTest();
+ }
+ public void testIDEA57667() {
+ doTest();
+ }
+ public void testIDEA57650() {
+ doTest();
+ }
+ public void testIDEA57378() {
+ doTest();
+ }
+ public void testIDEA57557() {
+ doTest();
+ }
+ public void testIDEA57563() {
+ doTest();
+ }
+ public void testIDEA57275() {
+ doTest();
+ }
+ public void testIDEA57533() {
+ doTest();
+ }
+ public void testIDEA57509() {
+ doTest();
+ }
+ public void testIDEA57410() {
+ doTest();
+ }
+ public void testIDEA57411() {
+ doTest();
+ }
+ public void testIDEA57484() {
+ doTest();
+ }
+ public void _testIDEA57485() {//todo
+ doTest();
+ }
+ public void testIDEA57486() {
+ doTest();
+ }
+ public void testIDEA57492() {
+ doTest();
+ }
+ public void testIDEA57493() {
+ doTest();
+ }
+ public void testIDEA57495() {
+ doTest();
+ }
+ public void testIDEA57494() {
+ doTest();
+ }
+ public void testIDEA57496() {
+ doTest();
+ }
+ public void testIDEA57264() {
+ doTest();
+ }
+ public void testIDEA57315() {
+ doTest();
+ }
+ public void testIDEA57346() {
+ doTest();
+ }
+ public void testIDEA57284() {
+ doTest();
+ }
+ public void testIDEA57286() {
+ doTest();
+ }
+ public void testIDEA57307() {
+ doTest(true);
+ }
+ public void testIDEA57308() {
+ doTest();
+ }
+ public void testIDEA57310() {
+ doTest();
+ }
+ public void testIDEA57311() {
+ doTest();
+ }
+ public void testIDEA57309() {
+ doTest();
+ }
+ public void testIDEA90802() {
+ doTest();
+ }
+ public void testIDEA70370() {
+ doTest(true);
+ }
+ public void testInaccessibleThroughWildcard() {
+ doTest();
+ }
+ public void testInconvertibleTypes() {
+ doTest();
+ }
+ public void testIncompatibleReturnType() {
+ doTest();
+ }
+ public void testContinueInferenceAfterFirstRawResult() {
+ doTest();
+ }
+ public void testDoNotAcceptLowerBoundIfRaw() {
+ doTest();
+ }
+ public void testStaticOverride() {
+ doTest();
+ }
+ public void testTypeArgumentsGivenOnRawType() {
+ doTest();
+ }
+ public void testSelectFromTypeParameter() {
+ doTest();
+ }
+ public void testTypeArgumentsGivenOnAnonymousClassCreation() {
+ doTest();
+ }
+
+ public void testIDEA94011() {
+ doTest();
+ }
+ public void testDifferentTypeParamsInOverloadedMethods() {
+ doTest(true);
+ }
+
+ public void testIDEA91626() {
+ doTest(true);
+ }
+ public void testIDEA92022() {
+ doTest();
+ }
+ public void testRawOnParameterized() {
+ doTest();
+ }
+ public void testFailedInferenceWithBoxing() {
+ doTest();
+ }
+ public void testFixedFailedInferenceWithBoxing() {
+ doTest();
+ }
+ public void testInferenceWithBoxingCovariant() {
+ doTest();
+ }
+ public void testSuperWildcardIsNotWithinItsBound() {
+ doTest();
+ }
+ public void testSpecificReturnType() {
+ doTest();
+ }
+ public void testParameterizedParameterBound() {
+ doTest();
+ }
+ public void testInstanceClassInStaticContextAccess() {
+ doTest();
+ }
+ public void testFlattenIntersectionType() {
+ doTest();
+ }
+ public void testIDEA97276() {
+ doTest();
+ }
+ public void testWildcardsBoundsIntersection() {
+ doTest();
+ }
+ public void testOverrideWithMoreSpecificReturn() {
+ doTest();
+ }
+ public void testIDEA97888() {
+ doTest();
+ }
+ public void testMethodCallParamsOnRawType() {
+ doTest();
+ }
+ public void testIDEA98421() {
+ doTest();
+ }
+ public void testErasureTypeParameterBound() {
+ doTest();
+ }
+ public void testThisAsAccessObject() {
+ doTest();
+ }
+ public void testIDEA67861() {
+ doTest();
+ }
+ public void testIDEA67597() {
+ doTest();
+ }
+ public void testIDEA57539() {
+ doTest();
+ }
+ public void testIDEA67570() {
+ doTest();
+ }
+ public void testIDEA99061() {
+ doTest();
+ }
+ public void testIDEA99347() {
+ doTest();
+ }
+ public void testIDEA86875() {
+ doTest();
+ }
+ public void testIDEA103760(){
+ doTest();
+ }
+ public void testIDEA105846(){
+ doTest();
+ }
+ public void testIDEA105695(){
+ doTest();
+ }
+ public void testIDEA104992(){
+ doTest();
+ }
+ public void testIDEA57446(){
+ doTest();
+ }
+ public void testIDEA67677(){
+ doTest();
+ }
+ public void testIDEA67798(){
+ doTest();
+ }
+ public void testIDEA57534(){
+ doTest();
+ }
+ public void testIDEA57482(){
+ doTest();
+ }
+ public void testIDEA67577(){
+ doTest();
+ }
+ public void testIDEA57413(){
+ doTest();
+ }
+ public void testIDEA57265(){
+ doTest();
+ }
+ public void testIDEA57271(){
+ doTest();
+ }
+ public void testIDEA57272(){
+ doTest();
+ }
+ public void testIDEA57285(){
+ doTest();
+ }
+ public void testIDEA65066(){
+ doTest();
+ }
+ public void testIDEA67998(){
+ doTest();
+ }
+ public void testIDEA18425(){
+ doTest();
+ }
+ public void testIDEA27080(){
+ doTest();
+ }
+ public void testIDEA22079(){
+ doTest();
+ }
+ public void testIDEA21602(){
+ doTest();
+ }
+ public void testIDEA21602_7(){
+ doTest();
+ }
+
+ public void testIDEA21597() throws Exception {
+ doTest();
+ }
+ public void testIDEA20573() throws Exception {
+ doTest();
+ }
+ public void testIDEA20244() throws Exception {
+ doTest();
+ }
+ public void testIDEA22005() throws Exception {
+ doTest();
+ }
+ public void testIDEA57259() throws Exception {
+ doTest();
+ }
+ public void testIDEA107957() throws Exception {
+ doTest();
+ }
+ public void testIDEA109875() throws Exception {
+ doTest();
+ }
+ public void testIDEA106964() throws Exception {
+ doTest();
+ }
+ public void testIDEA107782() throws Exception {
+ doTest();
+ }
+ public void testInheritedWithDifferentArgsInTypeParams() throws Exception {
+ doTest();
+ }
+ public void testIllegalForwardReferenceInTypeParameterDefinition() throws Exception {
+ doTest();
+ }
+
+ public void testIDEA57877() throws Exception {
+ doTest();
+ }
+ public void testIDEA110568() throws Exception {
+ doTest();
+ }
+ public void testSelfRef() throws Exception {
+ doTest();
+ }
+ public void testTypeParamsCyclicInference() throws Exception {
+ doTest();
+ }
+ public void testCaptureTopLevelWildcardsForConditionalExpression() throws Exception {
+ doTest();
+ }
+ public void testGenericsOverrideMethodInRawInheritor() throws Exception {
+ doTest();
+ }
+
+ public void testIDEA107654() throws Exception {
+ doTest();
+ }
+
+ public void testIDEA55510() throws Exception {
+ doTest();
+ }
+
+ public void testIDEA27185(){
+ doTest();
+ }
+ public void testIDEA67571(){
+ doTest();
+ }
+ public void _testTypeArgumentsOnRawType(){//todo
+ doTest();
+ }
+
+ public void testTypeArgumentsOnRawType17(){
+ doTest();
+ }
+
+ public void testWildcardsOnRawTypes() {
+ doTest();
+ }
+ public void testDisableWithinBoundsCheckForSuperWildcards() {
+ doTest();
+ }
+
+ public void testIDEA108287() throws Exception {
+ doTest();
+ }
+
+ public void testIDEA77128() throws Exception {
+ doTest();
+ }
+
+ public void testDisableCastingToNestedWildcards() throws Exception {
+ doTest();
+ }
+
+ public void testBooleanInferenceFromIfCondition() throws Exception {
+ doTest();
+ }
+
+ public void testMethodCallOnRawTypesExtended() throws Exception {
+ doTest();
+ }
+
+ public void testIDEA104100() {
+ doTest();
+ }
+ public void testIDEA104160() {
+ doTest();
+ }
+ public void testSOEInLeastUpperClass() {
+ doTest();
+ }
+
+ public void testIDEA57334() {
+ doTest();
+ }
+
+ public void testIDEA57325() {
+ doTest();
+ }
+ public void testIDEA67835() {
+ doTest();
+ }
+ public void testIDEA67744() {
+ doTest();
+ }
+ public void testIDEA67682() {
+ doTest();
+ }
+ public void testIDEA57391() {
+ doTest();
+ }
+ public void testIDEA110869() {
+ doTest();
+ }
+ /*public void testIDEA110947() { doTest5(false); }*/
+ public void testIDEA112122() {
+ doTest();
+ }
+ public void testNoInferenceFromTypeCast() {
+ doTest();
+ }
+ public void testCaptureWildcardsInTypeCasts() {
+ doTest();
+ }
+ public void testIDEA111085() {
+ doTest();
+ }
+ public void testIDEA109556() {
+ doTest();
+ }
+ public void testIDEA107440() {
+ doTest();
+ }
+ public void testIDEA57289() {
+ doTest();
+ }
+ public void testIDEA57439() {
+ doTest();
+ }
+ public void testIDEA57312() {
+ doTest();
+ }
+ public void testIDEA67865() {
+ doTest();
+ }
+ public void testBoxingSpecific() {
+ doTest();
+ }
+ public void testIDEA67843() { //fixme need to change test
+ doTest();
+ }
+ public void testAmbiguousTypeParamVsConcrete() {
+ doTest();
+ }
+ public void testRawAssignments() throws Exception {
+ doTest();
+ }
+ public void testIDEA87860() throws Exception {
+ doTest();
+ }
+
+ private void doTest() {
+ doTest(false);
+ }
+
+ private void doTest(boolean warnings) {
+ LanguageLevelProjectExtension.getInstance(getJavaFacade().getProject()).setLanguageLevel(LanguageLevel.JDK_1_8);
+ IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), myTestRootDisposable);
+ final PsiResolveHelperImpl helper = (PsiResolveHelperImpl)JavaPsiFacade.getInstance(getProject()).getResolveHelper();
+ helper.setTestHelper(new PsiGraphInferenceHelper(getPsiManager()));
+ try {
+ doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false);
+ }
+ finally {
+ helper.setTestHelper(null);
+ }
+ }
+
+
+ public void testIDEA67584() throws Exception {
+ doTest();
+ }
+ public void testIDEA113225() throws Exception {
+ doTest();
+ }
+
+ public void _testJavaUtilCollections_NoVerify() throws Exception { //todo
+ PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));
+ assertNotNull(collectionsClass);
+ collectionsClass = (PsiClass)collectionsClass.getNavigationElement();
+ final String text = collectionsClass.getContainingFile().getText();
+ configureFromFileText("Collections.java", text.replaceAll("\r", "\n"));
+ final PsiResolveHelperImpl helper = (PsiResolveHelperImpl)JavaPsiFacade.getInstance(getProject()).getResolveHelper();
+ helper.setTestHelper(new PsiGraphInferenceHelper(getPsiManager()));
+ try {
+ doTestConfiguredFile(false, false, null);
+ }
+ finally {
+ helper.setTestHelper(null);
+ }
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java
index be7ff01..99c7c27 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java
@@ -26,6 +26,6 @@
}
private void doTest() throws Exception {
- doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
+ doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
}
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ExceptionVariablesInferenceTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ExceptionVariablesInferenceTest.java
index 1e665ac..182b9f2 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ExceptionVariablesInferenceTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ExceptionVariablesInferenceTest.java
@@ -42,6 +42,6 @@
}
private void doTest(final boolean checkWarnings) throws Exception {
- doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
+ doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
}
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java
index 84e60d5..1071f19 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java
@@ -79,12 +79,16 @@
doTest();
}
+ public void testDefaultConstructorAsArgument() throws Exception {
+ doTest();
+ }
+
private void doTest() throws Exception {
doTest(false);
}
private void doTest(final boolean checkWarnings) throws Exception {
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable());
- doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
+ doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
}
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
index cf99110..f2e23bd 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
@@ -37,6 +37,6 @@
}
private void doTest(boolean checkWarnings, boolean checkInfos) {
- doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkInfos);
+ doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkInfos);
}
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java
index 633beb0..b6f6654 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java
@@ -51,7 +51,7 @@
public void testAmbiguityRawGenerics() { doTest(); }
public void testDefaultMethod() { doTest(); }
public void testLambdaOnVarargsPlace() { doTest(); }
- public void testLambdaRawOrNot() { doTest(); }
+ public void testLambdaRawOrNot() { doTest(); } //todo incorrect testdata
public void testReturnTypeCompatibility1() { doTest(); }
public void testNoInferenceResult() { doTest(); }
public void testInferenceFromArgs() { doTest(); }
@@ -92,12 +92,13 @@
public void testFunctionalInterfaceCheck() { doTest();}
public void testUnderscores() { doTest(true);}
public void testReturnTypeAmbiguity() { doTest();}
+ public void testWildcardsAndFormalLambdaParams() {doTest();}
private void doTest() {
doTest(false);
}
private void doTest(final boolean checkWarnings) {
- doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
+ doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
}
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaInferenceTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaInferenceTest.java
index 6584cdc..96e6058 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaInferenceTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaInferenceTest.java
@@ -30,6 +30,6 @@
}
private void doTest() throws Exception {
- doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
+ doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
}
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java
index c27dc9c..94ca90d 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java
@@ -30,6 +30,6 @@
public void testInferFromFormal() { doTest(); }
private void doTest() {
- doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
+ doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
}
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java
index 17d7bd1..36f98aa 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java
@@ -35,6 +35,6 @@
public void testIntersection() { doTest(); }
public void testSer() { doTest(); }
private void doTest() {
- doTest(BASE_PATH + "/" + getTestName(false) + ".java", true, false);
+ doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", true, false);
}
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
index b0b8751..3559d65 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
@@ -95,6 +95,6 @@
private void doTest(boolean warnings) {
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable());
- doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false);
+ doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false);
}
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/PsiPolyExpressionUtilTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/PsiPolyExpressionUtilTest.java
index b892318..cca3bd5 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/PsiPolyExpressionUtilTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/PsiPolyExpressionUtilTest.java
@@ -16,6 +16,7 @@
package com.intellij.codeInsight.daemon.lambda;
import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
@@ -79,4 +80,41 @@
assertNotNull(elementAtCaret);
return PsiTreeUtil.getParentOfType(elementAtCaret, PsiExpression.class);
}
+
+ public void testPertinentLambdaExpression() throws Exception {
+ assertTrue(doTestLambdaPertinent(" void bar(List<Runnable> l) {" +
+ " foo(() <caret>-> {}, l);" +
+ " }"));
+ }
+
+ public void testPertinentImplicitLambdaExpression() throws Exception {
+ assertTrue(doTestLambdaPertinent(" void bar(List<Comparable<String>> l) {" +
+ " foo((String s) <caret>-> 1, l);" +
+ " }"));
+ }
+
+ public void testPertinentNestedLambdaExpression() throws Exception {
+ assertTrue(doTestLambdaPertinent(" interface Fun<I, O> { O inOut(I i);}\n" +
+ " void bar(List<Fun<String, Fun<String, String>>> l) {" +
+ " foo((sIn, sOut) -> (sInInner, sOutInner) <caret>-> sOutInner, l);" +
+ " }"));
+ }
+
+ private boolean doTestLambdaPertinent(final String barText) {
+ myFixture.configureByText("Foo.java", "import java.util.*;" +
+ "class Foo {" +
+ " <T> T foo(T t, List<T> lT) {" +
+ " }" +
+ barText +
+ "}");
+ final PsiElement elementAtCaret = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
+ assertNotNull(elementAtCaret);
+ final PsiExpression psiExpression = PsiTreeUtil.getParentOfType(elementAtCaret, PsiExpression.class);
+ assertInstanceOf(psiExpression, PsiLambdaExpression.class);
+ final PsiClass aClass = myFixture.findClass("Foo");
+ assertNotNull(aClass);
+ final PsiMethod[] meths = aClass.findMethodsByName("foo", false);
+ assertTrue(meths.length == 1);
+ return InferenceSession.isPertinentToApplicability(psiExpression, meths[0]);
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceBackwardTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceBackwardTest.java
index fd9369a..07be23a 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceBackwardTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceBackwardTest.java
@@ -31,7 +31,6 @@
import com.intellij.psi.PsiFile;
import com.intellij.slicer.SliceAnalysisParams;
import com.intellij.slicer.SliceHandler;
-import com.intellij.slicer.SliceManager;
import com.intellij.slicer.SliceUsage;
import com.intellij.util.CommonProcessors;
import com.intellij.util.containers.IntArrayList;
@@ -59,7 +58,7 @@
params.scope = new AnalysisScope(getProject());
params.dataFlowToThis = true;
- SliceUsage usage = SliceManager.createRootUsage(element, params);
+ SliceUsage usage = SliceUsage.createRootUsage(element, params);
checkUsages(usage, true, myFlownOffsets);
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceForwardTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceForwardTest.java
index 69c3547..7b2d307 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceForwardTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceForwardTest.java
@@ -23,7 +23,6 @@
import com.intellij.psi.PsiElement;
import com.intellij.slicer.SliceAnalysisParams;
import com.intellij.slicer.SliceForwardHandler;
-import com.intellij.slicer.SliceManager;
import com.intellij.slicer.SliceUsage;
import com.intellij.util.containers.IntArrayList;
import gnu.trove.TIntObjectHashMap;
@@ -49,7 +48,7 @@
SliceAnalysisParams params = new SliceAnalysisParams();
params.scope = new AnalysisScope(getProject());
params.dataFlowToThis = false;
- SliceUsage usage = SliceManager.createRootUsage(element, params);
+ SliceUsage usage = SliceUsage.createRootUsage(element, params);
SliceBackwardTest.checkUsages(usage, false, myFlownOffsets);
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceTreeTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceTreeTest.java
index 624ec7f..771cfe3 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceTreeTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceTreeTest.java
@@ -1,11 +1,9 @@
package com.intellij.codeInsight.slice;
import com.intellij.analysis.AnalysisScope;
-import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase;
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.ide.util.treeView.AbstractTreeNode;
-import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.impl.ToolWindowHeadlessManagerImpl;
@@ -34,7 +32,7 @@
params.scope = new AnalysisScope(getProject());
params.dataFlowToThis = true;
- SliceUsage usage = SliceManager.createRootUsage(element, params);
+ SliceUsage usage = SliceUsage.createRootUsage(element, params);
SlicePanel panel = new SlicePanel(getProject(), true, new SliceRootNode(getProject(), new DuplicateMap(), usage), false, ToolWindowHeadlessManagerImpl.HEADLESS_WINDOW) {
@@ -252,7 +250,7 @@
}
private static void checkStructure(final SliceNode root, @NonNls String dataExpected) {
- List<SliceNode> actualNodes = new ArrayList<SliceNode>((Collection<? extends SliceNode>)root.getChildren());
+ List<SliceNode> actualNodes = new ArrayList<SliceNode>((Collection)root.getChildren());
Collections.sort(actualNodes, SliceTreeBuilder.SLICE_NODE_COMPARATOR);
Object[] actualStrings = ContainerUtil.map2Array(actualNodes, new Function<SliceNode, Object>() {
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
index b0df0fb..cc9dee3 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
@@ -286,6 +286,7 @@
public void testContractAnnotation() { doTest(); }
public void testContractInLoopNotTooComplex() { doTest(); }
public void testContractWithNullable() { doTest(); }
+ public void testContractPreservesUnknownNullability() { doTest(); }
public void testBoxingImpliesNotNull() { doTest(); }
public void testLargeIntegersAreNotEqualWhenBoxed() { doTest(); }
@@ -295,6 +296,12 @@
public void testAnonymousMethodIndependence() { doTest(); }
public void testAnonymousFieldIndependence() { doTest(); }
public void testNoConfusionWithAnonymousConstantInitializer() { doTest(); }
+ public void testForeachOverWildcards() { doTest(); }
+ public void testFinalGetter() { doTest(); }
+
+ public void testManySequentialIfsNotComplex() { doTest(); }
+ public void testLongDisjunctionsNotComplex() { doTest(); }
+ public void testWhileNotComplex() { doTest(); }
public void _testNullCheckBeforeInstanceof() { doTest(); }
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java
index 480a910..1bd64f4 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java
@@ -15,6 +15,9 @@
*/
package com.intellij.codeInspection;
+import com.intellij.codeInsight.completion.NormalCompletionTest;
+import com.intellij.codeInsight.completion.SmartTypeCompletionTest;
+import com.intellij.codeInsight.slice.SliceBackwardTest;
import com.intellij.codeInsight.slice.SliceTreeTest;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -25,6 +28,9 @@
suite.addTestSuite(DataFlowInspectionTest.class);
suite.addTestSuite(DataFlowInspectionAncientTest.class);
suite.addTestSuite(SliceTreeTest.class);
+ suite.addTestSuite(SliceBackwardTest.class);
+ suite.addTestSuite(SmartTypeCompletionTest.class);
+ suite.addTestSuite(NormalCompletionTest.class);
return suite;
}
}
diff --git a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
index e579fbb..49ff835 100644
--- a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
+++ b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
@@ -478,36 +478,36 @@
private static void runFindForwardAndBackward(FindManager findManager, FindModel findModel, String text, String ext) {
findModel.setForward(true);
LightVirtualFile file = new LightVirtualFile("A."+ext, text);
- int prevousOffset;
+ int previousOffset;
FindResult findResult = findManager.findString(text, 0, findModel, file);
assertTrue(findResult.isStringFound());
- prevousOffset = findResult.getStartOffset();
+ previousOffset = findResult.getStartOffset();
findResult = findManager.findString(text, findResult.getEndOffset(), findModel, file);
assertTrue(findResult.isStringFound());
- assertTrue(findResult.getStartOffset() > prevousOffset);
- prevousOffset = findResult.getStartOffset();
+ assertTrue(findResult.getStartOffset() > previousOffset);
+ previousOffset = findResult.getStartOffset();
findResult = findManager.findString(text, findResult.getEndOffset(), findModel, file);
assertTrue(findResult.isStringFound());
- assertTrue(findResult.getStartOffset() > prevousOffset);
+ assertTrue(findResult.getStartOffset() > previousOffset);
findModel.setForward(false);
findResult = findManager.findString(text, text.length(), findModel, file);
assertTrue(findResult.isStringFound());
- prevousOffset = findResult.getStartOffset();
+ previousOffset = findResult.getStartOffset();
- findResult = findManager.findString(text, prevousOffset, findModel, file);
+ findResult = findManager.findString(text, previousOffset, findModel, file);
assertTrue(findResult.isStringFound());
- assertTrue(prevousOffset > findResult.getStartOffset() );
+ assertTrue(previousOffset > findResult.getStartOffset() );
- prevousOffset = findResult.getStartOffset();
+ previousOffset = findResult.getStartOffset();
- findResult = findManager.findString(text, prevousOffset, findModel, file);
+ findResult = findManager.findString(text, previousOffset, findModel, file);
assertTrue(findResult.isStringFound());
- assertTrue(prevousOffset > findResult.getStartOffset() );
+ assertTrue(previousOffset > findResult.getStartOffset() );
}
public void testFindInJavaDocs() throws Exception{
@@ -547,4 +547,35 @@
runFindInCommentsAndLiterals(findManager, findModel, text, "cs");
}
+
+ public void testFindInLiteralToSkipQuotes() throws Exception{
+ FindManager findManager = FindManager.getInstance(myProject);
+
+ FindModel findModel = new FindModel();
+ findModel.setStringToFind("^done$");
+ findModel.setWholeWordsOnly(false);
+ findModel.setRegularExpressions(true);
+ findModel.setFromCursor(false);
+ findModel.setGlobal(true);
+ findModel.setMultipleFiles(false);
+ findModel.setProjectScope(true);
+
+ String text = "\"done\"; 'done'; 'done' \"done2\"";
+
+ findModel.setInStringLiteralsOnly(true);
+ findModel.setInCommentsOnly(false);
+ runFindForwardAndBackward(findManager, findModel, text, "java");
+
+ text = "def n = \"\"\"done\"\"\"\n def n = /done/\n def n = \"done\"\n def n = \"done2\"";
+
+ runFindForwardAndBackward(findManager, findModel, text, "groovy");
+
+ text = "\"\"; \"done\"; 'done'; 'done' \"done2\"";
+
+ findModel.setStringToFind("done");
+ findModel.setWholeWordsOnly(true);
+ findModel.setRegularExpressions(false);
+
+ runFindForwardAndBackward(findManager, findModel, text, "java");
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java b/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java
index 72e9c2a..80dda6dc 100644
--- a/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java
+++ b/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java
@@ -42,6 +42,6 @@
public void testMatcher1() throws Exception {checkTree("ico");}
public void testMatcher2() throws Exception {checkTree("ico");}
- @Bombed(user = "peter", month = Calendar.SEPTEMBER, day = 20)
+ @Bombed(user = "peter", month = Calendar.DECEMBER, day = 20)
public void testAnonymousMatcher2() throws Exception {checkTree("ico");}
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy
index 0b4e838..b456d41 100644
--- a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy
@@ -131,4 +131,16 @@
}'''
doTest(initial: text, expected: text, rules: [rule(CLASS)] )
}
+
+ void "test statements on the same line"() {
+ def before = '''\
+
+
+
+public enum Sender {a, b; private String value;
+}
+'''
+ doTest(initial: before, expected: before)
+ }
+
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBracesTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBracesTest.java
index 889e591..2e2d0c5 100644
--- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBracesTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBracesTest.java
@@ -155,4 +155,14 @@
"}";
doTextTest(text, text);
}
+
+ public void testSimpleMethodsInOneLineEvenIfExceedsRightMargin() {
+ getSettings().KEEP_SIMPLE_METHODS_IN_ONE_LINE = true;
+ getSettings().getRootSettings().RIGHT_MARGIN = 90;
+ String text = "public class Repr2 {\n" +
+ " public void start() { System.out.println(\"kfjsdkfjsdkfjskdjfslkdjfklsdjfklsdjfksjdfkljsdkfjsd!\"); }\n" +
+ "}";
+ doTextTest(text, text);
+ }
+
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java
index be33547..b347207 100644
--- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java
@@ -536,4 +536,13 @@
getIndentOptions().USE_TAB_CHARACTER = true;
doTextTest(initial, expected);
}
+
+ public void testLambdaIndentation() throws Exception {
+ String before = "Runnable r = () ->\n" +
+ "{\n" +
+ " System.out.println(\"olo\");\n" +
+ "};";
+ doMethodTest(before, before);
+ }
+
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterSpaceTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterSpaceTest.java
index ab35904..e78f718 100644
--- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterSpaceTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterSpaceTest.java
@@ -33,6 +33,34 @@
"class Foo {\n" + " Map<String, String> map() {\n" + " }\n" + "}");
}
+ public void testDoNotPlaceStatementsOnOneLineIfFirstEndsWithSingleLineComment() {
+ getSettings().KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE = true;
+ getSettings().KEEP_LINE_BREAKS = false;
+ String before = "public class Reproduce {\n" +
+ " public void start() {\n" +
+ " if (true)\n" +
+ " return; // comment\n" +
+ " final int count = 5;\n" +
+ " for (int i = 0; i < count; i++) {\n" +
+ " System.out.println(\"AAA!\");\n" +
+ " System.out.println(\"BBB!\"); // ololol\n" +
+ " System.out.println(\"asda\"); /* ololo */\n" +
+ " System.out.println(\"booo\");\n" +
+ " }\n" +
+ " }\n" +
+ "}";
+ String after = "public class Reproduce {\n" +
+ " public void start() {\n" +
+ " if (true) return; // comment\n" +
+ " final int count = 5; for (int i = 0; i < count; i++) {\n" +
+ " System.out.println(\"AAA!\"); System.out.println(\"BBB!\"); // ololol\n" +
+ " System.out.println(\"asda\"); /* ololo */ System.out.println(\"booo\");\n" +
+ " }\n" +
+ " }\n" +
+ "}";
+ doTextTest(before, after);
+ }
+
public void testSpaceBeforeAnnotationParamArray() {
// Inspired by IDEA-24329
getSettings().SPACE_BEFORE_ANNOTATION_ARRAY_INITIALIZER_LBRACE = true;
diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java
index 695ac71..68dbf09 100644
--- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java
@@ -2972,4 +2972,33 @@
" }\n" +
"}");
}
+
+ public void testCommaInMethodDeclParamsList() {
+ getSettings().SPACE_AFTER_COMMA = true;
+ String before = "public class Test {\n" +
+ " public static void act( int a , int b , int c , int d) {\n" +
+ " act(1,2,3,4);\n" +
+ " }\n" +
+ "}\n";
+ String after = "public class Test {\n" +
+ " public static void act(int a, int b, int c, int d) {\n" +
+ " act(1, 2, 3, 4);\n" +
+ " }\n" +
+ "}\n";
+ doTextTest(before, after);
+ getSettings().SPACE_AFTER_COMMA = false;
+ before = "public class Test {\n" +
+ " public static void act( int a , int b , int c , int d) {\n" +
+ " act(1 , 2 , 3 , 4);\n" +
+ " }\n" +
+ "}\n";
+ after = "public class Test {\n" +
+ " public static void act(int a,int b,int c,int d) {\n" +
+ " act(1,2,3,4);\n" +
+ " }\n" +
+ "}\n";
+ doTextTest(before, after);
+ }
+
+
}
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/EncapsulateFieldsTest.java b/java/java-tests/testSrc/com/intellij/refactoring/EncapsulateFieldsTest.java
index fd536cb..dd3af4b 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/EncapsulateFieldsTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/EncapsulateFieldsTest.java
@@ -43,11 +43,11 @@
}
public void testDiffWithReturnTypeOnly() throws Exception {
- doTest("i", "There already is a method <b><code>Test setI(int)</code></b> which differs from setter <b><code>setI</code></b> by return type only.");
+ doTest("i", "There is already method <b><code>Test setI(int)</code></b> which differs from setter <b><code>setI</code></b> by return type only");
}
public void testDiffWithReturnTypeOnlyInHierarchy() throws Exception {
- doTest("i", "There already is a method <b><code>Super setI(int)</code></b> which differs from setter <b><code>setI</code></b> by return type only.");
+ doTest("i", "There is already method <b><code>Super setI(int)</code></b> which differs from setter <b><code>setI</code></b> by return type only");
}
public void testHideOverriderMethod() throws Exception {
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java
index b5ec296..5be5dad 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java
@@ -59,6 +59,15 @@
});
}
+ public void testReplaceAll3() throws Exception {
+ doTest(new Pass<AbstractInplaceIntroducer>() {
+ @Override
+ public void pass(AbstractInplaceIntroducer inplaceIntroduceFieldPopup) {
+ inplaceIntroduceFieldPopup.setReplaceAllOccurrences(true);
+ }
+ });
+ }
+
public void testReplaceAllMethodCalls() throws Exception {
doTest(new Pass<AbstractInplaceIntroducer>() {
@Override
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java
index 5fff219..618381a 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java
@@ -1,4 +1,20 @@
/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
* Created by IntelliJ IDEA.
* User: dsl
* Date: 07.05.2002
@@ -114,7 +130,7 @@
}
public void testSuperInExpression() throws Exception {
- doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class.");
+ doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class");
}
public void testNull() throws Exception {
@@ -150,7 +166,7 @@
}
public void testSuperWithSideEffect() throws Exception {
- doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class.");
+ doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class");
}
public void testConflictingField() throws Exception {
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java
index a447fa1..07f3a61 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java
@@ -149,8 +149,8 @@
protected boolean reportConflicts(MultiMap<PsiElement,String> conflicts, final Project project, IntroduceVariableSettings dialog) {
assertEquals(2, conflicts.size());
Collection<? extends String> conflictsMessages = conflicts.values();
- assertTrue(conflictsMessages.contains("Introducing variable may break code logic."));
- assertTrue(conflictsMessages.contains("Local variable <b><code>c</code></b> is modified in loop body."));
+ assertTrue(conflictsMessages.contains("Introducing variable may break code logic"));
+ assertTrue(conflictsMessages.contains("Local variable <b><code>c</code></b> is modified in loop body"));
return false;
}
});
@@ -242,7 +242,7 @@
}
catch (Exception e) {
assertEquals(e.getMessage(), "Error message:Cannot perform refactoring.\n" +
- "Selected block should represent an expression.");
+ "Selected block should represent an expression");
return;
}
fail("Should not be able to perform refactoring");
@@ -254,7 +254,7 @@
}
catch (Exception e) {
assertEquals(e.getMessage(), "Error message:Cannot perform refactoring.\n" +
- "Selected block should represent an expression.");
+ "Selected block should represent an expression");
return;
}
fail("Should not be able to perform refactoring");
@@ -366,7 +366,7 @@
}
catch (Exception e) {
assertEquals(e.getMessage(), "Error message:Cannot perform refactoring.\n" +
- "Selected block should represent an expression.");
+ "Selected block should represent an expression");
return;
}
fail("Should not be able to perform refactoring");
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/MoveClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/MoveClassTest.java
index bcaabef..c646301 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/MoveClassTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/MoveClassTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -78,7 +78,7 @@
fail("Conflicts expected");
}
catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
- assertEquals("A package-local class <b><code>Class2</code></b> will no longer be accessible from field <b><code>User.class2</code></b>", e.getMessage());
+ assertEquals("Package-local class <b><code>Class2</code></b> will no longer be accessible from field <b><code>User.class2</code></b>", e.getMessage());
}
}
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java b/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java
index 2caa921..9bc767a 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.refactoring;
import com.intellij.JavaTestUtil;
@@ -172,7 +187,7 @@
doTest("foo1");
}
catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
- Assert.assertEquals("Method with same erasure is already defined in the class <b><code>RenameTest</code></b>.", e.getMessage());
+ Assert.assertEquals("Method with same erasure is already defined in the class <b><code>RenameTest</code></b>", e.getMessage());
return;
}
fail("Conflicts were not found");
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java b/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java
index f72add5..f771665 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -81,7 +81,7 @@
doTestInplaceRename("bar");
}
catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
- assertEquals("Method bar() is already defined in the class <b><code>Foo</code></b>.", e.getMessage());
+ assertEquals("Method bar() is already defined in the class <b><code>Foo</code></b>", e.getMessage());
checkResultByFile(BASE_PATH + getTestName(false) + "_after.java");
return;
}
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameMethodMultiTest.java b/java/java-tests/testSrc/com/intellij/refactoring/RenameMethodMultiTest.java
index f2b52e1..6da0cdf 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/RenameMethodMultiTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameMethodMultiTest.java
@@ -1,5 +1,21 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.refactoring;
+import com.intellij.JavaTestUtil;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaPsiFacade;
@@ -7,7 +23,6 @@
import com.intellij.psi.PsiMethod;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.rename.RenameProcessor;
-import com.intellij.JavaTestUtil;
import org.junit.Assert;
/**
@@ -51,7 +66,7 @@
catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
Assert.assertEquals("Renaming method will override final \"method <b><code>A.finalMethod()</code></b>\"\n" +
"Method finalMethod() will override \n" +
- "a method of the base class <b><code>p.A</code></b>.", e.getMessage());
+ "a method of the base class <b><code>p.A</code></b>", e.getMessage());
return;
}
fail("Conflicts were not found");
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java
index 6d66a43..4cf3229 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.refactoring.inline;
import com.intellij.JavaTestUtil;
@@ -108,11 +123,11 @@
}
public void testAnotherDefinitionUsed() throws Exception {
- doTest(true, "Cannot perform refactoring.\nAnother variable 'bar' definition is used together with inlined one.");
+ doTest(true, "Cannot perform refactoring.\nAnother variable 'bar' definition is used together with inlined one");
}
public void testAnotherDefinitionUsed1() throws Exception {
- doTest(false, "Cannot perform refactoring.\nAnother variable 'bar' definition is used together with inlined one.");
+ doTest(false, "Cannot perform refactoring.\nAnother variable 'bar' definition is used together with inlined one");
}
public void testTypeArgumentsStatic() throws Exception {
@@ -137,7 +152,7 @@
public void testAssignmentToArrayElement() throws Exception {
doTest(true, "Cannot perform refactoring.\n" +
- "Variable 'arr' is accessed for writing.");
+ "Variable 'arr' is accessed for writing");
}
public void testArrayMethodCallInitialized() throws Exception {
@@ -150,7 +165,7 @@
public void testNonEqAssignment() throws Exception {
doTest(false, "Cannot perform refactoring.\n" +
- "Variable 'x' is accessed for writing.");
+ "Variable 'x' is accessed for writing");
}
public void testInlineFromTryCatch() throws Exception {
@@ -223,7 +238,7 @@
public void testLocalVarInsideLambdaBodyWriteUsage() throws Exception {
doTest(true, "Cannot perform refactoring.\n" +
- "Variable 'hello' is accessed for writing.");
+ "Variable 'hello' is accessed for writing");
}
private void doTest(final boolean inlineDef, String conflictMessage) throws Exception {
diff --git a/java/jdkAnnotations/java/util/annotations.xml b/java/jdkAnnotations/java/util/annotations.xml
index 9699f06c..4d202ed 100644
--- a/java/jdkAnnotations/java/util/annotations.xml
+++ b/java/jdkAnnotations/java/util/annotations.xml
@@ -462,12 +462,7 @@
<item name="java.util.Arrays void sort(short[], int, int) 0">
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
- <item name="java.util.Calendar void add(int, int) 0" >
- <annotation name="org.intellij.lang.annotations.MagicConstant">
- <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
- </annotation>
- </item>
- <item name="java.util.Calendar void clear(int) 0" >
+ <item name="java.util.Calendar boolean isSet(int) 0">
<annotation name="org.intellij.lang.annotations.MagicConstant">
<val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
</annotation>
@@ -487,26 +482,6 @@
<val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
</annotation>
</item>
- <item name="java.util.Calendar java.lang.String getDisplayName(int, int, java.util.Locale) 0">
- <annotation name="org.intellij.lang.annotations.MagicConstant">
- <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
- </annotation>
- </item>
- <item name="java.util.Calendar java.lang.String getDisplayName(int, int, java.util.Locale) 1">
- <annotation name="org.intellij.lang.annotations.MagicConstant">
- <val name="intValues" val="{java.util.Calendar.SHORT, java.util.Calendar.LONG}" />
- </annotation>
- </item>
- <item name="java.util.Calendar java.util.Map<java.lang.String,java.lang.Integer> getDisplayNames(int, int, java.util.Locale) 0">
- <annotation name="org.intellij.lang.annotations.MagicConstant">
- <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
- </annotation>
- </item>
- <item name="java.util.Calendar java.util.Map<java.lang.String,java.lang.Integer> getDisplayNames(int, int, java.util.Locale) 1">
- <annotation name="org.intellij.lang.annotations.MagicConstant">
- <val name="intValues" val="{java.util.Calendar.SHORT, java.util.Calendar.LONG, java.util.Calendar.ALL_STYLES}" />
- </annotation>
- </item>
<item name="java.util.Calendar int getFirstDayOfWeek()">
<annotation name="org.intellij.lang.annotations.MagicConstant">
<val name="intValues" val="{java.util.Calendar.SUNDAY, java.util.Calendar.MONDAY, java.util.Calendar.TUESDAY, java.util.Calendar.WEDNESDAY, java.util.Calendar.THURSDAY, java.util.Calendar.FRIDAY, java.util.Calendar.SATURDAY}" />
@@ -532,7 +507,32 @@
<val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
</annotation>
</item>
- <item name="java.util.Calendar boolean isSet(int) 0">
+ <item name="java.util.Calendar java.lang.String getDisplayName(int, int, java.util.Locale) 0">
+ <annotation name="org.intellij.lang.annotations.MagicConstant">
+ <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
+ </annotation>
+ </item>
+ <item name="java.util.Calendar java.lang.String getDisplayName(int, int, java.util.Locale) 1">
+ <annotation name="org.intellij.lang.annotations.MagicConstant">
+ <val name="intValues" val="{java.util.Calendar.SHORT, java.util.Calendar.LONG}" />
+ </annotation>
+ </item>
+ <item name="java.util.Calendar java.util.Map<java.lang.String,java.lang.Integer> getDisplayNames(int, int, java.util.Locale) 0">
+ <annotation name="org.intellij.lang.annotations.MagicConstant">
+ <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
+ </annotation>
+ </item>
+ <item name="java.util.Calendar java.util.Map<java.lang.String,java.lang.Integer> getDisplayNames(int, int, java.util.Locale) 1">
+ <annotation name="org.intellij.lang.annotations.MagicConstant">
+ <val name="intValues" val="{java.util.Calendar.SHORT, java.util.Calendar.LONG, java.util.Calendar.ALL_STYLES}" />
+ </annotation>
+ </item>
+ <item name="java.util.Calendar void add(int, int) 0" >
+ <annotation name="org.intellij.lang.annotations.MagicConstant">
+ <val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
+ </annotation>
+ </item>
+ <item name="java.util.Calendar void clear(int) 0" >
<annotation name="org.intellij.lang.annotations.MagicConstant">
<val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
</annotation>
diff --git a/java/jdkAnnotations/java/util/regex/annotations.xml b/java/jdkAnnotations/java/util/regex/annotations.xml
index b3f189e..2afbcb5 100644
--- a/java/jdkAnnotations/java/util/regex/annotations.xml
+++ b/java/jdkAnnotations/java/util/regex/annotations.xml
@@ -11,10 +11,17 @@
<val name="flagsFromClass" val="java.util.regex.Pattern.class" />
</annotation>
</item>
+ <item name='java.util.regex.Pattern java.util.regex.Matcher matcher(java.lang.CharSequence)'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
<item name="java.util.regex.Pattern java.util.regex.Pattern compile(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NonNls" />
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
+ <item name="java.util.regex.Pattern java.util.regex.Pattern compile(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.NonNls" />
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
<item name="java.util.regex.Pattern java.util.regex.Pattern compile(java.lang.String, int) 1">
<annotation name="org.intellij.lang.annotations.MagicConstant">
<val name="flagsFromClass" val="java.util.regex.Pattern.class" />
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestLexer.java b/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestLexer.java
index 26741c2..1372768 100644
--- a/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestLexer.java
+++ b/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestLexer.java
@@ -27,6 +27,7 @@
import com.intellij.lexer.LexerBase;
import com.intellij.psi.TokenType;
import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.lang.manifest.psi.ManifestTokenType;
@@ -63,7 +64,7 @@
private IElementType myTokenType;
@Override
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
this.myBuffer = buffer;
this.myEndOffset = endOffset;
myCurrentState = State.values()[initialState];
@@ -104,6 +105,7 @@
return myEndOffset;
}
+ @NotNull
@Override
public CharSequence getBufferSequence() {
return myBuffer;
diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java
index 60bf96c..52a24e8 100644
--- a/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java
+++ b/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java
@@ -24,8 +24,11 @@
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.vfs.VirtualFileFilter;
+import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.impl.source.resolve.PsiResolveHelperImpl;
+import com.intellij.psi.impl.source.resolve.graphInference.PsiGraphInferenceHelper;
import com.intellij.testFramework.ExpectedHighlightingData;
import com.intellij.testFramework.FileTreeAccessFilter;
import com.intellij.testFramework.HighlightTestInfo;
@@ -80,6 +83,18 @@
doTestConfiguredFile(checkWarnings, checkInfos, filePath);
}
+ protected void doTestNewInference(@NonNls String filePath, boolean checkWarnings, boolean checkInfos) {
+ final PsiResolveHelperImpl helper = (PsiResolveHelperImpl)JavaPsiFacade.getInstance(getProject()).getResolveHelper();
+ //helper.setTestHelper(new PsiGraphInferenceHelper(getPsiManager()));
+ try {
+ configureByFile(filePath);
+ doTestConfiguredFile(checkWarnings, checkInfos, filePath);
+ }
+ finally {
+ helper.setTestHelper(null);
+ }
+ }
+
protected void doTest(@NonNls String filePath, boolean checkWarnings, boolean checkWeakWarnings, boolean checkInfos) {
configureByFile(filePath);
doTestConfiguredFile(checkWarnings, checkWeakWarnings, checkInfos, filePath);
diff --git a/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java b/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java
index 7164207..348a1af 100644
--- a/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java
+++ b/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java
@@ -80,7 +80,7 @@
public static void enableExternalCompiler(final Project project) {
new WriteAction() {
protected void run(final Result result) {
- CompilerWorkspaceConfiguration.getInstance(project).USE_COMPILE_SERVER = true;
+ CompilerWorkspaceConfiguration.getInstance(project).USE_OUT_OF_PROCESS_BUILD = true;
ApplicationManagerEx.getApplicationEx().doNotSave(false);
JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx();
table.addJdk(table.getInternalJdk());
@@ -91,7 +91,7 @@
public static void disableExternalCompiler(final Project project) {
new WriteAction() {
protected void run(final Result result) {
- CompilerWorkspaceConfiguration.getInstance(project).USE_COMPILE_SERVER = false;
+ CompilerWorkspaceConfiguration.getInstance(project).USE_OUT_OF_PROCESS_BUILD = false;
ApplicationManagerEx.getApplicationEx().doNotSave(true);
JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx();
table.removeJdk(table.getInternalJdk());
diff --git a/java/testFramework/src/com/intellij/ide/projectWizard/NewProjectWizardTestCase.java b/java/testFramework/src/com/intellij/ide/projectWizard/NewProjectWizardTestCase.java
new file mode 100644
index 0000000..8ae8848
--- /dev/null
+++ b/java/testFramework/src/com/intellij/ide/projectWizard/NewProjectWizardTestCase.java
@@ -0,0 +1,18 @@
+package com.intellij.ide.projectWizard;
+
+import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+
+import java.io.File;
+
+/**
+ * @author Dmitry Avdeev
+ * Date: 23.09.13
+ */
+public abstract class NewProjectWizardTestCase extends ProjectWizardTestCase {
+ @Override
+ protected AbstractProjectWizard createWizard(Project project, File directory) {
+ return new NewProjectWizard(project, ModulesProvider.EMPTY_MODULES_PROVIDER, directory.getPath());
+ }
+}
diff --git a/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java b/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java
index 9620aa7..8a05be2 100644
--- a/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java
+++ b/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java
@@ -2,10 +2,11 @@
import com.intellij.ide.actions.ImportModuleAction;
import com.intellij.ide.impl.NewProjectUtil;
+import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;
import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
import com.intellij.ide.util.newProjectWizard.SelectTemplateSettings;
import com.intellij.ide.util.newProjectWizard.SelectTemplateStep;
-import com.intellij.ide.util.projectWizard.ModuleWizardStep;
+import com.intellij.ide.wizard.Step;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
@@ -38,14 +39,15 @@
* @author Dmitry Avdeev
* Date: 10/29/12
*/
-public abstract class ProjectWizardTestCase extends PlatformTestCase {
+@SuppressWarnings("unchecked")
+public abstract class ProjectWizardTestCase<T extends AbstractProjectWizard> extends PlatformTestCase {
protected final List<Sdk> mySdks = new ArrayList<Sdk>();
- protected AddModuleWizard myWizard;
+ protected T myWizard;
@Nullable
private Project myCreatedProject;
- protected Project createProjectFromTemplate(String group, String name, @Nullable Consumer<ModuleWizardStep> adjuster) throws IOException {
+ protected Project createProjectFromTemplate(String group, String name, @Nullable Consumer<Step> adjuster) throws IOException {
runWizard(group, name, null, adjuster);
try {
myCreatedProject = NewProjectUtil.createFromWizard(myWizard, null);
@@ -68,7 +70,7 @@
}
@Nullable
- protected Module createModuleFromTemplate(String group, String name, @Nullable Consumer<ModuleWizardStep> adjuster) throws IOException {
+ protected Module createModuleFromTemplate(String group, String name, @Nullable Consumer<Step> adjuster) throws IOException {
runWizard(group, name, getProject(), adjuster);
return createModuleFromWizard();
}
@@ -77,7 +79,7 @@
return new NewModuleAction().createModuleFromWizard(myProject, null, myWizard);
}
- protected void runWizard(String group, String name, Project project, @Nullable Consumer<ModuleWizardStep> adjuster) throws IOException {
+ protected void runWizard(String group, String name, Project project, @Nullable Consumer<Step> adjuster) throws IOException {
createWizard(project);
SelectTemplateStep step = (SelectTemplateStep)myWizard.getCurrentStepObject();
@@ -98,11 +100,22 @@
protected void createWizard(Project project) throws IOException {
File directory = FileUtil.createTempDirectory(getName(), "new", false);
myFilesToDelete.add(directory);
- myWizard = new AddModuleWizard(project, DefaultModulesProvider.createForProject(project), directory.getPath());
+ myWizard = createWizard(project, directory);
UIUtil.dispatchAllInvocationEvents(); // to make default selection applied
}
- protected void runWizard(Consumer<ModuleWizardStep> adjuster) {
+ protected Project createProject(Consumer<Step> adjuster) throws IOException {
+ createWizard(getProject());
+ runWizard(adjuster);
+ myCreatedProject = NewProjectUtil.createFromWizard(myWizard, null);
+ return myCreatedProject;
+ }
+
+ protected T createWizard(Project project, File directory) {
+ return (T)new AddModuleWizard(project, DefaultModulesProvider.createForProject(project), directory.getPath());
+ }
+
+ protected void runWizard(Consumer<Step> adjuster) {
while (!myWizard.isLast()) {
myWizard.doNextAction();
if (adjuster != null) {
@@ -157,7 +170,7 @@
return importFrom(path, getProject(), null, provider);
}
- protected Module importProjectFrom(String path, Consumer<ModuleWizardStep> adjuster, ProjectImportProvider... providers) {
+ protected Module importProjectFrom(String path, Consumer<Step> adjuster, ProjectImportProvider... providers) {
Module module = importFrom(path, null, adjuster, providers);
if (module != null) {
myCreatedProject = module.getProject();
@@ -166,13 +179,14 @@
}
private Module importFrom(String path,
- @Nullable Project project, Consumer<ModuleWizardStep> adjuster,
+ @Nullable Project project, Consumer<Step> adjuster,
final ProjectImportProvider... providers) {
VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath(path);
assertNotNull("Can't find " + path, file);
assertTrue(providers[0].canImport(file, project));
- myWizard = ImportModuleAction.createImportWizard(project, null, file, providers);
+ myWizard = (T)ImportModuleAction.createImportWizard(project, null, file, providers);
+ assertNotNull(myWizard);
if (myWizard.getStepCount() > 0) {
runWizard(adjuster);
}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsElementType.java b/jps/model-api/src/org/jetbrains/jps/model/JpsElementType.java
index 1adee50..5ee5146 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/JpsElementType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/JpsElementType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,13 +15,17 @@
*/
package org.jetbrains.jps.model;
+import org.jetbrains.annotations.NotNull;
+
/**
+ * Base interface for all types of elements in JPS model
+ *
+ * <p>
+ * Use {@link org.jetbrains.jps.model.ex.JpsElementTypeBase} as a base class for all implementations of this interface
+ * </p>
* @author nik
*/
-public abstract class JpsElementType<P extends JpsElement> {
- private final JpsElementChildRole<P> myPropertiesRole = new JpsElementChildRole<P>();
-
- public final JpsElementChildRole<P> getPropertiesRole() {
- return myPropertiesRole;
- }
+public interface JpsElementType<P extends JpsElement> {
+ @NotNull
+ JpsElementChildRole<P> getPropertiesRole();
}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/DirectoryArtifactType.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/DirectoryArtifactType.java
index 3b66462..79e970e 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/artifact/DirectoryArtifactType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/DirectoryArtifactType.java
@@ -16,10 +16,11 @@
package org.jetbrains.jps.model.artifact;
import org.jetbrains.jps.model.JpsDummyElement;
+import org.jetbrains.jps.model.ex.JpsElementTypeWithDummyProperties;
/**
* @author nik
*/
-public class DirectoryArtifactType extends JpsArtifactType<JpsDummyElement> {
+public class DirectoryArtifactType extends JpsElementTypeWithDummyProperties implements JpsArtifactType<JpsDummyElement> {
public static final DirectoryArtifactType INSTANCE = new DirectoryArtifactType();
}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/JarArtifactType.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/JarArtifactType.java
index c0306a9..bd36fc4 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/artifact/JarArtifactType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/JarArtifactType.java
@@ -16,10 +16,11 @@
package org.jetbrains.jps.model.artifact;
import org.jetbrains.jps.model.JpsDummyElement;
+import org.jetbrains.jps.model.ex.JpsElementTypeWithDummyProperties;
/**
* @author nik
*/
-public class JarArtifactType extends JpsArtifactType<JpsDummyElement> {
+public class JarArtifactType extends JpsElementTypeWithDummyProperties implements JpsArtifactType<JpsDummyElement> {
public static final JarArtifactType INSTANCE = new JarArtifactType();
}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactType.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactType.java
index a4a6c31..fe05178 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactType.java
@@ -19,7 +19,12 @@
import org.jetbrains.jps.model.JpsElementType;
/**
+ * Represents a type of artifacts in JPS model
+ *
+ * <p>
+ * Use {@link org.jetbrains.jps.model.ex.JpsElementTypeBase} as a base class for implementations of this interface
+ * </p>
* @author nik
*/
-public abstract class JpsArtifactType<P extends JpsElement> extends JpsElementType<P> {
+public interface JpsArtifactType<P extends JpsElement> extends JpsElementType<P> {
}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/ex/JpsElementTypeBase.java b/jps/model-api/src/org/jetbrains/jps/model/ex/JpsElementTypeBase.java
new file mode 100644
index 0000000..7894697
--- /dev/null
+++ b/jps/model-api/src/org/jetbrains/jps/model/ex/JpsElementTypeBase.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.jps.model.ex;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.JpsElement;
+import org.jetbrains.jps.model.JpsElementChildRole;
+import org.jetbrains.jps.model.JpsElementType;
+
+/**
+ * A base class for all implementations of {@link org.jetbrains.jps.model.JpsElementType}.
+ *
+ * <p>
+ * If elements of your type don't have any specific properties extend {@link JpsElementTypeWithDummyProperties} instead.
+ * </p>
+ * @author nik
+ */
+public abstract class JpsElementTypeBase<P extends JpsElement>implements JpsElementType<P> {
+ private final JpsElementChildRole<P> myPropertiesRole = new JpsElementChildRole<P>();
+
+ @NotNull
+ @Override
+ public final JpsElementChildRole<P> getPropertiesRole() {
+ return myPropertiesRole;
+ }
+}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/ex/JpsElementTypeWithDummyProperties.java b/jps/model-api/src/org/jetbrains/jps/model/ex/JpsElementTypeWithDummyProperties.java
new file mode 100644
index 0000000..630340e
--- /dev/null
+++ b/jps/model-api/src/org/jetbrains/jps/model/ex/JpsElementTypeWithDummyProperties.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.jps.model.ex;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.JpsDummyElement;
+import org.jetbrains.jps.model.JpsElementFactory;
+import org.jetbrains.jps.model.JpsElementTypeWithDefaultProperties;
+
+/**
+ * A base class for type elements without any specific properties
+ *
+ * @author nik
+ */
+public abstract class JpsElementTypeWithDummyProperties extends JpsElementTypeBase<JpsDummyElement> implements JpsElementTypeWithDefaultProperties<JpsDummyElement> {
+ @NotNull
+ @Override
+ public JpsDummyElement createDefaultProperties() {
+ return JpsElementFactory.getInstance().createDummyElement();
+ }
+}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JavaResourceRootType.java b/jps/model-api/src/org/jetbrains/jps/model/java/JavaResourceRootType.java
index 7baa1a9..33adf96 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/java/JavaResourceRootType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/java/JavaResourceRootType.java
@@ -18,13 +18,13 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.JpsDummyElement;
import org.jetbrains.jps.model.JpsElementFactory;
-import org.jetbrains.jps.model.JpsElementTypeWithDefaultProperties;
+import org.jetbrains.jps.model.ex.JpsElementTypeWithDummyProperties;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
/**
* @author nik
*/
-public class JavaResourceRootType extends JpsModuleSourceRootType<JpsDummyElement> implements JpsElementTypeWithDefaultProperties<JpsDummyElement> {
+public class JavaResourceRootType extends JpsElementTypeWithDummyProperties implements JpsModuleSourceRootType<JpsDummyElement> {
public static final JavaResourceRootType RESOURCE = new JavaResourceRootType();
public static final JavaResourceRootType TEST_RESOURCE = new JavaResourceRootType();
diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootType.java b/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootType.java
index 2a181f1..97a0368 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootType.java
@@ -17,14 +17,14 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.JpsElementFactory;
-import org.jetbrains.jps.model.JpsElementTypeWithDefaultProperties;
import org.jetbrains.jps.model.JpsSimpleElement;
+import org.jetbrains.jps.model.ex.JpsElementTypeBase;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
/**
* @author nik
*/
-public class JavaSourceRootType extends JpsModuleSourceRootType<JpsSimpleElement<JavaSourceRootProperties>> implements JpsElementTypeWithDefaultProperties<JpsSimpleElement<JavaSourceRootProperties>> {
+public class JavaSourceRootType extends JpsElementTypeBase<JpsSimpleElement<JavaSourceRootProperties>> implements JpsModuleSourceRootType<JpsSimpleElement<JavaSourceRootProperties>> {
public static final JavaSourceRootType SOURCE = new JavaSourceRootType();
public static final JavaSourceRootType TEST_SOURCE = new JavaSourceRootType();
diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaLibraryType.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaLibraryType.java
index 5330360..0fcc7ec 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaLibraryType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaLibraryType.java
@@ -16,13 +16,15 @@
package org.jetbrains.jps.model.java;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.jps.model.*;
+import org.jetbrains.jps.model.JpsDummyElement;
+import org.jetbrains.jps.model.JpsElementFactory;
+import org.jetbrains.jps.model.ex.JpsElementTypeWithDummyProperties;
import org.jetbrains.jps.model.library.JpsLibraryType;
/**
* @author nik
*/
-public class JpsJavaLibraryType extends JpsLibraryType<JpsDummyElement> implements JpsElementTypeWithDefaultProperties<JpsDummyElement> {
+public class JpsJavaLibraryType extends JpsElementTypeWithDummyProperties implements JpsLibraryType<JpsDummyElement> {
public static final JpsJavaLibraryType INSTANCE = new JpsJavaLibraryType();
@NotNull
diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaModuleType.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaModuleType.java
index 6a971cf..c4f6299 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaModuleType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaModuleType.java
@@ -18,13 +18,13 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.JpsDummyElement;
import org.jetbrains.jps.model.JpsElementFactory;
-import org.jetbrains.jps.model.JpsElementTypeWithDefaultProperties;
+import org.jetbrains.jps.model.ex.JpsElementTypeWithDummyProperties;
import org.jetbrains.jps.model.module.JpsModuleType;
/**
* @author nik
*/
-public class JpsJavaModuleType extends JpsModuleType<JpsDummyElement> implements JpsElementTypeWithDefaultProperties<JpsDummyElement> {
+public class JpsJavaModuleType extends JpsElementTypeWithDummyProperties implements JpsModuleType<JpsDummyElement> {
public static final JpsJavaModuleType INSTANCE = new JpsJavaModuleType();
@NotNull
diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationType.java b/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationType.java
index aa0a7a2..c5c880c 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationType.java
@@ -15,12 +15,13 @@
*/
package org.jetbrains.jps.model.java.runConfiguration;
+import org.jetbrains.jps.model.ex.JpsElementTypeBase;
import org.jetbrains.jps.model.runConfiguration.JpsRunConfigurationType;
/**
* @author nik
*/
-public class JpsApplicationRunConfigurationType extends JpsRunConfigurationType<JpsApplicationRunConfigurationProperties> {
+public class JpsApplicationRunConfigurationType extends JpsElementTypeBase<JpsApplicationRunConfigurationProperties> implements JpsRunConfigurationType<JpsApplicationRunConfigurationProperties> {
public static final JpsApplicationRunConfigurationType INSTANCE = new JpsApplicationRunConfigurationType();
private JpsApplicationRunConfigurationType() {
diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryType.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryType.java
index 81a1de0..238c78e 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryType.java
@@ -19,7 +19,11 @@
import org.jetbrains.jps.model.JpsElementType;
/**
+ * Represents a type of libraries in JPS model.
+ * <p>
+ * Use {@link org.jetbrains.jps.model.ex.JpsElementTypeBase} as a base class for implementations of this interface
+ * </p>
* @author nik
*/
-public abstract class JpsLibraryType<P extends JpsElement> extends JpsElementType<P> {
+public interface JpsLibraryType<P extends JpsElement> extends JpsElementType<P> {
}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/sdk/JpsSdkType.java b/jps/model-api/src/org/jetbrains/jps/model/library/sdk/JpsSdkType.java
index 2699fdf..ecc62a7 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/library/sdk/JpsSdkType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/library/sdk/JpsSdkType.java
@@ -17,13 +17,13 @@
import org.jetbrains.jps.model.JpsElement;
import org.jetbrains.jps.model.JpsElementChildRole;
+import org.jetbrains.jps.model.ex.JpsElementTypeBase;
import org.jetbrains.jps.model.library.JpsLibraryType;
-import org.jetbrains.jps.model.library.sdk.JpsSdk;
/**
* @author nik
*/
-public abstract class JpsSdkType<P extends JpsElement> extends JpsLibraryType<JpsSdk<P>> {
+public abstract class JpsSdkType<P extends JpsElement> extends JpsElementTypeBase<JpsSdk<P>> implements JpsLibraryType<JpsSdk<P>> {
private final JpsElementChildRole<P> mySdkPropertiesRole = new JpsElementChildRole<P>();
public final JpsElementChildRole<P> getSdkPropertiesRole() {
diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java
index 3a1df16..8a85c2f 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java
@@ -45,8 +45,8 @@
Iterable<JpsTypedModuleSourceRoot<P>> getSourceRoots(@NotNull JpsModuleSourceRootType<P> type);
@NotNull
- <P extends JpsElement, Type extends JpsModuleSourceRootType<P> & JpsElementTypeWithDefaultProperties<P>>
- JpsModuleSourceRoot addSourceRoot(@NotNull String url, @NotNull Type rootType);
+ <P extends JpsElement>
+ JpsModuleSourceRoot addSourceRoot(@NotNull String url, @NotNull JpsModuleSourceRootType<P> rootType);
@NotNull
<P extends JpsElement>
diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRootType.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRootType.java
index 5a2dbb3..873664a 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRootType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRootType.java
@@ -17,9 +17,15 @@
import org.jetbrains.jps.model.JpsElement;
import org.jetbrains.jps.model.JpsElementType;
+import org.jetbrains.jps.model.JpsElementTypeWithDefaultProperties;
/**
+ * Represents a type of source roots of modules in JPS model.
+ *
+ * <p>
+ * Use {@link org.jetbrains.jps.model.ex.JpsElementTypeBase} as a base class for implementations of this interface
+ * </p>
* @author nik
*/
-public abstract class JpsModuleSourceRootType<P extends JpsElement> extends JpsElementType<P> {
+public interface JpsModuleSourceRootType<P extends JpsElement> extends JpsElementType<P>, JpsElementTypeWithDefaultProperties<P> {
}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleType.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleType.java
index 9062744..10c71cb 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleType.java
@@ -19,7 +19,12 @@
import org.jetbrains.jps.model.JpsElementType;
/**
+ * Represents a type of modules in JPS model
+ *
+ * <p>
+ * Use {@link org.jetbrains.jps.model.ex.JpsElementTypeBase} as a base class for implementations of this interface
+ * </p>
* @author nik
*/
-public abstract class JpsModuleType<P extends JpsElement> extends JpsElementType<P> {
+public interface JpsModuleType<P extends JpsElement> extends JpsElementType<P> {
}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfigurationType.java b/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfigurationType.java
index 558bf05..ebf0ab6 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfigurationType.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfigurationType.java
@@ -19,7 +19,12 @@
import org.jetbrains.jps.model.JpsElementType;
/**
+ * Represents a type of run configurations in JPS model
+ *
+ * <p>
+ * Use {@link org.jetbrains.jps.model.ex.JpsElementTypeBase} as a base class for implementations of this interface
+ * </p>
* @author nik
*/
-public abstract class JpsRunConfigurationType<P extends JpsElement> extends JpsElementType<P> {
+public interface JpsRunConfigurationType<P extends JpsElement> extends JpsElementType<P> {
}
diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaSdkUtil.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaSdkUtil.java
index 32a5a25..2610590 100644
--- a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaSdkUtil.java
+++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaSdkUtil.java
@@ -83,9 +83,17 @@
}
}
- File classesZip = new File(home, "lib/classes.zip");
- if (classesZip.isFile()) {
- rootFiles.add(classesZip);
+ String[] additionalJars = {
+ "jre/bin/default/jclSC170/vm.jar",
+ "jre/lib/i386/default/jclSC170/vm.jar",
+ "jre/lib/amd64/default/jclSC170/vm.jar",
+ "lib/classes.zip"
+ };
+ for (String relativePath : additionalJars) {
+ File jar = new File(home, relativePath);
+ if (jar.isFile()) {
+ rootFiles.add(jar);
+ }
}
File classesDir = new File(home, "classes");
diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java
index eff6c27..0c76723 100644
--- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java
+++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java
@@ -111,8 +111,7 @@
@NotNull
@Override
- public <P extends JpsElement, T extends JpsModuleSourceRootType<P> & JpsElementTypeWithDefaultProperties<P>>
- JpsModuleSourceRoot addSourceRoot(@NotNull String url, @NotNull T rootType) {
+ public <P extends JpsElement> JpsModuleSourceRoot addSourceRoot(@NotNull String url, @NotNull JpsModuleSourceRootType<P> rootType) {
return addSourceRoot(url, rootType, rootType.createDefaultProperties());
}
diff --git a/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java b/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java
index 05dc780..22500b2 100644
--- a/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java
+++ b/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java
@@ -18,22 +18,16 @@
import com.intellij.openapi.application.PathMacroFilter;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
-import org.jdom.Attribute;
-import org.jdom.Comment;
-import org.jdom.Element;
-import org.jdom.Text;
+import org.jdom.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.List;
-
/**
* @author Eugene Zhuravlev
* @since Dec 6, 2004
*/
public abstract class PathMacroMap {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.PathMacroMap");
-
+ private static final Logger LOG = Logger.getInstance(PathMacroMap.class);
public abstract String substitute(String text, boolean caseSensitive);
@@ -41,15 +35,10 @@
substitute(e, caseSensitive, false);
}
- public final void substitute(@NotNull Element e, boolean caseSensitive, final boolean recursively,
- @Nullable PathMacroFilter filter) {
- List content = e.getContent();
- //noinspection ForLoopReplaceableByForEach
- for (int i = 0, contentSize = content.size(); i < contentSize; i++) {
- Object child = content.get(i);
+ public final void substitute(@NotNull Element e, boolean caseSensitive, boolean recursively, @Nullable PathMacroFilter filter) {
+ for (Content child : e.getContent()) {
if (child instanceof Element) {
- Element element = (Element)child;
- substitute(element, caseSensitive, recursively, filter);
+ substitute((Element)child, caseSensitive, recursively, filter);
}
else if (child instanceof Text) {
Text t = (Text)child;
@@ -64,16 +53,11 @@
}
}
- List attributes = e.getAttributes();
- //noinspection ForLoopReplaceableByForEach
- for (int i = 0, attributesSize = attributes.size(); i < attributesSize; i++) {
- Object attribute1 = attributes.get(i);
- Attribute attribute = (Attribute)attribute1;
+ for (Attribute attribute : e.getAttributes()) {
if (filter == null || !filter.skipPathMacros(attribute)) {
- final String value = (recursively || (filter != null && filter.recursePathMacros(attribute)))
- ? substituteRecursively(attribute.getValue(), caseSensitive)
- : substitute(attribute.getValue(), caseSensitive);
- attribute.setValue(value);
+ attribute.setValue((recursively || (filter != null && filter.recursePathMacros(attribute)))
+ ? substituteRecursively(attribute.getValue(), caseSensitive)
+ : substitute(attribute.getValue(), caseSensitive));
}
}
}
diff --git a/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java b/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java
index 559ed4d..6f7d41b2 100644
--- a/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java
+++ b/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java
@@ -93,11 +93,11 @@
}
public void setUseInProcessJavac(boolean value) {
- //doesn't make sense for new builders
+ warning("projectBuilder.useInProcessJavac option is ignored because it doesn't make sense for new JPS builders");
}
public void setArrangeModuleCyclesOutputs(boolean value) {
- //doesn't make sense for new builders
+ warning("projectBuilder.arrangeModuleCyclesOutputs option is ignored because it doesn't make sense for new JPS builders");
}
public void error(String message) {
@@ -202,6 +202,8 @@
private void runBuild(final Set<String> modulesSet, final boolean allModules, boolean includeTests) {
if (!myDryRun) {
final AntMessageHandler messageHandler = new AntMessageHandler();
+ //noinspection AssignmentToStaticFieldFromInstanceMethod
+ AntLoggerFactory.ourMessageHandler = new AntMessageHandler();
Logger.setFactory(AntLoggerFactory.class);
boolean forceBuild = true;
@@ -321,14 +323,10 @@
}
}
- private class AntLoggerFactory implements Logger.Factory {
+ private static class AntLoggerFactory implements Logger.Factory {
private static final String COMPILER_NAME = "build runner";
- private final AntMessageHandler myMessageHandler;
-
- public AntLoggerFactory() {
- myMessageHandler = new AntMessageHandler();
- }
+ private static AntMessageHandler ourMessageHandler;
@Override
public Logger getLoggerInstance(String category) {
@@ -336,16 +334,16 @@
@Override
public void error(@NonNls String message, @Nullable Throwable t, @NotNull @NonNls String... details) {
if (t != null) {
- myMessageHandler.processMessage(new CompilerMessage(COMPILER_NAME, t));
+ ourMessageHandler.processMessage(new CompilerMessage(COMPILER_NAME, t));
}
else {
- myMessageHandler.processMessage(new CompilerMessage(COMPILER_NAME, BuildMessage.Kind.ERROR, message));
+ ourMessageHandler.processMessage(new CompilerMessage(COMPILER_NAME, BuildMessage.Kind.ERROR, message));
}
}
@Override
public void warn(@NonNls String message, @Nullable Throwable t) {
- myMessageHandler.processMessage(new CompilerMessage(COMPILER_NAME, BuildMessage.Kind.WARNING, message));
+ ourMessageHandler.processMessage(new CompilerMessage(COMPILER_NAME, BuildMessage.Kind.WARNING, message));
}
};
}
diff --git a/platform/analysis-api/src/com/intellij/codeInspection/ProblemDescriptor.java b/platform/analysis-api/src/com/intellij/codeInspection/ProblemDescriptor.java
index 088308e..be035f2 100644
--- a/platform/analysis-api/src/com/intellij/codeInspection/ProblemDescriptor.java
+++ b/platform/analysis-api/src/com/intellij/codeInspection/ProblemDescriptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
import com.intellij.lang.annotation.ProblemGroup;
import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -30,6 +31,7 @@
PsiElement getPsiElement();
PsiElement getStartElement();
PsiElement getEndElement();
+ TextRange getTextRangeInElement();
int getLineNumber();
@NotNull
ProblemHighlightType getHighlightType();
diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightingSessionImpl.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightingSessionImpl.java
index cb7c14d..fe0c3f8 100644
--- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightingSessionImpl.java
+++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightingSessionImpl.java
@@ -41,20 +41,23 @@
@NotNull private final ProgressIndicator myProgressIndicator;
private final EditorColorsScheme myEditorColorsScheme;
private final int myPassId;
+ @NotNull private final TextRange myRestrictRange;
private final Project myProject;
private final Document myDocument;
- private Map<TextRange,RangeMarker> myRanges2markersCache;
+ private final Map<TextRange,RangeMarker> myRanges2markersCache = new THashMap<TextRange, RangeMarker>();
public HighlightingSessionImpl(@NotNull PsiFile psiFile,
@Nullable Editor editor,
@NotNull ProgressIndicator progressIndicator,
EditorColorsScheme editorColorsScheme,
- int passId) {
+ int passId,
+ @NotNull TextRange restrictRange) {
myPsiFile = psiFile;
myEditor = editor;
myProgressIndicator = progressIndicator;
myEditorColorsScheme = editorColorsScheme;
myPassId = passId;
+ myRestrictRange = restrictRange;
myProject = psiFile.getProject();
myDocument = PsiDocumentManager.getInstance(myProject).getDocument(psiFile);
}
@@ -97,36 +100,34 @@
return myPassId;
}
- private TransferToEDTQueue<HighlightInfo> myAddHighlighterInEDTQueue;
- private TransferToEDTQueue<RangeHighlighterEx> myDisposeHighlighterInEDTQueue;
- void init(@NotNull final TextRange restrictRange) {
- myRanges2markersCache = new THashMap<TextRange, RangeMarker>();
- Condition<Object> stopCondition = new Condition<Object>() {
- @Override
- public boolean value(Object o) {
- return myProject.isDisposed() || getProgressIndicator().isCanceled();
- }
- };
- myAddHighlighterInEDTQueue = new TransferToEDTQueue<HighlightInfo>("Apply highlighting results", new Processor<HighlightInfo>() {
- @Override
- public boolean process(HighlightInfo info) {
- final EditorColorsScheme colorsScheme = getColorsScheme();
- UpdateHighlightersUtil.addHighlighterToEditorIncrementally(myProject, myDocument, getPsiFile(), restrictRange.getStartOffset(),
- restrictRange.getEndOffset(),
- info, colorsScheme, Pass.UPDATE_ALL, myRanges2markersCache);
+ private final TransferToEDTQueue<HighlightInfo> myAddHighlighterInEDTQueue = new TransferToEDTQueue<HighlightInfo>("Apply highlighting results", new Processor<HighlightInfo>() {
+ @Override
+ public boolean process(HighlightInfo info) {
+ final EditorColorsScheme colorsScheme = getColorsScheme();
+ UpdateHighlightersUtil.addHighlighterToEditorIncrementally(myProject, myDocument, getPsiFile(), myRestrictRange.getStartOffset(),
+ myRestrictRange.getEndOffset(),
+ info, colorsScheme, Pass.UPDATE_ALL, myRanges2markersCache);
- return true;
- }
- }, stopCondition, 200);
-
- myDisposeHighlighterInEDTQueue = new TransferToEDTQueue<RangeHighlighterEx>("Dispose abandoned highlighter", new Processor<RangeHighlighterEx>() {
- @Override
- public boolean process(@NotNull RangeHighlighterEx highlighter) {
- highlighter.dispose();
- return true;
- }
- }, stopCondition, 200);
- }
+ return true;
+ }
+ }, new Condition<Object>() {
+ @Override
+ public boolean value(Object o) {
+ return myProject.isDisposed() || getProgressIndicator().isCanceled();
+ }
+ }, 200);
+ private final TransferToEDTQueue<RangeHighlighterEx> myDisposeHighlighterInEDTQueue = new TransferToEDTQueue<RangeHighlighterEx>("Dispose abandoned highlighter", new Processor<RangeHighlighterEx>() {
+ @Override
+ public boolean process(@NotNull RangeHighlighterEx highlighter) {
+ highlighter.dispose();
+ return true;
+ }
+ }, new Condition<Object>() {
+ @Override
+ public boolean value(Object o) {
+ return myProject.isDisposed() || getProgressIndicator().isCanceled();
+ }
+ }, 200);
void queueHighlightInfo(@NotNull HighlightInfo info) {
myAddHighlighterInEDTQueue.offer(info);
diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/ProgressableTextEditorHighlightingPass.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/ProgressableTextEditorHighlightingPass.java
index 4719ecb..f5a26440 100644
--- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/ProgressableTextEditorHighlightingPass.java
+++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/ProgressableTextEditorHighlightingPass.java
@@ -62,14 +62,13 @@
@NotNull
private HighlightingSession sessionCreated(@NotNull TextRange restrictRange,
- @NotNull PsiFile file,
- @Nullable Editor editor,
- @NotNull ProgressIndicator progress,
- EditorColorsScheme scheme,
- int passId) {
- HighlightingSessionImpl impl = new HighlightingSessionImpl(file, editor, progress, scheme, passId);
+ @NotNull PsiFile file,
+ @Nullable Editor editor,
+ @NotNull ProgressIndicator progress,
+ EditorColorsScheme scheme,
+ int passId) {
+ HighlightingSessionImpl impl = new HighlightingSessionImpl(file, editor, progress, scheme, passId, restrictRange);
myHighlightingSession = impl;
- impl.init(restrictRange);
return impl;
}
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java b/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java
index 78b638b..ab9581f 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java
@@ -78,7 +78,7 @@
}
@NotNull
- private static List<ProblemDescriptor> inspect(@NotNull final List<LocalInspectionTool> tools,
+ public static List<ProblemDescriptor> inspect(@NotNull final List<LocalInspectionTool> tools,
@NotNull final PsiFile file,
@NotNull final InspectionManager iManager,
final boolean isOnTheFly,
@@ -92,8 +92,9 @@
return result;
}
+ // public accessibility for Upsource
@NotNull
- private static Map<String, List<ProblemDescriptor>> inspectEx(@NotNull final List<LocalInspectionTool> tools,
+ public static Map<String, List<ProblemDescriptor>> inspectEx(@NotNull final List<LocalInspectionTool> tools,
@NotNull final PsiFile file,
@NotNull final InspectionManager iManager,
final boolean isOnTheFly,
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java
index 42dfa58..45997b0 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java
@@ -102,6 +102,11 @@
return PsiTreeUtil.findCommonParent(startElement, endElement);
}
+ @Nullable
+ public TextRange getTextRangeInElement() {
+ return myTextRangeInElement;
+ }
+
@Override
public PsiElement getStartElement() {
return myStartSmartPointer.getElement();
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorUtil.java b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorUtil.java
index 2f7742d..b6c5ff5 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorUtil.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorUtil.java
@@ -15,6 +15,11 @@
*/
package com.intellij.codeInspection;
+import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
+import com.intellij.codeInsight.daemon.impl.SeverityRegistrar;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.editor.colors.CodeInsightColors;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
@@ -76,4 +81,41 @@
public static String renderDescriptionMessage(@NotNull CommonProblemDescriptor descriptor, PsiElement element) {
return renderDescriptionMessage(descriptor, element, false);
}
+
+ @NotNull
+ public static HighlightInfoType highlightTypeFromDescriptor(@NotNull ProblemDescriptor problemDescriptor, @NotNull HighlightSeverity severity, @NotNull SeverityRegistrar severityRegistrar) {
+ final ProblemHighlightType highlightType = problemDescriptor.getHighlightType();
+ switch (highlightType) {
+ case GENERIC_ERROR_OR_WARNING:
+ return severityRegistrar.getHighlightInfoTypeBySeverity(severity);
+ case LIKE_DEPRECATED:
+ return new HighlightInfoType.HighlightInfoTypeImpl(severity, HighlightInfoType.DEPRECATED.getAttributesKey());
+ case LIKE_UNKNOWN_SYMBOL:
+ if (severity == HighlightSeverity.ERROR) {
+ return new HighlightInfoType.HighlightInfoTypeImpl(severity, HighlightInfoType.WRONG_REF.getAttributesKey());
+ }
+ if (severity == HighlightSeverity.WARNING) {
+ return new HighlightInfoType.HighlightInfoTypeImpl(severity, CodeInsightColors.WEAK_WARNING_ATTRIBUTES);
+ }
+ return severityRegistrar.getHighlightInfoTypeBySeverity(severity);
+ case LIKE_UNUSED_SYMBOL:
+ return new HighlightInfoType.HighlightInfoTypeImpl(severity, HighlightInfoType.UNUSED_SYMBOL.getAttributesKey());
+ case INFO:
+ return HighlightInfoType.INFO;
+ case WEAK_WARNING:
+ return HighlightInfoType.WEAK_WARNING;
+ case ERROR:
+ return HighlightInfoType.WRONG_REF;
+ case GENERIC_ERROR:
+ return HighlightInfoType.ERROR;
+ case INFORMATION:
+ final TextAttributesKey attributes = ((ProblemDescriptorBase)problemDescriptor).getEnforcedTextAttributes();
+ if (attributes != null) {
+ return new HighlightInfoType.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, attributes);
+ }
+ return HighlightInfoType.INFORMATION;
+ }
+ throw new RuntimeException("Cannot map " + highlightType);
+ }
+
}
diff --git a/platform/bootstrap/src/com/intellij/ide/Bootstrap.java b/platform/bootstrap/src/com/intellij/ide/Bootstrap.java
index ff6693c..847062c 100644
--- a/platform/bootstrap/src/com/intellij/ide/Bootstrap.java
+++ b/platform/bootstrap/src/com/intellij/ide/Bootstrap.java
@@ -24,11 +24,13 @@
*/
public class Bootstrap {
private static final String PLUGIN_MANAGER = "com.intellij.ide.plugins.PluginManager";
+ public static final String NO_SPLASH = "nosplash";
private Bootstrap() { }
public static void main(String[] args, String mainClass, String methodName) throws Exception {
- UrlClassLoader newClassLoader = BootstrapClassLoaderUtil.initClassLoader(args.length == 0);
+ UrlClassLoader newClassLoader = BootstrapClassLoaderUtil.initClassLoader(args.length == 0 || args.length == 1 &&
+ NO_SPLASH.equals(args[0]));
WindowsCommandLineProcessor.ourMirrorClass = Class.forName(WindowsCommandLineProcessor.class.getName(), true, newClassLoader);
diff --git a/platform/core-api/src/com/intellij/ide/highlighter/ArchiveFileType.java b/platform/core-api/src/com/intellij/ide/highlighter/ArchiveFileType.java
index 438fb52..72b2b9b 100644
--- a/platform/core-api/src/com/intellij/ide/highlighter/ArchiveFileType.java
+++ b/platform/core-api/src/com/intellij/ide/highlighter/ArchiveFileType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,33 +35,40 @@
public static final ArchiveFileType INSTANCE = new ArchiveFileType();
+ @Override
@NotNull
public String getName() {
return "ARCHIVE";
}
+ @Override
@NotNull
public String getDescription() {
return IdeBundle.message("filetype.description.archive.files");
}
+ @Override
@NotNull
public String getDefaultExtension() {
return "";
}
+ @Override
public Icon getIcon() {
return ICON.getValue();
}
+ @Override
public boolean isBinary() {
return true;
}
+ @Override
public boolean isReadOnly() {
return false;
}
+ @Override
public String getCharset(@NotNull VirtualFile file, final byte[] content) {
return null;
}
diff --git a/platform/core-api/src/com/intellij/lexer/DelegateLexer.java b/platform/core-api/src/com/intellij/lexer/DelegateLexer.java
index 4b95562..ce8bbbc 100644
--- a/platform/core-api/src/com/intellij/lexer/DelegateLexer.java
+++ b/platform/core-api/src/com/intellij/lexer/DelegateLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
package com.intellij.lexer;
import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class DelegateLexer extends LexerBase {
@@ -34,7 +35,7 @@
}
@Override
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
myDelegate.start(buffer, startOffset, endOffset, initialState);
}
@@ -64,6 +65,7 @@
myDelegate.advance();
}
+ @NotNull
@Override
public final CharSequence getBufferSequence() {
return myDelegate.getBufferSequence();
diff --git a/platform/core-api/src/com/intellij/lexer/DocCommentLexer.java b/platform/core-api/src/com/intellij/lexer/DocCommentLexer.java
index bb121f9..7ea6da5 100644
--- a/platform/core-api/src/com/intellij/lexer/DocCommentLexer.java
+++ b/platform/core-api/src/com/intellij/lexer/DocCommentLexer.java
@@ -17,6 +17,7 @@
import com.intellij.psi.tree.IElementType;
import com.intellij.util.text.CharArrayUtil;
+import org.jetbrains.annotations.NotNull;
import java.io.IOException;
@@ -45,7 +46,7 @@
}
@Override
- public final void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public final void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
myBuffer = buffer;
myBufferIndex = startOffset;
myBufferEndOffset = endOffset;
@@ -59,6 +60,7 @@
return myState;
}
+ @NotNull
@Override
public CharSequence getBufferSequence() {
return myBuffer;
diff --git a/platform/core-api/src/com/intellij/lexer/DummyLexer.java b/platform/core-api/src/com/intellij/lexer/DummyLexer.java
new file mode 100644
index 0000000..3d13df9
--- /dev/null
+++ b/platform/core-api/src/com/intellij/lexer/DummyLexer.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lexer;
+
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
+
+public class DummyLexer extends LexerBase {
+ private CharSequence myBuffer;
+ private int myStartOffset;
+ private int myEndOffset;
+ private final IElementType myTokenType;
+
+ public DummyLexer(IElementType type) {
+ myTokenType = type;
+ }
+
+ @Override
+ public void start(@NotNull final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
+ myBuffer = buffer;
+ myStartOffset = startOffset;
+ myEndOffset = endOffset;
+ }
+
+ @NotNull
+ @Override
+ public CharSequence getBufferSequence() {
+ return myBuffer;
+ }
+
+ @Override
+ public int getState() {
+ return 0;
+ }
+
+ @Override
+ public IElementType getTokenType() {
+ return myStartOffset < myEndOffset ? myTokenType : null;
+ }
+
+ @Override
+ public int getTokenStart() {
+ return myStartOffset;
+ }
+
+ @Override
+ public int getTokenEnd() {
+ return myEndOffset;
+ }
+
+ @Override
+ public void advance() {
+ myStartOffset = myEndOffset;
+ }
+
+ @NotNull
+ @Override
+ public LexerPosition getCurrentPosition() {
+ return new LexerPositionImpl(0, getState());
+ }
+
+ @Override
+ public void restore(@NotNull LexerPosition position) {
+ }
+
+ @Override
+ public int getBufferEnd() {
+ return myEndOffset;
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/lexer/EmptyLexer.java b/platform/core-api/src/com/intellij/lexer/EmptyLexer.java
similarity index 100%
rename from platform/platform-api/src/com/intellij/lexer/EmptyLexer.java
rename to platform/core-api/src/com/intellij/lexer/EmptyLexer.java
diff --git a/platform/core-api/src/com/intellij/lexer/FlexAdapter.java b/platform/core-api/src/com/intellij/lexer/FlexAdapter.java
index cd9ccaf..593f68c 100644
--- a/platform/core-api/src/com/intellij/lexer/FlexAdapter.java
+++ b/platform/core-api/src/com/intellij/lexer/FlexAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package com.intellij.lexer;
import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
import java.io.IOException;
@@ -39,7 +40,7 @@
}
@Override
- public void start(final CharSequence buffer, int startOffset, int endOffset, final int initialState) {
+ public void start(@NotNull final CharSequence buffer, int startOffset, int endOffset, final int initialState) {
myText = buffer;
myEnd = endOffset;
myFlex.reset(myText, startOffset, endOffset, initialState);
@@ -76,6 +77,7 @@
myTokenType = null;
}
+ @NotNull
@Override
public CharSequence getBufferSequence() {
return myText;
diff --git a/platform/core-api/src/com/intellij/lexer/LayeredLexer.java b/platform/core-api/src/com/intellij/lexer/LayeredLexer.java
index eabb355..1080337 100644
--- a/platform/core-api/src/com/intellij/lexer/LayeredLexer.java
+++ b/platform/core-api/src/com/intellij/lexer/LayeredLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.containers.HashMap;
+import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Map;
@@ -75,7 +76,7 @@
}
@Override
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
LOG.assertTrue(initialState != IN_LAYER_STATE, "Restoring to layer is not supported.");
myState = initialState;
myCurrentLayerLexer = null;
@@ -157,13 +158,14 @@
myState = isLayerActive() ? IN_LAYER_STATE : super.getState();
}
+ @NotNull
@Override
public LexerPosition getCurrentPosition() {
return new LexerPositionImpl(getTokenStart(), getState());
}
@Override
- public void restore(LexerPosition position) {
+ public void restore(@NotNull LexerPosition position) {
start(getBufferSequence(), position.getOffset(), getBufferEnd(), position.getState());
}
diff --git a/platform/core-api/src/com/intellij/lexer/Lexer.java b/platform/core-api/src/com/intellij/lexer/Lexer.java
index 58b4dd3..1ccfd472 100644
--- a/platform/core-api/src/com/intellij/lexer/Lexer.java
+++ b/platform/core-api/src/com/intellij/lexer/Lexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package com.intellij.lexer;
import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -35,20 +36,22 @@
* @param initialState the initial state of the lexer.
* @since IDEA 7
*/
- public abstract void start(CharSequence buffer, int startOffset, int endOffset, int initialState);
+ public abstract void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState);
- public final void start(CharSequence buf, int start, int end) {
+ public final void start(@NotNull CharSequence buf, int start, int end) {
start(buf, start, end, 0);
}
- public final void start(CharSequence buf) {
+ public final void start(@NotNull CharSequence buf) {
start(buf, 0, buf.length(), 0);
}
+ @NotNull
public CharSequence getTokenSequence() {
return getBufferSequence().subSequence(getTokenStart(), getTokenEnd());
}
+ @NotNull
public String getTokenText() {
return getTokenSequence().toString();
}
@@ -93,6 +96,7 @@
*
* @return the lexer position and state.
*/
+ @NotNull
public abstract LexerPosition getCurrentPosition();
/**
@@ -100,7 +104,7 @@
*
* @param position the state and position to restore to.
*/
- public abstract void restore(LexerPosition position);
+ public abstract void restore(@NotNull LexerPosition position);
/**
* Returns the buffer sequence over which the lexer is running. This method should return the
@@ -108,6 +112,7 @@
* @return the lexer buffer.
* @since IDEA 7
*/
+ @NotNull
public abstract CharSequence getBufferSequence();
/**
diff --git a/platform/core-api/src/com/intellij/lexer/LexerBase.java b/platform/core-api/src/com/intellij/lexer/LexerBase.java
index c166bed..b7a69b8 100644
--- a/platform/core-api/src/com/intellij/lexer/LexerBase.java
+++ b/platform/core-api/src/com/intellij/lexer/LexerBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,10 @@
*/
package com.intellij.lexer;
+import org.jetbrains.annotations.NotNull;
+
public abstract class LexerBase extends Lexer {
+ @NotNull
@Override
public LexerPosition getCurrentPosition() {
final int offset = getTokenStart();
@@ -24,7 +27,7 @@
}
@Override
- public void restore(LexerPosition position) {
+ public void restore(@NotNull LexerPosition position) {
start(getBufferSequence(), position.getOffset(), getBufferEnd(), position.getState());
}
}
diff --git a/platform/core-api/src/com/intellij/lexer/MergingLexerAdapterBase.java b/platform/core-api/src/com/intellij/lexer/MergingLexerAdapterBase.java
index bbaace8..2d55098a 100644
--- a/platform/core-api/src/com/intellij/lexer/MergingLexerAdapterBase.java
+++ b/platform/core-api/src/com/intellij/lexer/MergingLexerAdapterBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package com.intellij.lexer;
import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
public class MergingLexerAdapterBase extends DelegateLexer {
private IElementType myTokenType;
@@ -29,7 +30,7 @@
}
@Override
- public void start(final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
+ public void start(@NotNull final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
super.start(buffer, startOffset, endOffset, initialState);
myTokenType = null;
}
@@ -81,7 +82,7 @@
}
@Override
- public void restore(LexerPosition position) {
+ public void restore(@NotNull LexerPosition position) {
MyLexerPosition pos = (MyLexerPosition)position;
getDelegate().restore(pos.getOriginalPosition());
@@ -90,6 +91,7 @@
myState = pos.getOldState();
}
+ @NotNull
@Override
public LexerPosition getCurrentPosition() {
return new MyLexerPosition(myTokenStart, myTokenType, getDelegate().getCurrentPosition(), myState);
diff --git a/platform/core-api/src/com/intellij/openapi/editor/colors/TextAttributesKey.java b/platform/core-api/src/com/intellij/openapi/editor/colors/TextAttributesKey.java
index 721f51e..53f0565 100644
--- a/platform/core-api/src/com/intellij/openapi/editor/colors/TextAttributesKey.java
+++ b/platform/core-api/src/com/intellij/openapi/editor/colors/TextAttributesKey.java
@@ -64,7 +64,8 @@
return myExternalName;
}
- public int compareTo(TextAttributesKey key) {
+ @Override
+ public int compareTo(@NotNull TextAttributesKey key) {
return myExternalName.compareTo(key.myExternalName);
}
@@ -79,10 +80,12 @@
return find(externalName);
}
+ @Override
public void readExternal(Element element) throws InvalidDataException {
DefaultJDOMExternalizer.readExternal(this, element);
}
+ @Override
public void writeExternal(Element element) throws WriteExternalException {
DefaultJDOMExternalizer.writeExternal(this, element);
}
diff --git a/platform/core-api/src/com/intellij/openapi/editor/markup/AttributesFlyweight.java b/platform/core-api/src/com/intellij/openapi/editor/markup/AttributesFlyweight.java
index 05fa2cd..411fc5e 100644
--- a/platform/core-api/src/com/intellij/openapi/editor/markup/AttributesFlyweight.java
+++ b/platform/core-api/src/com/intellij/openapi/editor/markup/AttributesFlyweight.java
@@ -19,6 +19,7 @@
*/
package com.intellij.openapi.editor.markup;
+import com.intellij.openapi.util.Comparing;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.containers.StripedLockConcurrentHashMap;
import org.intellij.lang.annotations.JdkConstants;
@@ -28,17 +29,29 @@
import java.awt.*;
public class AttributesFlyweight {
- private final int myHashCode;
private static final StripedLockConcurrentHashMap<FlyweightKey, AttributesFlyweight> entries = new StripedLockConcurrentHashMap<FlyweightKey, AttributesFlyweight>();
private static final ThreadLocal<FlyweightKey> ourKey = new ThreadLocal<FlyweightKey>();
+ private final int myHashCode;
+ private final Color myForeground;
+ private final Color myBackground;
+ @JdkConstants.FontStyle
+ private final int myFontType;
+ private final Color myEffectColor;
+ private final EffectType myEffectType;
+ private final Color myErrorStripeColor;
+
private static class FlyweightKey implements Cloneable {
- Color foreground;
- Color background;
- @JdkConstants.FontStyle int fontType;
- Color effectColor;
- EffectType effectType;
- Color errorStripeColor;
+ private Color foreground;
+ private Color background;
+ @JdkConstants.FontStyle
+ private int fontType;
+ private Color effectColor;
+ private EffectType effectType;
+ private Color errorStripeColor;
+
+ private FlyweightKey() {
+ }
@Override
public boolean equals(Object o) {
@@ -59,13 +72,7 @@
@Override
public int hashCode() {
- int result = foreground != null ? foreground.hashCode() : 0;
- result = 31 * result + (background != null ? background.hashCode() : 0);
- result = 31 * result + fontType;
- result = 31 * result + (effectColor != null ? effectColor.hashCode() : 0);
- result = 31 * result + (effectType != null ? effectType.hashCode() : 0);
- result = 31 * result + (errorStripeColor != null ? errorStripeColor.hashCode() : 0);
- return result;
+ return calcHashCode(foreground, background, fontType, effectColor, effectType, errorStripeColor);
}
@Override
@@ -102,39 +109,37 @@
return flyweight;
}
- return ConcurrencyUtil.cacheOrGet(entries, key.clone(), new AttributesFlyweight(foreground, background, fontType, effectColor, effectType, errorStripeColor));
+ AttributesFlyweight newValue = new AttributesFlyweight(foreground, background, fontType, effectColor, effectType, errorStripeColor);
+ return ConcurrencyUtil.cacheOrGet(entries, key.clone(), newValue);
}
- private final Color myForeground;
- private final Color myBackground;
- @JdkConstants.FontStyle
- private final int myFontType;
- private final Color myEffectColor ;
- private final EffectType myEffectType;
- private final Color myErrorStripeColor;
-
private AttributesFlyweight(Color foreground,
- Color background,
- @JdkConstants.FontStyle int fontType,
- Color effectColor,
- EffectType effectType,
- Color errorStripeColor) {
+ Color background,
+ @JdkConstants.FontStyle int fontType,
+ Color effectColor,
+ EffectType effectType,
+ Color errorStripeColor) {
myForeground = foreground;
myBackground = background;
myFontType = fontType;
myEffectColor = effectColor;
myEffectType = effectType;
myErrorStripeColor = errorStripeColor;
- myHashCode = calcHashCode();
+ myHashCode = calcHashCode(foreground, background, fontType, effectColor, effectType, errorStripeColor);
}
- private int calcHashCode() {
- int result = myForeground != null ? myForeground.hashCode() : 0;
- result = 31 * result + (myBackground != null ? myBackground.hashCode() : 0);
- result = 31 * result + myFontType;
- result = 31 * result + (myEffectColor != null ? myEffectColor.hashCode() : 0);
- result = 31 * result + (myEffectType != null ? myEffectType.hashCode() : 0);
- result = 31 * result + (myErrorStripeColor != null ? myErrorStripeColor.hashCode() : 0);
+ private static int calcHashCode(Color foreground,
+ Color background,
+ int fontType,
+ Color effectColor,
+ EffectType effectType,
+ Color errorStripeColor) {
+ int result = foreground != null ? foreground.hashCode() : 0;
+ result = 31 * result + (background != null ? background.hashCode() : 0);
+ result = 31 * result + fontType;
+ result = 31 * result + (effectColor != null ? effectColor.hashCode() : 0);
+ result = 31 * result + (effectType != null ? effectType.hashCode() : 0);
+ result = 31 * result + (errorStripeColor != null ? errorStripeColor.hashCode() : 0);
return result;
}
@@ -163,28 +168,34 @@
return myErrorStripeColor;
}
- public AttributesFlyweight withForeground(Color fore) {
- return create(fore, myBackground, myFontType, myEffectColor, myEffectType, myErrorStripeColor);
+ @NotNull
+ public AttributesFlyweight withForeground(Color foreground) {
+ return Comparing.equal(foreground, myForeground) ? this : create(foreground, myBackground, myFontType, myEffectColor, myEffectType, myErrorStripeColor);
}
- public AttributesFlyweight withBackground(Color back) {
- return create(myForeground, back, myFontType, myEffectColor, myEffectType, myErrorStripeColor);
+ @NotNull
+ public AttributesFlyweight withBackground(Color background) {
+ return Comparing.equal(background, myBackground) ? this : create(myForeground, background, myFontType, myEffectColor, myEffectType, myErrorStripeColor);
}
+ @NotNull
public AttributesFlyweight withFontType(@JdkConstants.FontStyle int fontType) {
- return create(myForeground, myBackground, fontType, myEffectColor, myEffectType, myErrorStripeColor);
+ return fontType == myFontType ? this : create(myForeground, myBackground, fontType, myEffectColor, myEffectType, myErrorStripeColor);
}
+ @NotNull
public AttributesFlyweight withEffectColor(Color effectColor) {
- return create(myForeground, myBackground, myFontType, effectColor, myEffectType, myErrorStripeColor);
+ return Comparing.equal(effectColor, myEffectColor) ? this : create(myForeground, myBackground, myFontType, effectColor, myEffectType, myErrorStripeColor);
}
+ @NotNull
public AttributesFlyweight withEffectType(EffectType effectType) {
- return create(myForeground, myBackground, myFontType, myEffectColor, effectType, myErrorStripeColor);
+ return Comparing.equal(effectType, myEffectType) ? this : create(myForeground, myBackground, myFontType, myEffectColor, effectType, myErrorStripeColor);
}
+ @NotNull
public AttributesFlyweight withErrorStripeColor(Color stripeColor) {
- return create(myForeground, myBackground, myFontType, myEffectColor, myEffectType, stripeColor);
+ return Comparing.equal(stripeColor, myErrorStripeColor) ? this : create(myForeground, myBackground, myFontType, myEffectColor, myEffectType, stripeColor);
}
@Override
@@ -212,19 +223,7 @@
@NonNls
@Override
public String toString() {
- return "AttributesFlyweight{" +
- "myForeground=" +
- myForeground +
- ", myBackground=" +
- myBackground +
- ", myFontType=" +
- myFontType +
- ", myEffectColor=" +
- myEffectColor +
- ", myEffectType=" +
- myEffectType +
- ", myErrorStripeColor=" +
- myErrorStripeColor +
- '}';
+ return "AttributesFlyweight{myForeground=" + myForeground + ", myBackground=" + myBackground + ", myFontType=" + myFontType +
+ ", myEffectColor=" + myEffectColor + ", myEffectType=" + myEffectType + ", myErrorStripeColor=" + myErrorStripeColor + '}';
}
}
diff --git a/platform/core-api/src/com/intellij/openapi/editor/markup/TextAttributes.java b/platform/core-api/src/com/intellij/openapi/editor/markup/TextAttributes.java
index 715e700..e504a8c 100644
--- a/platform/core-api/src/com/intellij/openapi/editor/markup/TextAttributes.java
+++ b/platform/core-api/src/com/intellij/openapi/editor/markup/TextAttributes.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
package com.intellij.openapi.editor.markup;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.*;
+import com.intellij.openapi.util.DefaultJDOMExternalizer;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.WriteExternalException;
import org.intellij.lang.annotations.JdkConstants;
import org.jdom.Element;
+import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
@@ -34,6 +38,9 @@
private boolean myEnforcedDefaults = false;
+ @NotNull
+ private AttributesFlyweight myAttrs;
+
/**
* Merges (layers) the two given text attributes.
*
@@ -41,6 +48,7 @@
* @param above Text attributes to merge "above", overriding settings from "under".
* @return Merged attributes instance.
*/
+ @Contract("!null, !null -> !null")
public static TextAttributes merge(TextAttributes under, TextAttributes above) {
if (under == null) return above;
if (above == null) return under;
@@ -154,8 +162,6 @@
}
}
- private AttributesFlyweight myAttrs;
-
public TextAttributes() {
this(null, null, null, EffectType.BOXED, Font.PLAIN);
}
@@ -194,7 +200,7 @@
}
@NotNull
- public static TextAttributes fromFlyweight(AttributesFlyweight flyweight) {
+ public static TextAttributes fromFlyweight(@NotNull AttributesFlyweight flyweight) {
TextAttributes f = new TextAttributes();
f.myAttrs = flyweight;
return f;
@@ -277,12 +283,7 @@
public void readExternal(Element element) throws InvalidDataException {
Externalizable ext = new Externalizable();
ext.readExternal(element);
- myAttrs = AttributesFlyweight.create(ext.FOREGROUND,
- ext.BACKGROUND,
- ext.FONT_TYPE,
- ext.EFFECT_COLOR,
- ext.getEffectType(),
- ext.ERROR_STRIPE_COLOR);
+ myAttrs = AttributesFlyweight.create(ext.FOREGROUND, ext.BACKGROUND, ext.FONT_TYPE, ext.EFFECT_COLOR, ext.getEffectType(), ext.ERROR_STRIPE_COLOR);
if (isEmpty()) myEnforcedDefaults = true;
}
@@ -302,18 +303,7 @@
@Override
public String toString() {
- return "[" +
- getForegroundColor() +
- "," +
- getBackgroundColor() +
- "," +
- getFontType() +
- "," +
- getEffectType() +
- "," +
- getEffectColor() +
- "," +
- getErrorStripeColor() +
- "]";
+ return "[" + getForegroundColor() + "," + getBackgroundColor() + "," + getFontType() + "," + getEffectType() + "," +
+ getEffectColor() + "," + getErrorStripeColor() + "]";
}
}
diff --git a/platform/core-api/src/com/intellij/openapi/fileTypes/FileTypeExtensionFactory.java b/platform/core-api/src/com/intellij/openapi/fileTypes/FileTypeExtensionFactory.java
new file mode 100644
index 0000000..2378fd5
--- /dev/null
+++ b/platform/core-api/src/com/intellij/openapi/fileTypes/FileTypeExtensionFactory.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.openapi.fileTypes;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.KeyedExtensionFactory;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+public class FileTypeExtensionFactory<T> extends KeyedExtensionFactory<T, FileType> {
+ public FileTypeExtensionFactory(@NotNull final Class<T> interfaceClass, @NonNls @NotNull final String epName) {
+ super(interfaceClass, epName, ApplicationManager.getApplication().getPicoContainer());
+ }
+
+ @Override
+ public String getKey(@NotNull final FileType key) {
+ return key.getName();
+ }
+}
\ No newline at end of file
diff --git a/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java b/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
index a1a88c6..6cda4f5 100644
--- a/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
+++ b/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
@@ -22,6 +22,7 @@
public static final String APPCODE_PREFIX = "AppCode";
public static final String CPP_PREFIX = "CppIde";
public static final String PYCHARM_PREFIX = "Python";
+ public static final String PYCHARM_PREFIX2 = "PyCharm";
public static final String RUBY_PREFIX = "Ruby";
public static final String PHP_PREFIX = "PhpStorm";
public static final String WEB_PREFIX = "WebStorm";
@@ -56,7 +57,8 @@
}
public static boolean isPyCharm() {
- return PYCHARM_PREFIX.equals(getPlatformPrefix());
+ String prefix = getPlatformPrefix();
+ return PYCHARM_PREFIX.equals(prefix) || (prefix != null && prefix.startsWith(PYCHARM_PREFIX2));
}
public static boolean isPhpStorm() {
@@ -67,10 +69,6 @@
return WEB_PREFIX.equals(getPlatformPrefix());
}
- public static boolean isFlexIde() {
- return FLEX_PREFIX.equals(getPlatformPrefix());
- }
-
public static boolean isIntelliJ() {
return isIdea() || isCommunity();
}
diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactory.java b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactory.java
index 8e31061..010b595 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactory.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactory.java
@@ -32,6 +32,7 @@
return ServiceManager.getService(project, PsiDirectoryFactory.class);
}
+ @NotNull
public abstract PsiDirectory createDirectory(@NotNull VirtualFile file);
@NotNull
@@ -40,7 +41,7 @@
@Nullable
public abstract PsiDirectoryContainer getDirectoryContainer(@NotNull PsiDirectory directory);
- public abstract boolean isPackage(PsiDirectory directory);
+ public abstract boolean isPackage(@NotNull PsiDirectory directory);
- public abstract boolean isValidPackageName(String name);
+ public abstract boolean isValidPackageName(@Nullable String name);
}
diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactoryImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactoryImpl.java
index ddbf1ef..d999602 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactoryImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryFactoryImpl.java
@@ -32,6 +32,7 @@
public PsiDirectoryFactoryImpl(final PsiManagerImpl manager) {
myManager = manager;
}
+ @NotNull
@Override
public PsiDirectory createDirectory(@NotNull final VirtualFile file) {
return new PsiDirectoryImpl(myManager, file);
@@ -52,7 +53,7 @@
}
@Override
- public boolean isPackage(PsiDirectory directory) {
+ public boolean isPackage(@NotNull PsiDirectory directory) {
return false;
}
diff --git a/platform/editor-ui-api/editor-ui-api.iml b/platform/editor-ui-api/editor-ui-api.iml
index a47a2d5..3de8227 100644
--- a/platform/editor-ui-api/editor-ui-api.iml
+++ b/platform/editor-ui-api/editor-ui-api.iml
@@ -11,6 +11,7 @@
<orderEntry type="module" module-name="util" />
<orderEntry type="module" module-name="annotations" />
<orderEntry type="module" module-name="projectModel-api" />
+ <orderEntry type="module" module-name="indexing-api" />
</component>
</module>
diff --git a/platform/editor-ui-api/src/com/intellij/ide/highlighter/HighlighterFactory.java b/platform/editor-ui-api/src/com/intellij/ide/highlighter/HighlighterFactory.java
new file mode 100644
index 0000000..e94ba79
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/ide/highlighter/HighlighterFactory.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.highlighter;
+
+import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.editor.highlighter.EditorHighlighter;
+import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.SyntaxHighlighter;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+
+public class HighlighterFactory {
+ private HighlighterFactory() {}
+
+ @NotNull
+ public static EditorHighlighter createHighlighter(SyntaxHighlighter highlighter, @NotNull EditorColorsScheme settings) {
+ return EditorHighlighterFactory.getInstance().createEditorHighlighter(highlighter, settings);
+ }
+
+ @NotNull
+ public static EditorHighlighter createHighlighter(Project project, @NotNull String fileName) {
+ return EditorHighlighterFactory.getInstance().createEditorHighlighter(project, fileName);
+ }
+
+ @NotNull
+ public static EditorHighlighter createHighlighter(Project project, @NotNull VirtualFile file) {
+ return EditorHighlighterFactory.getInstance().createEditorHighlighter(project, file);
+ }
+
+ @NotNull
+ public static EditorHighlighter createHighlighter(Project project, @NotNull FileType fileType) {
+ return EditorHighlighterFactory.getInstance().createEditorHighlighter(project, fileType);
+ }
+
+ @NotNull
+ public static EditorHighlighter createHighlighter(@NotNull EditorColorsScheme settings, @NotNull String fileName, Project project) {
+ return EditorHighlighterFactory.getInstance().createEditorHighlighter(settings, fileName, project);
+ }
+
+ @NotNull
+ public static EditorHighlighter createHighlighter(@NotNull FileType fileType, @NotNull EditorColorsScheme settings, Project project) {
+ return EditorHighlighterFactory.getInstance().createEditorHighlighter(fileType, settings, project);
+ }
+
+ @NotNull
+ public static EditorHighlighter createHighlighter(@NotNull VirtualFile vFile, @NotNull EditorColorsScheme settings, Project project) {
+ return EditorHighlighterFactory.getInstance().createEditorHighlighter(vFile, settings, project);
+ }
+}
\ No newline at end of file
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactory.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactory.java
new file mode 100644
index 0000000..8577857
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactory.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.editor.highlighter;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.SyntaxHighlighter;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author yole
+ */
+public abstract class EditorHighlighterFactory {
+
+ public static EditorHighlighterFactory getInstance() {
+ return ServiceManager.getService(EditorHighlighterFactory.class);
+ }
+
+ @NotNull
+ public abstract EditorHighlighter createEditorHighlighter(final SyntaxHighlighter syntaxHighlighter, @NotNull EditorColorsScheme colors);
+
+ @NotNull
+ public abstract EditorHighlighter createEditorHighlighter(@NotNull FileType fileType, @NotNull EditorColorsScheme settings, final Project project);
+
+ @NotNull
+ public abstract EditorHighlighter createEditorHighlighter(final Project project, @NotNull FileType fileType);
+
+ @NotNull
+ public abstract EditorHighlighter createEditorHighlighter(@NotNull final VirtualFile file, @NotNull EditorColorsScheme globalScheme, @Nullable final Project project);
+
+ @NotNull
+ public abstract EditorHighlighter createEditorHighlighter(final Project project, @NotNull VirtualFile file);
+
+ @NotNull
+ public abstract EditorHighlighter createEditorHighlighter(final Project project, @NotNull String fileName);
+
+ @NotNull
+ public abstract EditorHighlighter createEditorHighlighter(@NotNull EditorColorsScheme settings, @NotNull String fileName, @Nullable final Project project);
+}
\ No newline at end of file
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighter.java b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighter.java
new file mode 100644
index 0000000..a1105ab
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighter.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.fileTypes;
+
+import com.intellij.lexer.EmptyLexer;
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.editor.HighlighterColors;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
+
+public class PlainSyntaxHighlighter implements SyntaxHighlighter {
+ private static final TextAttributesKey[] ATTRS = {HighlighterColors.TEXT};
+
+ @Override
+ @NotNull
+ public Lexer getHighlightingLexer() {
+ return new EmptyLexer();
+ }
+
+ @Override
+ @NotNull
+ public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
+ return ATTRS;
+ }
+}
\ No newline at end of file
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighterFactory.java b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighterFactory.java
new file mode 100644
index 0000000..df5a83e
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighterFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.openapi.fileTypes;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+
+public class PlainSyntaxHighlighterFactory extends SyntaxHighlighterFactory {
+ @NotNull
+ public SyntaxHighlighter getSyntaxHighlighter(final Project project, final VirtualFile virtualFile) {
+ return new PlainSyntaxHighlighter();
+ }
+}
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighter.java b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighter.java
new file mode 100644
index 0000000..d6c7dc3
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighter.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.fileTypes;
+
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Controls the syntax highlighting of a file.
+ *
+ * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
+ * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.lang.Language, com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
+ */
+public interface SyntaxHighlighter {
+ /**
+ * @deprecated
+ * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
+ * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.lang.Language, com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
+ */
+ SyntaxHighlighterProvider PROVIDER =
+ new FileTypeExtensionFactory<SyntaxHighlighterProvider>(SyntaxHighlighterProvider.class, "com.intellij.syntaxHighlighter").get();
+
+ /**
+ * Returns the lexer used for highlighting the file. The lexer is invoked incrementally when the file is changed, so it must be
+ * capable of saving/restoring state and resuming lexing from the middle of the file.
+ *
+ * @return The lexer implementation.
+ */
+ @NotNull
+ Lexer getHighlightingLexer();
+
+ /**
+ * Returns the list of text attribute keys used for highlighting the specified token type. The attributes of all attribute keys
+ * returned for the token type are successively merged to obtain the color and attributes of the token.
+ *
+ * @param tokenType The token type for which the highlighting is requested.
+ * @return The array of text attribute keys.
+ */
+ @NotNull
+ TextAttributesKey[] getTokenHighlights(IElementType tokenType);
+}
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java
new file mode 100644
index 0000000..7f9fc89
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.fileTypes;
+
+import com.intellij.lang.Language;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author max
+ */
+public abstract class SyntaxHighlighterFactory {
+ public static final SyntaxHighlighterLanguageFactory LANGUAGE_FACTORY = new SyntaxHighlighterLanguageFactory();
+
+ /**
+ * Returns syntax highlighter for the given language.
+ *
+ * @param language a {@code Language} to get highlighter for
+ * @param project might be necessary to gather various project settings from
+ * @param file might be necessary to collect file specific settings
+ * @return {@code SyntaxHighlighter} interface implementation for the given file type
+ */
+ public static SyntaxHighlighter getSyntaxHighlighter(@NotNull Language language, @Nullable Project project, @Nullable VirtualFile file) {
+ return LANGUAGE_FACTORY.forLanguage(language).getSyntaxHighlighter(project, file);
+ }
+
+ /**
+ * Returns syntax highlighter for the given file type.
+ * Note: it is recommended to use {@link #getSyntaxHighlighter(Language, Project, VirtualFile)} in most cases,
+ * and use this method only when you are do not know the language you use.
+ *
+ * @param fileType a file type to use to select appropriate highlighter
+ * @param project might be necessary to gather various project settings from
+ * @param file might be necessary to collect file specific settings
+ * @return {@code SyntaxHighlighter} interface implementation for the given file type
+ */
+ @Nullable
+ public static SyntaxHighlighter getSyntaxHighlighter(@NotNull FileType fileType, @Nullable Project project, @Nullable VirtualFile file) {
+ return SyntaxHighlighter.PROVIDER.create(fileType, project, file);
+ }
+
+ /**
+ * Override this method to provide syntax highlighting (coloring) capabilities for your language implementation.
+ * By syntax highlighting we mean highlighting of keywords, comments, braces etc. where lexing the file content is enough
+ * to identify proper highlighting attributes.
+ * <p/>
+ * Default implementation doesn't highlight anything.
+ *
+ * @param project might be necessary to gather various project settings from.
+ * @param virtualFile might be necessary to collect file specific settings
+ * @return <code>SyntaxHighlighter</code> interface implementation for this particular language.
+ */
+ @NotNull
+ public abstract SyntaxHighlighter getSyntaxHighlighter(@Nullable Project project, @Nullable VirtualFile virtualFile);
+}
\ No newline at end of file
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterLanguageFactory.java b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterLanguageFactory.java
new file mode 100644
index 0000000..dae292f0
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterLanguageFactory.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.openapi.fileTypes;
+
+import com.intellij.lang.LanguageExtension;
+
+public class SyntaxHighlighterLanguageFactory extends LanguageExtension<SyntaxHighlighterFactory> {
+ SyntaxHighlighterLanguageFactory() {
+ super("com.intellij.lang.syntaxHighlighterFactory", new PlainSyntaxHighlighterFactory());
+ }
+}
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterProvider.java b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterProvider.java
new file mode 100644
index 0000000..bb5fb4f
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterProvider.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Created by IntelliJ IDEA.
+ * User: yole
+ * Date: 06.11.2007
+ * Time: 19:49:57
+ */
+package com.intellij.openapi.fileTypes;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public interface SyntaxHighlighterProvider {
+ @Nullable
+ SyntaxHighlighter create(@NotNull FileType fileType, @Nullable Project project, @Nullable VirtualFile file);
+}
\ No newline at end of file
diff --git a/platform/lang-api/src/com/intellij/psi/search/TodoAttributesUtil.java b/platform/editor-ui-api/src/com/intellij/psi/search/TodoAttributesUtil.java
similarity index 100%
rename from platform/lang-api/src/com/intellij/psi/search/TodoAttributesUtil.java
rename to platform/editor-ui-api/src/com/intellij/psi/search/TodoAttributesUtil.java
diff --git a/platform/editor-ui-ex/editor-ui-ex.iml b/platform/editor-ui-ex/editor-ui-ex.iml
index 7d91a31..ce87b28 100644
--- a/platform/editor-ui-ex/editor-ui-ex.iml
+++ b/platform/editor-ui-ex/editor-ui-ex.iml
@@ -11,6 +11,8 @@
<orderEntry type="module" module-name="util" exported="" />
<orderEntry type="module" module-name="annotations" exported="" />
<orderEntry type="module" module-name="core-impl" exported="" />
+ <orderEntry type="module" module-name="indexing-impl" />
+ <orderEntry type="module" module-name="projectModel-api" />
</component>
</module>
diff --git a/platform/editor-ui-ex/src/com/intellij/ide/todo/TodoConfiguration.java b/platform/editor-ui-ex/src/com/intellij/ide/todo/TodoConfiguration.java
new file mode 100644
index 0000000..1eb963e
--- /dev/null
+++ b/platform/editor-ui-ex/src/com/intellij/ide/todo/TodoConfiguration.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.ide.todo;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.components.NamedComponent;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.psi.search.*;
+import com.intellij.util.EventDispatcher;
+import com.intellij.util.messages.MessageBus;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Vladimir Kondratyev
+ */
+public class TodoConfiguration implements NamedComponent, JDOMExternalizable {
+ private TodoPattern[] myTodoPatterns;
+ private TodoFilter[] myTodoFilters;
+ private IndexPattern[] myIndexPatterns;
+
+ private final EventDispatcher<PropertyChangeListener> myPropertyChangeMulticaster = EventDispatcher.create(PropertyChangeListener.class);
+
+ @NonNls public static final String PROP_TODO_PATTERNS = "todoPatterns";
+ @NonNls public static final String PROP_TODO_FILTERS = "todoFilters";
+ @NonNls private static final String ELEMENT_PATTERN = "pattern";
+ @NonNls private static final String ELEMENT_FILTER = "filter";
+ private final MessageBus myMessageBus;
+
+ /**
+ * Invoked by reflection
+ */
+ TodoConfiguration(@NotNull MessageBus messageBus) {
+ myMessageBus = messageBus;
+ resetToDefaultTodoPatterns();
+ }
+
+ public void resetToDefaultTodoPatterns() {
+ myTodoPatterns = new TodoPattern[]{
+ new TodoPattern("\\btodo\\b.*", TodoAttributesUtil.createDefault(), false),
+ new TodoPattern("\\bfixme\\b.*", TodoAttributesUtil.createDefault(), false),
+ };
+ myTodoFilters = new TodoFilter[]{};
+ buildIndexPatterns();
+ }
+
+ private void buildIndexPatterns() {
+ myIndexPatterns = new IndexPattern[myTodoPatterns.length];
+ for(int i=0; i<myTodoPatterns.length; i++) {
+ myIndexPatterns [i] = myTodoPatterns [i].getIndexPattern();
+ }
+ }
+
+ public static TodoConfiguration getInstance() {
+ return ServiceManager.getService(TodoConfiguration.class);
+ }
+
+ @Override
+ @NotNull
+ public String getComponentName() {
+ return "TodoConfiguration";
+ }
+
+ @NotNull
+ public TodoPattern[] getTodoPatterns() {
+ return myTodoPatterns;
+ }
+
+ @NotNull
+ public IndexPattern[] getIndexPatterns() {
+ return myIndexPatterns;
+ }
+
+ public void setTodoPatterns(@NotNull TodoPattern[] todoPatterns) {
+ doSetTodoPatterns(todoPatterns, true);
+ }
+
+ private void doSetTodoPatterns(@NotNull TodoPattern[] todoPatterns, final boolean shouldNotifyIndices) {
+ TodoPattern[] oldTodoPatterns = myTodoPatterns;
+ IndexPattern[] oldIndexPatterns = myIndexPatterns;
+
+ myTodoPatterns = todoPatterns;
+ buildIndexPatterns();
+
+ // only trigger index refresh actual index patterns have changed
+ if (shouldNotifyIndices && !Arrays.deepEquals(myIndexPatterns, oldIndexPatterns)) {
+ final PropertyChangeEvent event =
+ new PropertyChangeEvent(this, IndexPatternProvider.PROP_INDEX_PATTERNS, oldTodoPatterns, todoPatterns);
+ myMessageBus.syncPublisher(IndexPatternProvider.INDEX_PATTERNS_CHANGED).propertyChange(event);
+ }
+
+ // only trigger gui and code daemon refresh when either the index patterns or presentation attributes have changed
+ if (!Arrays.deepEquals(myTodoPatterns, oldTodoPatterns)) {
+ final PropertyChangeListener multicaster = myPropertyChangeMulticaster.getMulticaster();
+ multicaster.propertyChange(new PropertyChangeEvent(this, PROP_TODO_PATTERNS, oldTodoPatterns, todoPatterns));
+ }
+ }
+
+ /**
+ * @return <code>TodoFilter</code> with specified <code>name</code>. Method returns
+ * <code>null</code> if there is no filter with <code>name</code>.
+ */
+ public TodoFilter getTodoFilter(String name) {
+ for (TodoFilter filter : myTodoFilters) {
+ if (filter.getName().equals(name)) {
+ return filter;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return all <code>TodoFilter</code>s.
+ */
+ @NotNull
+ public TodoFilter[] getTodoFilters() {
+ return myTodoFilters;
+ }
+
+ public void setTodoFilters(@NotNull TodoFilter[] filters) {
+ TodoFilter[] oldFilters = myTodoFilters;
+ myTodoFilters = filters;
+ myPropertyChangeMulticaster.getMulticaster().propertyChange(new PropertyChangeEvent(this, PROP_TODO_FILTERS, oldFilters, filters));
+ }
+
+ public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) {
+ myPropertyChangeMulticaster.addListener(listener);
+ }
+ public void addPropertyChangeListener(@NotNull PropertyChangeListener listener, @NotNull Disposable parentDisposable) {
+ myPropertyChangeMulticaster.addListener(listener,parentDisposable);
+ }
+ public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) {
+ myPropertyChangeMulticaster.removeListener(listener);
+ }
+
+ @Override
+ public void readExternal(Element element) throws InvalidDataException {
+ List<TodoPattern> patternsList = new ArrayList<TodoPattern>();
+ List<TodoFilter> filtersList = new ArrayList<TodoFilter>();
+ for (Element child : element.getChildren()) {
+ if (ELEMENT_PATTERN.equals(child.getName())) {
+ TodoPattern pattern = new TodoPattern(TodoAttributesUtil.createDefault());
+ pattern.readExternal(child, TodoAttributesUtil.getDefaultColorSchemeTextAttributes());
+ patternsList.add(pattern);
+ }
+ else if (ELEMENT_FILTER.equals(child.getName())) {
+ TodoPattern[] patterns = patternsList.toArray(new TodoPattern[patternsList.size()]);
+ TodoFilter filter = new TodoFilter();
+ filter.readExternal(child, patterns);
+ filtersList.add(filter);
+ }
+ }
+ doSetTodoPatterns(patternsList.toArray(new TodoPattern[patternsList.size()]), false);
+ setTodoFilters(filtersList.toArray(new TodoFilter[filtersList.size()]));
+ }
+
+ @Override
+ public void writeExternal(Element element) throws WriteExternalException {
+ final TodoPattern[] todoPatterns = myTodoPatterns;
+ for (TodoPattern pattern : todoPatterns) {
+ Element child = new Element(ELEMENT_PATTERN);
+ pattern.writeExternal(child);
+ element.addContent(child);
+ }
+ for (TodoFilter filter : myTodoFilters) {
+ Element child = new Element(ELEMENT_FILTER);
+ filter.writeExternal(child, todoPatterns);
+ element.addContent(child);
+ }
+ }
+
+ public void colorSettingsChanged() {
+ for (TodoPattern pattern : myTodoPatterns) {
+ TodoAttributes attributes = pattern.getAttributes();
+ if (!attributes.shouldUseCustomTodoColor()) {
+ attributes.setUseCustomTodoColor(false, TodoAttributesUtil.getDefaultColorSchemeTextAttributes());
+ }
+ }
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/todo/TodoIndexPatternProvider.java b/platform/editor-ui-ex/src/com/intellij/ide/todo/TodoIndexPatternProvider.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/ide/todo/TodoIndexPatternProvider.java
rename to platform/editor-ui-ex/src/com/intellij/ide/todo/TodoIndexPatternProvider.java
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java b/platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java
similarity index 100%
rename from platform/platform-impl/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java
rename to platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/IndexTodoCacheManagerImpl.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/IndexTodoCacheManagerImpl.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/cache/impl/IndexTodoCacheManagerImpl.java
rename to platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/IndexTodoCacheManagerImpl.java
diff --git a/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java
new file mode 100644
index 0000000..556db38
--- /dev/null
+++ b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.impl.cache.impl.id;
+
+import com.intellij.ide.highlighter.HighlighterFactory;
+import com.intellij.lang.Language;
+import com.intellij.lang.LanguageParserDefinitions;
+import com.intellij.lang.ParserDefinition;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter;
+import com.intellij.openapi.editor.highlighter.EditorHighlighter;
+import com.intellij.openapi.editor.highlighter.HighlighterIterator;
+import com.intellij.openapi.fileTypes.*;
+import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.CustomHighlighterTokenType;
+import com.intellij.psi.impl.cache.impl.BaseFilterLexer;
+import com.intellij.psi.impl.cache.CacheUtil;
+import com.intellij.psi.impl.cache.impl.IndexPatternUtil;
+import com.intellij.psi.impl.cache.impl.OccurrenceConsumer;
+import com.intellij.psi.impl.cache.impl.todo.TodoIndexEntry;
+import com.intellij.psi.impl.cache.impl.todo.TodoIndexers;
+import com.intellij.psi.search.IndexPattern;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.indexing.DataIndexer;
+import com.intellij.util.indexing.FileContent;
+import com.intellij.util.indexing.SubstitutedFileType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Author: dmitrylomov
+ */
+public abstract class PlatformIdTableBuilding {
+ public static final Key<EditorHighlighter> EDITOR_HIGHLIGHTER = new Key<EditorHighlighter>("Editor");
+ private static final Map<FileType, DataIndexer<TodoIndexEntry, Integer, FileContent>> ourTodoIndexers = new HashMap<FileType, DataIndexer<TodoIndexEntry, Integer, FileContent>>();
+ private static final TokenSet ABSTRACT_FILE_COMMENT_TOKENS = TokenSet.create(CustomHighlighterTokenType.LINE_COMMENT, CustomHighlighterTokenType.MULTI_LINE_COMMENT);
+
+ private PlatformIdTableBuilding() {}
+
+ @Nullable
+ public static DataIndexer<TodoIndexEntry, Integer, FileContent> getTodoIndexer(FileType fileType, final VirtualFile virtualFile) {
+ final DataIndexer<TodoIndexEntry, Integer, FileContent> indexer = ourTodoIndexers.get(fileType);
+
+ if (indexer != null) {
+ return indexer;
+ }
+
+ final DataIndexer<TodoIndexEntry, Integer, FileContent> extIndexer;
+ if (fileType instanceof SubstitutedFileType && !((SubstitutedFileType)fileType).isSameFileType()) {
+ SubstitutedFileType sft = (SubstitutedFileType)fileType;
+ extIndexer =
+ new CompositeTodoIndexer(getTodoIndexer(sft.getOriginalFileType(), virtualFile), getTodoIndexer(sft.getFileType(), virtualFile));
+ }
+ else {
+ extIndexer = TodoIndexers.INSTANCE.forFileType(fileType);
+ }
+ if (extIndexer != null) {
+ return extIndexer;
+ }
+
+ if (fileType instanceof LanguageFileType) {
+ final Language lang = ((LanguageFileType)fileType).getLanguage();
+ final ParserDefinition parserDef = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
+ final TokenSet commentTokens = parserDef != null ? parserDef.getCommentTokens() : null;
+ if (commentTokens != null) {
+ return new TokenSetTodoIndexer(commentTokens, virtualFile);
+ }
+ }
+
+ if (fileType instanceof CustomSyntaxTableFileType) {
+ return new TokenSetTodoIndexer(ABSTRACT_FILE_COMMENT_TOKENS, virtualFile);
+ }
+
+ return null;
+ }
+
+ public static boolean checkCanUseCachedEditorHighlighter(final CharSequence chars, final EditorHighlighter editorHighlighter) {
+ assert editorHighlighter instanceof LexerEditorHighlighter;
+ final boolean b = ((LexerEditorHighlighter)editorHighlighter).checkContentIsEqualTo(chars);
+ if (!b) {
+ final Logger logger = Logger.getInstance(IdTableBuilding.class.getName());
+ logger.warn("Unexpected mismatch of editor highlighter content with indexing content");
+ }
+ return b;
+ }
+
+ @Deprecated
+ public static void registerTodoIndexer(@NotNull FileType fileType, DataIndexer<TodoIndexEntry, Integer, FileContent> indexer) {
+ ourTodoIndexers.put(fileType, indexer);
+ }
+
+ public static boolean isTodoIndexerRegistered(@NotNull FileType fileType) {
+ return ourTodoIndexers.containsKey(fileType) || TodoIndexers.INSTANCE.forFileType(fileType) != null || fileType instanceof InternalFileType;
+ }
+
+ private static class CompositeTodoIndexer implements DataIndexer<TodoIndexEntry, Integer, FileContent> {
+ private final DataIndexer<TodoIndexEntry, Integer, FileContent>[] indexers;
+
+ public CompositeTodoIndexer(@NotNull DataIndexer<TodoIndexEntry, Integer, FileContent>... indexers) {
+ this.indexers = indexers;
+ }
+
+ @NotNull
+ @Override
+ public Map<TodoIndexEntry, Integer> map(FileContent inputData) {
+ Map<TodoIndexEntry, Integer> result = ContainerUtil.newTroveMap();
+ for (DataIndexer<TodoIndexEntry, Integer, FileContent> indexer : indexers) {
+ for (Map.Entry<TodoIndexEntry, Integer> entry : indexer.map(inputData).entrySet()) {
+ TodoIndexEntry key = entry.getKey();
+ if (result.containsKey(key)) {
+ result.put(key, result.get(key) + entry.getValue());
+ } else {
+ result.put(key, entry.getValue());
+ }
+ }
+ }
+ return result;
+ }
+ }
+
+ private static class TokenSetTodoIndexer implements DataIndexer<TodoIndexEntry, Integer, FileContent> {
+ @NotNull private final TokenSet myCommentTokens;
+ private final VirtualFile myFile;
+
+ public TokenSetTodoIndexer(@NotNull final TokenSet commentTokens, @NotNull final VirtualFile file) {
+ myCommentTokens = commentTokens;
+ myFile = file;
+ }
+
+ @Override
+ @NotNull
+ public Map<TodoIndexEntry, Integer> map(final FileContent inputData) {
+ if (IndexPatternUtil.getIndexPatternCount() > 0) {
+ final CharSequence chars = inputData.getContentAsText();
+ final OccurrenceConsumer occurrenceConsumer = new OccurrenceConsumer(null, true);
+ EditorHighlighter highlighter;
+
+ final EditorHighlighter editorHighlighter = inputData.getUserData(EDITOR_HIGHLIGHTER);
+ if (editorHighlighter != null && checkCanUseCachedEditorHighlighter(chars, editorHighlighter)) {
+ highlighter = editorHighlighter;
+ }
+ else {
+ highlighter = HighlighterFactory.createHighlighter(null, myFile);
+ highlighter.setText(chars);
+ }
+
+ final int documentLength = chars.length();
+ BaseFilterLexer.TodoScanningState todoScanningState = null;
+ final HighlighterIterator iterator = highlighter.createIterator(0);
+
+ while (!iterator.atEnd()) {
+ final IElementType token = iterator.getTokenType();
+
+ if (myCommentTokens.contains(token) || CacheUtil.isInComments(token)) {
+ int start = iterator.getStart();
+ if (start >= documentLength) break;
+ int end = iterator.getEnd();
+
+ todoScanningState = BaseFilterLexer.advanceTodoItemsCount(
+ chars.subSequence(start, Math.min(end, documentLength)),
+ occurrenceConsumer,
+ todoScanningState
+ );
+ if (end > documentLength) break;
+ }
+ iterator.advance();
+ }
+ final Map<TodoIndexEntry, Integer> map = new HashMap<TodoIndexEntry, Integer>();
+ for (IndexPattern pattern : IndexPatternUtil.getIndexPatterns()) {
+ final int count = occurrenceConsumer.getOccurrenceCount(pattern);
+ if (count > 0) {
+ map.put(new TodoIndexEntry(pattern.getPatternString(), pattern.isCaseSensitive()), count);
+ }
+ }
+ return map;
+ }
+ return Collections.emptyMap();
+ }
+ }
+
+ public static class PlainTextTodoIndexer implements DataIndexer<TodoIndexEntry, Integer, FileContent> {
+ @Override
+ @NotNull
+ public Map<TodoIndexEntry, Integer> map(final FileContent inputData) {
+ String chars = inputData.getContentAsText().toString(); // matching strings is faster than HeapCharBuffer
+
+ final IndexPattern[] indexPatterns = IndexPatternUtil.getIndexPatterns();
+ if (indexPatterns.length <= 0) {
+ return Collections.emptyMap();
+ }
+ OccurrenceConsumer occurrenceConsumer = new OccurrenceConsumer(null, true);
+ for (IndexPattern indexPattern : indexPatterns) {
+ Pattern pattern = indexPattern.getPattern();
+ if (pattern != null) {
+ Matcher matcher = pattern.matcher(chars);
+ while (matcher.find()) {
+ if (matcher.start() != matcher.end()) {
+ occurrenceConsumer.incTodoOccurrence(indexPattern);
+ }
+ }
+ }
+ }
+ Map<TodoIndexEntry, Integer> map = new HashMap<TodoIndexEntry, Integer>();
+ for (IndexPattern indexPattern : indexPatterns) {
+ final int count = occurrenceConsumer.getOccurrenceCount(indexPattern);
+ if (count > 0) {
+ map.put(new TodoIndexEntry(indexPattern.getPatternString(), indexPattern.isCaseSensitive()), count);
+ }
+ }
+ return map;
+ }
+
+ }
+
+ static {
+ IdTableBuilding.registerIdIndexer(PlainTextFileType.INSTANCE, new IdTableBuilding.PlainTextIndexer());
+ registerTodoIndexer(PlainTextFileType.INSTANCE, new PlainTextTodoIndexer());
+
+ //IdTableBuilding.registerIdIndexer(StdFileTypes.IDEA_MODULE, null);
+ //IdTableBuilding.registerIdIndexer(StdFileTypes.IDEA_WORKSPACE, null);
+ //IdTableBuilding.registerIdIndexer(StdFileTypes.IDEA_PROJECT, null);
+
+ //registerTodoIndexer(StdFileTypes.IDEA_MODULE, null);
+ //registerTodoIndexer(StdFileTypes.IDEA_WORKSPACE, null);
+ //registerTodoIndexer(StdFileTypes.IDEA_PROJECT, null);
+ }
+}
diff --git a/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java
new file mode 100644
index 0000000..b9f8ec6
--- /dev/null
+++ b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.psi.impl.cache.impl.todo;
+
+import com.intellij.lang.Language;
+import com.intellij.lang.LanguageParserDefinitions;
+import com.intellij.lang.ParserDefinition;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.impl.cache.impl.id.PlatformIdTableBuilding;
+import com.intellij.psi.search.IndexPatternProvider;
+import com.intellij.psi.tree.TokenSet;
+import com.intellij.util.indexing.*;
+import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.KeyDescriptor;
+import com.intellij.util.messages.MessageBus;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Jan 20, 2008
+ */
+public class TodoIndex extends FileBasedIndexExtension<TodoIndexEntry, Integer> {
+ @NonNls public static final ID<TodoIndexEntry, Integer> NAME = ID.create("TodoIndex");
+
+ public TodoIndex(MessageBus messageBus) {
+ messageBus.connect().subscribe(IndexPatternProvider.INDEX_PATTERNS_CHANGED, new PropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ FileBasedIndex.getInstance().requestRebuild(NAME);
+ }
+ });
+ }
+
+ private final KeyDescriptor<TodoIndexEntry> myKeyDescriptor = new KeyDescriptor<TodoIndexEntry>() {
+ @Override
+ public int getHashCode(final TodoIndexEntry value) {
+ return value.hashCode();
+ }
+
+ @Override
+ public boolean isEqual(final TodoIndexEntry val1, final TodoIndexEntry val2) {
+ return val1.equals(val2);
+ }
+
+ @Override
+ public void save(final DataOutput out, final TodoIndexEntry value) throws IOException {
+ out.writeUTF(value.pattern);
+ out.writeBoolean(value.caseSensitive);
+ }
+
+ @Override
+ public TodoIndexEntry read(final DataInput in) throws IOException {
+ final String pattern = in.readUTF();
+ final boolean caseSensitive = in.readBoolean();
+ return new TodoIndexEntry(pattern, caseSensitive);
+ }
+ };
+
+ private final DataExternalizer<Integer> myValueExternalizer = new DataExternalizer<Integer>() {
+ @Override
+ public void save(final DataOutput out, final Integer value) throws IOException {
+ out.writeInt(value.intValue());
+ }
+
+ @Override
+ public Integer read(final DataInput in) throws IOException {
+ return Integer.valueOf(in.readInt());
+ }
+ };
+
+ private final DataIndexer<TodoIndexEntry, Integer, FileContent> myIndexer = new DataIndexer<TodoIndexEntry, Integer, FileContent>() {
+ @Override
+ @NotNull
+ public Map<TodoIndexEntry,Integer> map(final FileContent inputData) {
+ final VirtualFile file = inputData.getFile();
+ final DataIndexer<TodoIndexEntry, Integer, FileContent> indexer = PlatformIdTableBuilding
+ .getTodoIndexer(inputData.getFileType(), file);
+ if (indexer != null) {
+ return indexer.map(inputData);
+ }
+ return Collections.emptyMap();
+ }
+ };
+
+ private final FileBasedIndex.InputFilter myInputFilter = new FileBasedIndex.InputFilter() {
+ @Override
+ public boolean acceptInput(final VirtualFile file) {
+ if (!file.isInLocalFileSystem()) {
+ return false; // do not index TODOs in library sources
+ }
+
+ final FileType fileType = file.getFileType();
+
+ if (fileType instanceof LanguageFileType) {
+ final Language lang = ((LanguageFileType)fileType).getLanguage();
+ final ParserDefinition parserDef = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
+ final TokenSet commentTokens = parserDef != null ? parserDef.getCommentTokens() : null;
+ return commentTokens != null;
+ }
+
+ return PlatformIdTableBuilding.isTodoIndexerRegistered(fileType) ||
+ fileType instanceof CustomSyntaxTableFileType;
+ }
+ };
+
+ @Override
+ public int getVersion() {
+ return 5;
+ }
+
+ @Override
+ public boolean dependsOnFileContent() {
+ return true;
+ }
+
+ @NotNull
+ @Override
+ public ID<TodoIndexEntry, Integer> getName() {
+ return NAME;
+ }
+
+ @NotNull
+ @Override
+ public DataIndexer<TodoIndexEntry, Integer, FileContent> getIndexer() {
+ return myIndexer;
+ }
+
+ @Override
+ public KeyDescriptor<TodoIndexEntry> getKeyDescriptor() {
+ return myKeyDescriptor;
+ }
+
+ @Override
+ public DataExternalizer<Integer> getValueExternalizer() {
+ return myValueExternalizer;
+ }
+
+ @Override
+ public FileBasedIndex.InputFilter getInputFilter() {
+ return myInputFilter;
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternOccurrenceImpl.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/IndexPatternOccurrenceImpl.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternOccurrenceImpl.java
rename to platform/editor-ui-ex/src/com/intellij/psi/impl/search/IndexPatternOccurrenceImpl.java
diff --git a/platform/editor-ui-ex/src/com/intellij/psi/impl/search/IndexPatternSearcher.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/IndexPatternSearcher.java
new file mode 100644
index 0000000..d108c60
--- /dev/null
+++ b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/IndexPatternSearcher.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.psi.impl.search;
+
+import com.intellij.lang.Language;
+import com.intellij.lang.LanguageParserDefinitions;
+import com.intellij.lang.ParserDefinition;
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.SyntaxHighlighter;
+import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
+import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.cache.TodoCacheManager;
+import com.intellij.psi.search.IndexPattern;
+import com.intellij.psi.search.IndexPatternOccurrence;
+import com.intellij.psi.search.IndexPatternProvider;
+import com.intellij.psi.search.searches.IndexPatternSearch;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
+import com.intellij.util.Processor;
+import com.intellij.util.QueryExecutor;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.text.CharSequenceSubSequence;
+import gnu.trove.TIntArrayList;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author yole
+ */
+public class IndexPatternSearcher implements QueryExecutor<IndexPatternOccurrence, IndexPatternSearch.SearchParameters> {
+ @Override
+ public boolean execute(@NotNull final IndexPatternSearch.SearchParameters queryParameters,
+ @NotNull final Processor<IndexPatternOccurrence> consumer) {
+ final PsiFile file = queryParameters.getFile();
+ VirtualFile virtualFile = file.getVirtualFile();
+ if (file instanceof PsiBinaryFile || file instanceof PsiCompiledElement || virtualFile == null) {
+ return true;
+ }
+
+ final TodoCacheManager cacheManager = TodoCacheManager.SERVICE.getInstance(file.getProject());
+ final IndexPatternProvider patternProvider = queryParameters.getPatternProvider();
+ int count = patternProvider != null
+ ? cacheManager.getTodoCount(virtualFile, patternProvider)
+ : cacheManager.getTodoCount(virtualFile, queryParameters.getPattern());
+ return count == 0 || executeImpl(queryParameters, consumer);
+ }
+
+ protected static boolean executeImpl(IndexPatternSearch.SearchParameters queryParameters,
+ Processor<IndexPatternOccurrence> consumer) {
+ final IndexPatternProvider patternProvider = queryParameters.getPatternProvider();
+ final PsiFile file = queryParameters.getFile();
+ TIntArrayList commentStarts = new TIntArrayList();
+ TIntArrayList commentEnds = new TIntArrayList();
+
+ final CharSequence chars = file.getViewProvider().getContents();
+ findCommentTokenRanges(file, chars, queryParameters.getRange(), commentStarts, commentEnds);
+ TIntArrayList occurrences = new TIntArrayList(1);
+ IndexPattern[] patterns = patternProvider != null ? patternProvider.getIndexPatterns() : null;
+
+ for (int i = 0; i < commentStarts.size(); i++) {
+ int commentStart = commentStarts.get(i);
+ int commentEnd = commentEnds.get(i);
+ occurrences.resetQuick();
+
+ if (patternProvider != null) {
+ for (int j = patterns.length - 1; j >=0; --j) {
+ if (!collectPatternMatches(patterns[j], chars, commentStart, commentEnd, file, queryParameters.getRange(), consumer, occurrences)) {
+ return false;
+ }
+ }
+ }
+ else {
+ if (!collectPatternMatches(queryParameters.getPattern(), chars, commentStart, commentEnd, file, queryParameters.getRange(),
+ consumer, occurrences)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+
+ private static final TokenSet COMMENT_TOKENS =
+ TokenSet.create(CustomHighlighterTokenType.LINE_COMMENT, CustomHighlighterTokenType.MULTI_LINE_COMMENT);
+
+ private static void findCommentTokenRanges(final PsiFile file,
+ final CharSequence chars,
+ final TextRange range,
+ final TIntArrayList commentStarts,
+ final TIntArrayList commentEnds) {
+ if (file instanceof PsiPlainTextFile) {
+ FileType fType = file.getFileType();
+ if (fType instanceof CustomSyntaxTableFileType) {
+ Lexer lexer = SyntaxHighlighterFactory.getSyntaxHighlighter(fType, file.getProject(), file.getVirtualFile()).getHighlightingLexer();
+ findComments(lexer, chars, range, COMMENT_TOKENS, commentStarts, commentEnds, null);
+ }
+ else {
+ commentStarts.add(0);
+ commentEnds.add(file.getTextLength());
+ }
+ }
+ else {
+ final FileViewProvider viewProvider = file.getViewProvider();
+ final Set<Language> relevantLanguages = viewProvider.getLanguages();
+ for (Language lang : relevantLanguages) {
+ final TIntArrayList commentStartsList = new TIntArrayList();
+ final TIntArrayList commentEndsList = new TIntArrayList();
+
+ final SyntaxHighlighter syntaxHighlighter =
+ SyntaxHighlighterFactory.getSyntaxHighlighter(lang, file.getProject(), file.getVirtualFile());
+ Lexer lexer = syntaxHighlighter.getHighlightingLexer();
+ TokenSet commentTokens = null;
+ IndexPatternBuilder builderForFile = null;
+ for (IndexPatternBuilder builder : Extensions.getExtensions(IndexPatternBuilder.EP_NAME)) {
+ Lexer lexerFromBuilder = builder.getIndexingLexer(file);
+ if (lexerFromBuilder != null) {
+ lexer = lexerFromBuilder;
+ commentTokens = builder.getCommentTokenSet(file);
+ builderForFile = builder;
+ }
+ }
+ if (builderForFile == null) {
+ final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
+ if (parserDefinition != null) {
+ commentTokens = parserDefinition.getCommentTokens();
+ }
+ }
+
+ if (commentTokens != null) {
+ findComments(lexer, chars, range, commentTokens, commentStartsList, commentEndsList, builderForFile);
+ mergeCommentLists(commentStarts, commentEnds, commentStartsList, commentEndsList);
+ }
+ }
+ }
+ }
+
+ private static void mergeCommentLists(TIntArrayList commentStarts,
+ TIntArrayList commentEnds,
+ TIntArrayList commentStartsList,
+ TIntArrayList commentEndsList) {
+ if (commentStarts.isEmpty() && commentEnds.isEmpty()) {
+ commentStarts.add(commentStartsList.toNativeArray());
+ commentEnds.add(commentEndsList.toNativeArray());
+ return;
+ }
+
+ ContainerUtil.mergeSortedArrays(commentStarts, commentEnds, commentStartsList, commentEndsList);
+ }
+
+ private static void findComments(final Lexer lexer,
+ final CharSequence chars,
+ final TextRange range,
+ final TokenSet commentTokens,
+ final TIntArrayList commentStarts,
+ final TIntArrayList commentEnds,
+ final IndexPatternBuilder builderForFile) {
+ for (lexer.start(chars); ; lexer.advance()) {
+ IElementType tokenType = lexer.getTokenType();
+ if (tokenType == null) break;
+
+ if (range != null) {
+ if (lexer.getTokenEnd() <= range.getStartOffset()) continue;
+ if (lexer.getTokenStart() >= range.getEndOffset()) break;
+ }
+
+ boolean isComment = commentTokens.contains(tokenType);
+ if (!isComment) {
+ final Language commentLang = tokenType.getLanguage();
+ final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(commentLang);
+ if (parserDefinition != null) {
+ final TokenSet langCommentTokens = parserDefinition.getCommentTokens();
+ isComment = langCommentTokens.contains(tokenType);
+ }
+ }
+
+ if (isComment) {
+ final int startDelta = builderForFile != null ? builderForFile.getCommentStartDelta(lexer.getTokenType()) : 0;
+ final int endDelta = builderForFile != null ? builderForFile.getCommentEndDelta(lexer.getTokenType()) : 0;
+
+ int start = lexer.getTokenStart() + startDelta;
+ int end = lexer.getTokenEnd() - endDelta;
+ assert start <= end : "Invalid comment range: " +
+ new TextRange(start, end) +
+ "; lexer token range=" +
+ new TextRange(lexer.getTokenStart(), lexer.getTokenEnd()) +
+ "; delta=" +
+ new TextRange(startDelta, endDelta) +
+ "; lexer=" +
+ lexer +
+ "; builder=" +
+ builderForFile +
+ "; chars length:" +
+ chars.length();
+ assert end <= chars.length() : "Invalid comment end: " +
+ new TextRange(start, end) +
+ "; lexer token range=" +
+ new TextRange(lexer.getTokenStart(), lexer.getTokenEnd()) +
+ "; delta=" +
+ new TextRange(startDelta, endDelta) +
+ "; lexer=" +
+ lexer +
+ "; builder=" +
+ builderForFile +
+ "; chars length:" +
+ chars.length();
+ commentStarts.add(start);
+ commentEnds.add(end);
+ }
+ }
+ }
+
+ private static boolean collectPatternMatches(IndexPattern indexPattern,
+ CharSequence chars,
+ int commentStart,
+ int commentEnd,
+ PsiFile file,
+ TextRange range,
+ Processor<IndexPatternOccurrence> consumer,
+ TIntArrayList matches
+ ) {
+ Pattern pattern = indexPattern.getPattern();
+ if (pattern != null) {
+ ProgressManager.checkCanceled();
+
+ CharSequence input = new CharSequenceSubSequence(chars, commentStart, commentEnd);
+ Matcher matcher = pattern.matcher(input);
+ while (true) {
+ //long time1 = System.currentTimeMillis();
+ boolean found = matcher.find();
+ //long time2 = System.currentTimeMillis();
+ //System.out.println("scanned text of length " + (lexer.getTokenEnd() - lexer.getTokenStart() + " in " + (time2 - time1) + " ms"));
+
+ if (!found) break;
+ int start = matcher.start() + commentStart;
+ int end = matcher.end() + commentStart;
+ if (start != end) {
+ if ((range == null || range.getStartOffset() <= start && end <= range.getEndOffset()) && matches.indexOf(start) == -1) {
+ matches.add(start);
+ if (!consumer.process(new IndexPatternOccurrenceImpl(file, start, end, indexPattern))) {
+ return false;
+ }
+ }
+ }
+
+ ProgressManager.checkCanceled();
+ }
+ }
+ return true;
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/LightIndexPatternSearch.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/LightIndexPatternSearch.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/search/LightIndexPatternSearch.java
rename to platform/editor-ui-ex/src/com/intellij/psi/impl/search/LightIndexPatternSearch.java
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/LightIndexPatternSearcher.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/LightIndexPatternSearcher.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/search/LightIndexPatternSearcher.java
rename to platform/editor-ui-ex/src/com/intellij/psi/impl/search/LightIndexPatternSearcher.java
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/PsiTodoSearchHelperImpl.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/PsiTodoSearchHelperImpl.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/search/PsiTodoSearchHelperImpl.java
rename to platform/editor-ui-ex/src/com/intellij/psi/impl/search/PsiTodoSearchHelperImpl.java
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/TodoItemsCreator.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/TodoItemsCreator.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/search/TodoItemsCreator.java
rename to platform/editor-ui-ex/src/com/intellij/psi/impl/search/TodoItemsCreator.java
diff --git a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java
index 8e46a2f..51fb0d6 100644
--- a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java
+++ b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,10 +22,8 @@
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.picocontainer.*;
-import org.picocontainer.defaults.AssignabilityRegistrationException;
import org.picocontainer.defaults.CachingComponentAdapter;
import org.picocontainer.defaults.ConstructorInjectionComponentAdapter;
-import org.picocontainer.defaults.NotConcreteRegistrationException;
/**
* @author Alexander Kireyev
@@ -33,6 +31,7 @@
*/
public class ExtensionComponentAdapter implements LoadingOrder.Orderable, AssignableToComponentAdapter {
public static final ExtensionComponentAdapter[] EMPTY_ARRAY = new ExtensionComponentAdapter[0];
+
private Object myComponentInstance;
private final String myImplementationClassName;
private final Element myExtensionElement;
@@ -65,36 +64,42 @@
}
@Override
- public Object getComponentInstance(final PicoContainer container)
- throws PicoInitializationException,
- PicoIntrospectionException,
- AssignabilityRegistrationException,
- NotConcreteRegistrationException,
- ProcessCanceledException {
+ public Object getComponentInstance(final PicoContainer container) throws PicoException, ProcessCanceledException {
if (myComponentInstance == null) {
- if (Element.class.equals(getComponentImplementation())) {
- myComponentInstance = myExtensionElement;
- }
- else {
- Object componentInstance = getDelegate().getComponentInstance(container);
-
- if (myDeserializeInstance) {
- try {
- XmlSerializer.deserializeInto(componentInstance, myExtensionElement);
- }
- catch (Exception e) {
- throw new PicoInitializationException(e);
- }
+ try {
+ if (Element.class.equals(getComponentImplementation())) {
+ myComponentInstance = myExtensionElement;
}
+ else {
+ Object componentInstance = getDelegate().getComponentInstance(container);
- ExtensionInitializer initializer = (ExtensionInitializer)container.getComponentInstance(ExtensionInitializer.class);
- if (initializer != null) {
- initializer.initExtension(componentInstance);
+ if (myDeserializeInstance) {
+ try {
+ XmlSerializer.deserializeInto(componentInstance, myExtensionElement);
+ }
+ catch (Exception e) {
+ throw new PicoInitializationException(e);
+ }
+ }
+
+ ExtensionInitializer initializer = (ExtensionInitializer)container.getComponentInstance(ExtensionInitializer.class);
+ if (initializer != null) {
+ initializer.initExtension(componentInstance);
+ }
+
+ myComponentInstance = componentInstance;
}
- myComponentInstance = componentInstance;
}
+ catch (ProcessCanceledException e) {
+ throw e;
+ }
+ catch (Throwable t) {
+ PluginId pluginId = myPluginDescriptor != null ? myPluginDescriptor.getPluginId() : null;
+ throw new PicoPluginExtensionInitializationException(t.getMessage(), t, pluginId);
+ }
+
if (myComponentInstance instanceof PluginAware) {
- PluginAware pluginAware = (PluginAware) myComponentInstance;
+ PluginAware pluginAware = (PluginAware)myComponentInstance;
pluginAware.setPluginDescriptor(myPluginDescriptor);
}
}
@@ -161,7 +166,8 @@
private synchronized ComponentAdapter getDelegate() {
if (myDelegate == null) {
- myDelegate = new CachingComponentAdapter(new ConstructorInjectionComponentAdapter(getComponentKey(), loadClass(myImplementationClassName), null, true));
+ Class impl = loadClass(myImplementationClassName);
+ myDelegate = new CachingComponentAdapter(new ConstructorInjectionComponentAdapter(getComponentKey(), impl, null, true));
}
return myDelegate;
diff --git a/platform/extensions/src/com/intellij/openapi/extensions/impl/PicoPluginExtensionInitializationException.java b/platform/extensions/src/com/intellij/openapi/extensions/impl/PicoPluginExtensionInitializationException.java
new file mode 100644
index 0000000..07ac622
--- /dev/null
+++ b/platform/extensions/src/com/intellij/openapi/extensions/impl/PicoPluginExtensionInitializationException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.extensions.impl;
+
+import com.intellij.openapi.extensions.PluginId;
+import org.picocontainer.PicoInitializationException;
+
+public class PicoPluginExtensionInitializationException extends PicoInitializationException {
+ private final PluginId myPluginId;
+
+ public PicoPluginExtensionInitializationException(String message, Throwable cause, PluginId id) {
+ super(message, cause);
+ myPluginId = id;
+ }
+
+ public PluginId getPluginId() {
+ return myPluginId;
+ }
+}
diff --git a/platform/extensions/src/com/intellij/openapi/util/KeyedExtensionFactory.java b/platform/extensions/src/com/intellij/openapi/util/KeyedExtensionFactory.java
new file mode 100644
index 0000000..dee255d
--- /dev/null
+++ b/platform/extensions/src/com/intellij/openapi/util/KeyedExtensionFactory.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.util;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.extensions.KeyedFactoryEPBean;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.picocontainer.PicoContainer;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * @author yole
+ */
+public abstract class KeyedExtensionFactory<T, KeyT> {
+ private final Class<T> myInterfaceClass;
+ private final ExtensionPointName<KeyedFactoryEPBean> myEpName;
+ private final PicoContainer myPicoContainer;
+
+ public KeyedExtensionFactory(@NotNull final Class<T> interfaceClass, @NonNls @NotNull final String epName, @NotNull PicoContainer picoContainer) {
+ myInterfaceClass = interfaceClass;
+ myEpName = new ExtensionPointName<KeyedFactoryEPBean>(epName);
+ myPicoContainer = picoContainer;
+ }
+
+ @NotNull
+ public T get() {
+ final KeyedFactoryEPBean[] epBeans = Extensions.getExtensions(myEpName);
+ InvocationHandler handler = new InvocationHandler() {
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ //noinspection unchecked
+ KeyT keyArg = (KeyT) args [0];
+ String key = getKey(keyArg);
+ Object result = getByKey(epBeans, key, method, args);
+ if (result == null) {
+ result = getByKey(epBeans, null, method, args);
+ }
+ return result;
+ }
+ };
+ //noinspection unchecked
+ return (T)Proxy.newProxyInstance(myInterfaceClass.getClassLoader(), new Class<?>[] { myInterfaceClass }, handler );
+ }
+
+ public T getByKey(@NotNull KeyT key) {
+ final KeyedFactoryEPBean[] epBeans = Extensions.getExtensions(myEpName);
+ for (KeyedFactoryEPBean epBean : epBeans) {
+ if (Comparing.strEqual(getKey(key), epBean.key)) {
+ try {
+ if (epBean.implementationClass != null) {
+ return (T)epBean.instantiate(epBean.implementationClass, myPicoContainer);
+ }
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ return null;
+ }
+
+ private T getByKey(final KeyedFactoryEPBean[] epBeans, final String key, final Method method, final Object[] args) {
+ Object result = null;
+ for(KeyedFactoryEPBean epBean: epBeans) {
+ if (Comparing.strEqual(epBean.key, key, true)) {
+ try {
+ if (epBean.implementationClass != null) {
+ result = epBean.instantiate(epBean.implementationClass, myPicoContainer);
+ }
+ else {
+ Object factory = epBean.instantiate(epBean.factoryClass, myPicoContainer);
+ result = method.invoke(factory, args);
+ }
+ if (result != null) {
+ break;
+ }
+ }
+ catch (RuntimeException e) {
+ throw e;
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ //noinspection ConstantConditions
+ return (T)result;
+ }
+
+ public abstract String getKey(@NotNull KeyT key);
+}
+
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java
index 7b02d53..57e123b 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java
@@ -18,6 +18,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Alarm;
import com.intellij.util.containers.ContainerUtilRt;
@@ -197,12 +198,12 @@
try {
String compileOutputPath = data.getCompileOutputPath(ExternalSystemSourceType.SOURCE);
if (compileOutputPath != null) {
- extension.setCompilerOutputPath(compileOutputPath);
+ extension.setCompilerOutputPath(VfsUtilCore.pathToUrl(compileOutputPath));
}
String testCompileOutputPath = data.getCompileOutputPath(ExternalSystemSourceType.TEST);
if (testCompileOutputPath != null) {
- extension.setCompilerOutputPathForTests(testCompileOutputPath);
+ extension.setCompilerOutputPathForTests(VfsUtilCore.pathToUrl(testCompileOutputPath));
}
extension.inheritCompilerOutputPath(data.isInheritProjectCompileOutputPath());
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTreeModel.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTreeModel.java
index 3d927e9..3b6dc04 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTreeModel.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTreeModel.java
@@ -30,6 +30,7 @@
import javax.swing.*;
import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import java.util.*;
@@ -63,11 +64,8 @@
}
};
- @NotNull private final TreeNode[] myNodeHolder = new TreeNode[1];
- @NotNull private final int[] myIndexHolder = new int[1];
-
@NotNull private final ExternalSystemUiAware myUiAware;
- @NotNull private final ProjectSystemId myExternalSystemId;
+ @NotNull private final ProjectSystemId myExternalSystemId;
public ExternalSystemTasksTreeModel(@NotNull ProjectSystemId externalSystemId) {
super(new ExternalSystemNode<String>(new ExternalSystemNodeDescriptor<String>("", "", "", null)));
@@ -82,7 +80,7 @@
/**
* Ensures that current model has a top-level node which corresponds to the given external project info holder
*
- * @param project target external project info holder
+ * @param project target external project info holder
*/
@SuppressWarnings("unchecked")
@NotNull
@@ -108,17 +106,15 @@
}
ExternalProjectPojo element = new ExternalProjectPojo(project.getName(), project.getPath());
ExternalSystemNodeDescriptor<ExternalProjectPojo> descriptor = descriptor(element, myUiAware.getProjectIcon());
- myIndexHolder[0] = root.getChildCount();
ExternalSystemNode<ExternalProjectPojo> result = new ExternalSystemNode<ExternalProjectPojo>(descriptor);
- root.add(result);
- nodesWereInserted(root, myIndexHolder);
+ insertNodeInto(result, root);
return result;
}
/**
* Asks current model to remove all nodes which have given data as a {@link ExternalSystemNodeDescriptor#getElement() payload}.
*
- * @param payload target payload
+ * @param payload target payload
*/
public void pruneNodes(@NotNull Object payload) {
Deque<ExternalSystemNode<?>> toProcess = new ArrayDeque<ExternalSystemNode<?>>();
@@ -137,8 +133,7 @@
}
public void ensureSubProjectsStructure(@NotNull ExternalProjectPojo topLevelProject,
- @NotNull Collection<ExternalProjectPojo> subProjects)
- {
+ @NotNull Collection<ExternalProjectPojo> subProjects) {
ExternalSystemNode<ExternalProjectPojo> topLevelProjectNode = ensureProjectNodeExists(topLevelProject);
Map<String/*config path*/, ExternalProjectPojo> toAdd = ContainerUtilRt.newHashMap();
for (ExternalProjectPojo subProject : subProjects) {
@@ -154,12 +149,8 @@
taskWeights.put(childElement, subProjects.size() + i);
continue;
}
-
if (toAdd.remove(((ExternalProjectPojo)childElement).getPath()) == null) {
- topLevelProjectNode.remove(child);
- myIndexHolder[0] = i;
- myNodeHolder[0] = child;
- nodesWereRemoved(topLevelProjectNode, myIndexHolder, myNodeHolder);
+ removeNodeFromParent(child);
//noinspection AssignmentToForLoopParameter
i--;
}
@@ -168,13 +159,10 @@
for (Map.Entry<String, ExternalProjectPojo> entry : toAdd.entrySet()) {
ExternalProjectPojo
element = new ExternalProjectPojo(entry.getValue().getName(), entry.getValue().getPath());
- topLevelProjectNode.add(new ExternalSystemNode<ExternalProjectPojo>(descriptor(element, myUiAware.getProjectIcon())));
- myIndexHolder[0] = topLevelProjectNode.getChildCount() - 1;
- nodesWereInserted(topLevelProjectNode, myIndexHolder);
+ insertNodeInto(new ExternalSystemNode<ExternalProjectPojo>(descriptor(element, myUiAware.getProjectIcon())),
+ topLevelProjectNode);
}
}
-
- ExternalSystemUiUtil.sort(topLevelProjectNode, this, NODE_COMPARATOR);
}
public void ensureTasks(@NotNull String externalProjectConfigPath, @NotNull Collection<ExternalTaskPojo> tasks) {
@@ -198,10 +186,7 @@
Object element = childNode.getDescriptor().getElement();
if (element instanceof ExternalTaskExecutionInfo) {
if (!toAdd.remove(element)) {
- moduleNode.remove(childNode);
- myIndexHolder[0] = i;
- myNodeHolder[0] = childNode;
- nodesWereRemoved(moduleNode, myIndexHolder, myNodeHolder);
+ removeNodeFromParent(childNode);
//noinspection AssignmentToForLoopParameter
i--;
}
@@ -210,12 +195,11 @@
if (!toAdd.isEmpty()) {
for (ExternalTaskExecutionInfo taskInfo : toAdd) {
- moduleNode.add(new ExternalSystemNode<ExternalTaskExecutionInfo>(descriptor(taskInfo, taskInfo.getDescription(), myUiAware.getTaskIcon())));
- myIndexHolder[0] = moduleNode.getChildCount() - 1;
- nodesWereInserted(moduleNode, myIndexHolder);
+ insertNodeInto(
+ new ExternalSystemNode<ExternalTaskExecutionInfo>(descriptor(taskInfo, taskInfo.getDescription(), myUiAware.getTaskIcon())),
+ moduleNode);
}
}
- ExternalSystemUiUtil.sort(moduleNode, this, NODE_COMPARATOR);
}
@NotNull
@@ -241,8 +225,7 @@
ExternalSystemNode<?> grandChild = child.getChildAt(j);
Object grandChildElement = grandChild.getDescriptor().getElement();
if (grandChildElement instanceof ExternalProjectPojo
- && ((ExternalProjectPojo)grandChildElement).getPath().equals(configPath))
- {
+ && ((ExternalProjectPojo)grandChildElement).getPath().equals(configPath)) {
return (ExternalSystemNode<ExternalProjectPojo>)grandChild;
}
}
@@ -259,9 +242,40 @@
private static <T> ExternalSystemNodeDescriptor<T> descriptor(@NotNull T element, @NotNull String description, @Nullable Icon icon) {
return new ExternalSystemNodeDescriptor<T>(element, element.toString(), description, icon);
}
-
+
@NotNull
public ExternalSystemNode<?> getRoot() {
return (ExternalSystemNode<?>)super.getRoot();
}
+
+ public void insertNodeInto(MutableTreeNode child, MutableTreeNode parent) {
+ int index = findIndexFor(child, parent);
+ super.insertNodeInto(child, parent, index);
+ }
+
+ public void insertNodeInto(MutableTreeNode child, MutableTreeNode parent, int i) {
+ insertNodeInto(child, parent);
+ }
+
+ private static int findIndexFor(MutableTreeNode child, MutableTreeNode parent) {
+ int childCount = parent.getChildCount();
+ if (childCount == 0) {
+ return 0;
+ }
+ if (childCount == 1) {
+ return NODE_COMPARATOR.compare(child, parent.getChildAt(0)) <= 0 ? 0 : 1;
+ }
+ return findIndexFor(child, parent, 0, childCount - 1);
+ }
+
+ private static int findIndexFor(MutableTreeNode child, MutableTreeNode parent, int i1, int i2) {
+ if (i1 == i2) {
+ return NODE_COMPARATOR.compare(child, parent.getChildAt(i1)) <= 0 ? i1 : i1 + 1;
+ }
+ int half = (i1 + i2) / 2;
+ if (NODE_COMPARATOR.compare(child, parent.getChildAt(half)) <= 0) {
+ return findIndexFor(child, parent, i1, half);
+ }
+ return findIndexFor(child, parent, half + 1, i2);
+ }
}
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUiUtil.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUiUtil.java
index 06ae2a1..d987be2 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUiUtil.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUiUtil.java
@@ -105,32 +105,6 @@
component.add(Box.createVerticalGlue(), new GridBag().weightx(1).weighty(1).fillCell().coverLine());
}
- public static void sort(@NotNull DefaultMutableTreeNode parent,
- @NotNull DefaultTreeModel model,
- @NotNull Comparator<TreeNode> comparator)
- {
- List<MutableTreeNode> children = ContainerUtilRt.newArrayList();
- THashMap<TreeNode, Integer> initialOrder = ContainerUtil.newIdentityTroveMap();
- for (int i = 0; i < parent.getChildCount(); i++) {
- MutableTreeNode child = (MutableTreeNode)parent.getChildAt(i);
- children.add(child);
- initialOrder.put(child, i);
- }
- Collections.sort(children, comparator);
- parent.removeAllChildren();
-
- for (MutableTreeNode child : children) {
- parent.add(child);
- }
- for (int i = 0; i < children.size(); i++) {
- MutableTreeNode child = children.get(i);
- Integer initialIndex = initialOrder.get(child);
- if (initialIndex != i) {
- model.nodeChanged(child);
- }
- }
- }
-
/**
* Applies data from the given settings object to the given model.
*
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java
index 3750bff..9e75f7f 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java
@@ -47,8 +47,8 @@
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.PerformInBackgroundOption;
import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
@@ -461,21 +461,21 @@
public void run() {
if (modal) {
String title = ExternalSystemBundle.message("progress.import.text", projectName, externalSystemId.getReadableName());
- ProgressManager.getInstance().run(new Task.Modal(project, title, true) {
+ new Task.Backgroundable(project, title, true, PerformInBackgroundOption.DEAF) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
refreshProjectStructureTask.execute(indicator);
}
- });
+ }.queue();
}
else {
String title = ExternalSystemBundle.message("progress.refresh.text", projectName, externalSystemId.getReadableName());
- ProgressManager.getInstance().run(new Task.Backgroundable(project, title) {
+ new Task.Backgroundable(project, title) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
refreshProjectStructureTask.execute(indicator);
}
- });
+ }.queue();
}
}
});
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/AbstractCustomLexer.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/AbstractCustomLexer.java
index 92e75ad..263baa2 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/AbstractCustomLexer.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/AbstractCustomLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
import com.intellij.psi.CustomHighlighterTokenType;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -40,7 +41,8 @@
myTokenParsers = tokenParsers.toArray(new TokenParser[tokenParsers.size()]);
}
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ @Override
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
myBuffer = buffer;
myStartOffset = startOffset;
myEndOffset = endOffset;
@@ -52,22 +54,27 @@
advance();
}
+ @Override
public int getState() {
return 0;
}
+ @Override
public IElementType getTokenType() {
return myCurrentToken.getType();
}
+ @Override
public int getTokenStart() {
return myCurrentToken.getStart();
}
+ @Override
public int getTokenEnd() {
return myCurrentToken.getEnd();
}
+ @Override
public void advance() {
if (myPosition >= myEndOffset) {
myCurrentToken.updateData(myPosition, myPosition, null);
@@ -95,10 +102,13 @@
myCurrentToken.updateData(myPosition, myPosition + 1, CustomHighlighterTokenType.CHARACTER);
}
+ @Override
+ @NotNull
public CharSequence getBufferSequence() {
return myBuffer;
}
+ @Override
public int getBufferEnd() {
return myEndOffset;
}
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/SyntaxTable.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/SyntaxTable.java
index 7697451..d6e23b6 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/SyntaxTable.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/SyntaxTable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -70,6 +70,7 @@
return parser;
}
+ @Override
protected Object clone() throws CloneNotSupportedException {
SyntaxTable cl = (SyntaxTable) super.clone();
cl.myKeywords1 = new TreeSet<String>(myKeywords1);
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java
index af3b3d4..e258e22 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,6 +54,7 @@
new BraceTokenParser(">", CustomHighlighterTokenType.R_ANGLE));
}
+ @Override
protected int getTokenEnd(int position) {
return position;
}
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/HexNumberParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/HexNumberParser.java
index 383fe63..5d41176 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/HexNumberParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/HexNumberParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
super(prefix, CustomHighlighterTokenType.NUMBER);
}
+ @Override
protected int getTokenEnd(int position) {
for (; position < myEndOffset; position++) {
if (!StringUtil.isHexDigit(myBuffer.charAt(position))) break;
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/IdentifierParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/IdentifierParser.java
index 6f44365..57b29ae8 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/IdentifierParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/IdentifierParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
public IdentifierParser() {
}
+ @Override
public boolean hasToken(int position) {
if (!Character.isJavaIdentifierStart(myBuffer.charAt(position))) return false;
final int start = position;
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/LineCommentParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/LineCommentParser.java
index 0f358da..c5fc32d 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/LineCommentParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/LineCommentParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,6 +39,7 @@
return super.hasToken(position);
}
+ @Override
protected int getTokenEnd(int position) {
for (; position < myEndOffset; position++) {
if (myBuffer.charAt(position) == '\n') break;
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/MultilineCommentParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/MultilineCommentParser.java
index 018ea20..e878738 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/MultilineCommentParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/MultilineCommentParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@
myEndDelimiter = endDelimiter.toCharArray();
}
+ @Override
protected int getTokenEnd(int position) {
for (; position < myEndOffset; position++) {
// todo: implement KMP
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/NumberParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/NumberParser.java
index 2fa17c0..928da95 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/NumberParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/NumberParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@
}
}
+ @Override
public boolean hasToken(int position) {
final int start = position;
final char startChar = myBuffer.charAt(start);
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/PrefixedTokenParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/PrefixedTokenParser.java
index c80015b..7b03d4b 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/PrefixedTokenParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/PrefixedTokenParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@
myPrefix = prefix.toCharArray();
}
+ @Override
public boolean hasToken(int position) {
final int start = position;
int i;
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/QuotedStringParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/QuotedStringParser.java
index 7bfa566..9e08795 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/QuotedStringParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/QuotedStringParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@
myAllowEscapes = allowEscapes;
}
+ @Override
protected int getTokenEnd(int position) {
boolean escaped = false;
for(; position < myEndOffset; position++) {
diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/WhitespaceParser.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/WhitespaceParser.java
index 2da63cf..e84534d 100644
--- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/WhitespaceParser.java
+++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/tokens/WhitespaceParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
*/
public class WhitespaceParser extends TokenParser {
+ @Override
public boolean hasToken(int position) {
if (!Character.isWhitespace(myBuffer.charAt(position))) return false;
int start = position;
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/cache/TodoCacheManager.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/TodoCacheManager.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/cache/TodoCacheManager.java
rename to platform/indexing-impl/src/com/intellij/psi/impl/cache/TodoCacheManager.java
diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/BaseFilterLexer.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/BaseFilterLexer.java
index d297a9a..cc9dddf 100644
--- a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/BaseFilterLexer.java
+++ b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/BaseFilterLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,8 @@
import com.intellij.psi.search.IndexPattern;
import com.intellij.psi.search.UsageSearchContext;
import com.intellij.util.text.CharArrayUtil;
+import gnu.trove.TIntArrayList;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.regex.Matcher;
@@ -32,7 +34,7 @@
private int myTodoScannedBound = 0;
private int myOccurenceMask;
- private TodoScanningData[] myTodoScanningData;
+ private TodoScanningState myTodoScanningState;
private CharSequence myCachedBufferSequence;
private char[] myCachedArraySequence;
@@ -49,49 +51,56 @@
if (start >= end) return; // this prevents scanning of the same comment twice
CharSequence input = myCachedBufferSequence.subSequence(start, end);
- myTodoScanningData = advanceTodoItemsCount(input, myOccurrenceConsumer, myTodoScanningData);
+ myTodoScanningState = advanceTodoItemsCount(input, myOccurrenceConsumer, myTodoScanningState);
myTodoScannedBound = end;
}
- public static class TodoScanningData {
- final IndexPattern pattern;
- final Matcher matcher;
+ public static class TodoScanningState {
+ final IndexPattern[] myPatterns;
+ final Matcher[] myMatchers;
+ TIntArrayList myOccurences;
- public TodoScanningData(IndexPattern pattern, Matcher matcher) {
- this.matcher = matcher;
- this.pattern = pattern;
+ public TodoScanningState(IndexPattern[] patterns, Matcher[] matchers) {
+ myPatterns = patterns;
+ myMatchers = matchers;
+ myOccurences = new TIntArrayList(1);
}
}
- public static TodoScanningData[] advanceTodoItemsCount(final CharSequence input, final OccurrenceConsumer consumer, TodoScanningData[] todoScanningData) {
- if (todoScanningData == null) {
+ public static TodoScanningState advanceTodoItemsCount(final CharSequence input, final OccurrenceConsumer consumer, TodoScanningState todoScanningState) {
+ if (todoScanningState == null) {
IndexPattern[] patterns = IndexPatternUtil.getIndexPatterns();
- todoScanningData = new TodoScanningData[patterns.length];
+
+ Matcher[] matchers = new Matcher[patterns.length];
+ todoScanningState = new TodoScanningState(patterns, matchers);
for (int i = 0; i < patterns.length; ++i) {
- IndexPattern indexPattern = patterns[i];
- Pattern pattern = indexPattern.getPattern();
+ Pattern pattern = patterns[i].getPattern();
if (pattern != null) {
- todoScanningData [i] = new TodoScanningData(indexPattern, pattern.matcher(""));
+ matchers[i] = pattern.matcher("");
}
}
+ } else {
+ todoScanningState.myOccurences.resetQuick();
}
- for (TodoScanningData data:todoScanningData) {
- if (data == null) continue;
- Matcher matcher = data.matcher;
+ for (int i = todoScanningState.myMatchers.length - 1; i >= 0; --i) {
+ Matcher matcher = todoScanningState.myMatchers[i];
+ if (matcher == null) continue;
matcher.reset(input);
while (matcher.find()) {
- if (matcher.start() != matcher.end()) {
- consumer.incTodoOccurrence(data.pattern);
+ int start = matcher.start();
+ if (start != matcher.end() && todoScanningState.myOccurences.indexOf(start) == -1) {
+ consumer.incTodoOccurrence(todoScanningState.myPatterns[i]);
+ todoScanningState.myOccurences.add(start);
}
}
}
- return todoScanningData;
+ return todoScanningState;
}
@Override
@@ -140,7 +149,7 @@
}
@Override
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
super.start(buffer, startOffset, endOffset, initialState);
myCachedBufferSequence = getBufferSequence();
myCachedArraySequence = CharArrayUtil.fromSequenceWithoutCopying(myCachedBufferSequence);
diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java
index 7886102..59f0a6e 100644
--- a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java
+++ b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java
@@ -22,6 +22,7 @@
import com.intellij.lang.findUsages.FindUsagesProvider;
import com.intellij.lang.findUsages.LanguageFindUsages;
import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.InternalFileType;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
import com.intellij.psi.CustomHighlighterTokenType;
@@ -65,15 +66,15 @@
}
}
- private static final HashMap<FileType, FileTypeIdIndexer> ourIdIndexers = new HashMap<FileType, FileTypeIdIndexer>();
+ private static final Map<FileType, FileTypeIdIndexer> ourIdIndexers = new HashMap<FileType, FileTypeIdIndexer>();
@Deprecated
- public static void registerIdIndexer(FileType fileType, FileTypeIdIndexer indexer) {
+ public static void registerIdIndexer(@NotNull FileType fileType, FileTypeIdIndexer indexer) {
ourIdIndexers.put(fileType, indexer);
}
- public static boolean isIdIndexerRegistered(FileType fileType) {
- return ourIdIndexers.containsKey(fileType) || IdIndexers.INSTANCE.forFileType(fileType) != null;
+ public static boolean isIdIndexerRegistered(@NotNull FileType fileType) {
+ return ourIdIndexers.containsKey(fileType) || IdIndexers.INSTANCE.forFileType(fileType) != null || fileType instanceof InternalFileType;
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndexers.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndexers.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndexers.java
rename to platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndexers.java
diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/search/IndexPatternBuilder.java b/platform/indexing-impl/src/com/intellij/psi/impl/search/IndexPatternBuilder.java
new file mode 100644
index 0000000..167ae038
--- /dev/null
+++ b/platform/indexing-impl/src/com/intellij/psi/impl/search/IndexPatternBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.psi.impl.search;
+
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author yole
+ */
+public interface IndexPatternBuilder {
+ ExtensionPointName<IndexPatternBuilder> EP_NAME = ExtensionPointName.create("com.intellij.indexPatternBuilder");
+
+ @Nullable
+ Lexer getIndexingLexer(@NotNull PsiFile file);
+ @Nullable
+ TokenSet getCommentTokenSet(@NotNull PsiFile file);
+ int getCommentStartDelta(IElementType tokenType);
+ int getCommentEndDelta(IElementType tokenType);
+}
diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/search/TodoItemImpl.java b/platform/indexing-impl/src/com/intellij/psi/impl/search/TodoItemImpl.java
new file mode 100644
index 0000000..07a6bf2
--- /dev/null
+++ b/platform/indexing-impl/src/com/intellij/psi/impl/search/TodoItemImpl.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.psi.impl.search;
+
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.search.TodoItem;
+import com.intellij.psi.search.TodoPattern;
+import org.jetbrains.annotations.NotNull;
+
+public class TodoItemImpl implements TodoItem {
+ private final PsiFile myFile;
+ private final int myStartOffset;
+ private final int myEndOffset;
+ private final TodoPattern myPattern;
+
+ public TodoItemImpl(@NotNull PsiFile file, int startOffset, int endOffset, @NotNull TodoPattern pattern) {
+ myFile = file;
+ myStartOffset = startOffset;
+ myEndOffset = endOffset;
+ myPattern = pattern;
+ }
+
+ @NotNull
+ @Override
+ public PsiFile getFile() {
+ return myFile;
+ }
+
+ @NotNull
+ @Override
+ public TextRange getTextRange() {
+ return new TextRange(myStartOffset, myEndOffset);
+ }
+
+ @NotNull
+ @Override
+ public TodoPattern getPattern() {
+ return myPattern;
+ }
+
+ public int hashCode(){
+ return myFile.hashCode()+myStartOffset+myEndOffset+myPattern.hashCode();
+ }
+
+ public boolean equals(Object obj){
+ if(!(obj instanceof TodoItemImpl)){
+ return false;
+ }
+ TodoItemImpl todoItem=(TodoItemImpl)obj;
+ return myFile.equals(todoItem.myFile) &&
+ myStartOffset == todoItem.myStartOffset &&
+ myEndOffset == todoItem.myEndOffset &&
+ myPattern.equals(todoItem.myPattern);
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java
index ab7b43c..df14ef0 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java
@@ -29,7 +29,9 @@
* @deprecated not used anymore, only the user controls whether the lookup will be focused
*/
@NotNull
- public abstract ThreeState shouldFocusLookup(@NotNull CompletionParameters parameters);
+ public ThreeState shouldFocusLookup(@NotNull CompletionParameters parameters) {
+ return ThreeState.UNSURE;
+ }
/**
* This method is invoked first when a completion autopopup is scheduled. Extensions are able to cancel this completion process based on location.
diff --git a/platform/lang-api/src/com/intellij/facet/FacetTypeRegistry.java b/platform/lang-api/src/com/intellij/facet/FacetTypeRegistry.java
index 7884b7b..8e2ce49 100644
--- a/platform/lang-api/src/com/intellij/facet/FacetTypeRegistry.java
+++ b/platform/lang-api/src/com/intellij/facet/FacetTypeRegistry.java
@@ -17,6 +17,7 @@
package com.intellij.facet;
import com.intellij.openapi.components.ServiceManager;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -38,14 +39,18 @@
*/
public abstract void unregisterFacetType(FacetType facetType);
+ @NotNull
public abstract FacetTypeId[] getFacetTypeIds();
+ @NotNull
public abstract FacetType[] getFacetTypes();
+ @NotNull
public abstract FacetType[] getSortedFacetTypes();
@Nullable
public abstract FacetType findFacetType(String id);
- public abstract <F extends Facet<C>, C extends FacetConfiguration> FacetType<F, C> findFacetType(FacetTypeId<F> typeId);
+ @NotNull
+ public abstract <F extends Facet<C>, C extends FacetConfiguration> FacetType<F, C> findFacetType(@NotNull FacetTypeId<F> typeId);
}
diff --git a/platform/lang-api/src/com/intellij/facet/ui/FacetBasedFrameworkSupportProvider.java b/platform/lang-api/src/com/intellij/facet/ui/FacetBasedFrameworkSupportProvider.java
index 89d33e1..742f8d9 100644
--- a/platform/lang-api/src/com/intellij/facet/ui/FacetBasedFrameworkSupportProvider.java
+++ b/platform/lang-api/src/com/intellij/facet/ui/FacetBasedFrameworkSupportProvider.java
@@ -66,9 +66,7 @@
* @see #getPrecedingFrameworkProviderIds()
*/
public static String getProviderId(final FacetTypeId<?> typeId) {
- FacetType<?,?> type = FacetTypeRegistry.getInstance().findFacetType(typeId);
- LOG.assertTrue(type != null, typeId);
- return getProviderId(type);
+ return getProviderId(FacetTypeRegistry.getInstance().findFacetType(typeId));
}
@Override
@@ -77,8 +75,7 @@
FacetTypeId<?> typeId = myFacetType.getUnderlyingFacetType();
if (typeId == null) return null;
- FacetType<?,?> type = FacetTypeRegistry.getInstance().findFacetType(typeId);
- return type != null ? getProviderId(type) : null;
+ return getProviderId(FacetTypeRegistry.getInstance().findFacetType(typeId));
}
diff --git a/platform/lang-api/src/com/intellij/ide/util/projectWizard/AbstractModuleBuilder.java b/platform/lang-api/src/com/intellij/ide/util/projectWizard/AbstractModuleBuilder.java
index 665b593..26fd925 100644
--- a/platform/lang-api/src/com/intellij/ide/util/projectWizard/AbstractModuleBuilder.java
+++ b/platform/lang-api/src/com/intellij/ide/util/projectWizard/AbstractModuleBuilder.java
@@ -33,6 +33,11 @@
public abstract ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider);
+ /** @deprecated Will be removed soon */
+ public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider, boolean forNewWizard) {
+ return forNewWizard ? ModuleWizardStep.EMPTY_ARRAY : createWizardSteps(wizardContext, modulesProvider);
+ }
+
@Nullable
public ModuleWizardStep modifySettingsStep(@NotNull SettingsStep settingsStep) {
return null;
diff --git a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
index f14cd7a..45f25cd 100644
--- a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
+++ b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
@@ -17,6 +17,7 @@
import com.intellij.ide.IdeBundle;
import com.intellij.ide.highlighter.ModuleFileType;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPointName;
@@ -57,7 +58,6 @@
private String myContentEntryPath;
private final Set<ModuleConfigurationUpdater> myUpdaters = new HashSet<ModuleConfigurationUpdater>();
private final EventDispatcher<ModuleBuilderListener> myDispatcher = EventDispatcher.create(ModuleBuilderListener.class);
- private Map<String, Boolean> myAvailableFrameworks;
@NotNull
public static List<ModuleBuilder> getAllBuilders() {
@@ -140,6 +140,11 @@
}
}
+ @Nullable
+ public JComponent getCustomOptionsPanel(Disposable parentDisposable) {
+ return null;
+ }
+
protected List<WizardInputField> getAdditionalFields() {
return Collections.emptyList();
}
@@ -362,10 +367,14 @@
return myJdk;
}
+ private Map<String, Boolean> myAvailableFrameworks;
+
+ /** @deprecated will be removed */
public Map<String, Boolean> getAvailableFrameworks() {
return myAvailableFrameworks;
}
+ /** @deprecated will be removed */
public void setAvailableFrameworks(Map<String, Boolean> availableFrameworks) {
myAvailableFrameworks = availableFrameworks;
}
diff --git a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleWizardStep.java b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleWizardStep.java
index 314607cb..b6893cf 100644
--- a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleWizardStep.java
+++ b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleWizardStep.java
@@ -17,6 +17,7 @@
import com.intellij.ide.util.BrowseFilesListener;
import com.intellij.ide.wizard.StepAdapter;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.FieldPanel;
@@ -26,15 +27,22 @@
import javax.swing.*;
import java.awt.*;
-public abstract class ModuleWizardStep extends StepAdapter {
+public abstract class ModuleWizardStep extends StepAdapter implements Disposable {
protected static final Icon ICON = IconLoader.getIcon("/addmodulewizard.png");
public static final ModuleWizardStep[] EMPTY_ARRAY = new ModuleWizardStep[0];
@Override
public abstract JComponent getComponent();
+
+ /** Commits data from UI into ModuleBuilder and WizardContext */
public abstract void updateDataModel();
+ /** Update UI from ModuleBuilder and WizardContext */
+ public void updateStep() {
+ // empty by default
+ }
+
@NonNls public String getHelpId() {
return null;
}
@@ -47,10 +55,6 @@
// empty by default
}
- public void updateStep() {
- // empty by default
- }
-
@Override
public Icon getIcon() {
return ICON;
@@ -67,6 +71,11 @@
public void disposeUIResources() {
}
+ @Override
+ public void dispose() {
+ disposeUIResources();
+ }
+
public static FieldPanel createFieldPanel(final JTextField field, final String labelText, final BrowseFilesListener browseButtonActionListener) {
final FieldPanel fieldPanel = new FieldPanel(field, labelText, null, browseButtonActionListener, null);
fieldPanel.getFieldLabel().setFont(UIUtil.getLabelFont().deriveFont(Font.BOLD));
diff --git a/platform/lang-api/src/com/intellij/lang/annotation/ExternalAnnotator.java b/platform/lang-api/src/com/intellij/lang/annotation/ExternalAnnotator.java
index 46d641e..9f8644c 100644
--- a/platform/lang-api/src/com/intellij/lang/annotation/ExternalAnnotator.java
+++ b/platform/lang-api/src/com/intellij/lang/annotation/ExternalAnnotator.java
@@ -30,24 +30,6 @@
*/
public abstract class ExternalAnnotator<InitialInfoType, AnnotationResultType> {
/**
- * @deprecated use {@link ExternalAnnotator#collectInformation(PsiFile)} instead
- */
- @Nullable
- @Deprecated
- public InitialInfoType collectionInformation(@NotNull PsiFile file) {
- return null;
- }
-
- /**
- * @deprecated use {@link ExternalAnnotator#collectInformation(PsiFile, Editor, boolean)} instead
- */
- @Nullable
- @Deprecated()
- public InitialInfoType collectInformation(@NotNull PsiFile file, @NotNull Editor editor) {
- return collectInformation(file);
- }
-
- /**
* Collects initial information required for annotation. Expected to run within read action.
* See {@link ExternalAnnotator#collectInformation(PsiFile, Editor, boolean)} for details.
*
@@ -56,7 +38,7 @@
*/
@Nullable
public InitialInfoType collectInformation(@NotNull PsiFile file) {
- return collectionInformation(file);
+ return null;
}
/**
@@ -70,7 +52,7 @@
*/
@Nullable
public InitialInfoType collectInformation(@NotNull PsiFile file, @NotNull Editor editor, boolean hasErrors) {
- return hasErrors ? null : collectInformation(file, editor);
+ return hasErrors ? null : collectInformation(file);
}
/**
@@ -92,15 +74,4 @@
*/
public void apply(@NotNull PsiFile file, AnnotationResultType annotationResult, @NotNull AnnotationHolder holder) {
}
-
- /**
- * Annotates the specified file.
- *
- * @param file the file to annotate.
- * @param holder the container which receives annotations created by the plugin.
- */
- // todo: adapt existing annotators to a new API
- @Deprecated
- public void annotate(PsiFile file, AnnotationHolder holder) {
- }
}
diff --git a/platform/lang-api/src/com/intellij/lexer/CompositeLexer.java b/platform/lang-api/src/com/intellij/lexer/CompositeLexer.java
index 74937ac..d728aff 100644
--- a/platform/lang-api/src/com/intellij/lexer/CompositeLexer.java
+++ b/platform/lang-api/src/com/intellij/lexer/CompositeLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package com.intellij.lexer;
import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
public abstract class CompositeLexer extends LexerBase {
private final Lexer myLexer1;
@@ -30,12 +31,13 @@
protected abstract IElementType getCompositeTokenType(IElementType type1, IElementType type2);
@Override
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
myLexer1.start(buffer, startOffset, endOffset, (initialState >> 16) & 0xFFFF);
myLexer2.start(buffer, startOffset, endOffset, initialState & 0xFFFF);
myCurOffset = startOffset;
}
+ @NotNull
@Override
public CharSequence getBufferSequence() {
return myLexer1.getBufferSequence();
diff --git a/platform/lang-api/src/com/intellij/lexer/FilterLexer.java b/platform/lang-api/src/com/intellij/lexer/FilterLexer.java
index 328a8cf..6f03469 100644
--- a/platform/lang-api/src/com/intellij/lexer/FilterLexer.java
+++ b/platform/lang-api/src/com/intellij/lexer/FilterLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
public class FilterLexer extends DelegateLexer {
private final Filter myFilter;
@@ -55,7 +56,7 @@
}
@Override
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
super.start(buffer, startOffset, endOffset, initialState);
myPrevTokenEnd = -1;
locateToken();
@@ -73,13 +74,14 @@
return myPrevTokenEnd;
}
+ @NotNull
@Override
public LexerPosition getCurrentPosition() {
return getDelegate().getCurrentPosition(); //To change body of overridden methods use File | Settings | File Templates.
}
@Override
- public void restore(LexerPosition position) {
+ public void restore(@NotNull LexerPosition position) {
getDelegate().restore(position);
myPrevTokenEnd = -1;
}
diff --git a/platform/lang-api/src/com/intellij/lexer/StoppableLexerAdapter.java b/platform/lang-api/src/com/intellij/lexer/StoppableLexerAdapter.java
index f8fec84..3763297 100644
--- a/platform/lang-api/src/com/intellij/lexer/StoppableLexerAdapter.java
+++ b/platform/lang-api/src/com/intellij/lexer/StoppableLexerAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
package com.intellij.lexer;
import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
public class StoppableLexerAdapter extends DelegateLexer {
@@ -61,13 +62,14 @@
return myStopped ? null : super.getTokenType();
}
+ @NotNull
@Override
public LexerPosition getCurrentPosition() {
return getDelegate().getCurrentPosition();
}
@Override
- public void restore(LexerPosition position) {
+ public void restore(@NotNull LexerPosition position) {
getDelegate().restore(position);
}
diff --git a/platform/lang-api/src/com/intellij/lexer/StringLiteralLexer.java b/platform/lang-api/src/com/intellij/lexer/StringLiteralLexer.java
index 978c01b..a163e5b 100644
--- a/platform/lang-api/src/com/intellij/lexer/StringLiteralLexer.java
+++ b/platform/lang-api/src/com/intellij/lexer/StringLiteralLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.StringEscapesTokenTypes;
import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
/**
* @author max
@@ -74,7 +75,7 @@
}
@Override
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
myBuffer = buffer;
myStart = startOffset;
if (myQuoteChar == NO_QUOTE_CHAR) {
@@ -249,6 +250,7 @@
myEnd = locateToken(myStart);
}
+ @NotNull
@Override
public CharSequence getBufferSequence() {
return myBuffer;
diff --git a/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java b/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java
index 14c0e46..8152efd 100644
--- a/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java
+++ b/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java
@@ -20,6 +20,7 @@
*/
package com.intellij.openapi.roots.ui;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.ui.SdkPathEditor;
import com.intellij.openapi.roots.OrderRootType;
@@ -29,7 +30,9 @@
import javax.swing.*;
public interface OrderRootTypeUIFactory {
- KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType> FACTORY = new KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType>(OrderRootTypeUIFactory.class, "com.intellij.OrderRootTypeUI") {
+ KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType> FACTORY = new KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType>(OrderRootTypeUIFactory.class, "com.intellij.OrderRootTypeUI",
+ ApplicationManager
+ .getApplication().getPicoContainer()) {
@Override
public String getKey(@NotNull final OrderRootType key) {
return key.name();
diff --git a/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java b/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java
index 69193ae..c3685b03 100644
--- a/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java
+++ b/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java
@@ -37,10 +37,6 @@
public void updateDetailView(DetailView panel) {
if (panel == null) return;
- if (equals(panel.getCurrentItem())) {
- return;
- }
-
doUpdateDetailView(panel, panel.hasEditorOnly());
panel.setCurrentItem(this);
diff --git a/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.form b/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.form
new file mode 100644
index 0000000..d0b545c
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.form
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.application.options.ImportSchemeChooserDialog">
+ <grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="10" left="10" bottom="10" right="10"/>
+ <constraints>
+ <xy x="48" y="54" width="436" height="321"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <grid id="50b89" 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="1" 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/>
+ <border type="none"/>
+ <children>
+ <component id="9d822" class="com.intellij.ui.components.JBLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Import to:"/>
+ </properties>
+ </component>
+ <component id="172e4" class="javax.swing.JTextField" binding="myTargetNameField">
+ <constraints>
+ <grid row="0" column="2" 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>
+ <component id="1a0d0" class="javax.swing.JCheckBox" binding="myUseCurrentScheme">
+ <constraints>
+ <grid row="1" 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="Current scheme"/>
+ </properties>
+ </component>
+ </children>
+ </grid>
+ <scrollpane id="41119" class="com.intellij.ui.components.JBScrollPane">
+ <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"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="f1a29" class="com.intellij.ui.components.JBList" binding="mySchemeList">
+ <constraints/>
+ <properties/>
+ </component>
+ </children>
+ </scrollpane>
+ <vspacer id="5cb42">
+ <constraints>
+ <grid row="2" 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/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.java b/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.java
new file mode 100644
index 0000000..78ed30a
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.java
@@ -0,0 +1,100 @@
+package com.intellij.application.options;
+
+import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.openapi.options.Scheme;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.ui.components.JBList;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class ImportSchemeChooserDialog extends DialogWrapper {
+ private JPanel contentPane;
+ private JBList mySchemeList;
+ private JTextField myTargetNameField;
+ private JCheckBox myUseCurrentScheme;
+ private String mySelectedName;
+ private final static String UNNAMED_SCHEME_ITEM = "<" + ApplicationBundle.message("code.style.scheme.import.unnamed") + ">";
+ private final List<String> myNames = new ArrayList<String>();
+
+ public ImportSchemeChooserDialog(@NotNull Component parent,
+ String[] schemeNames,
+ final @Nullable String currScheme) {
+ super(parent, false);
+ if (schemeNames.length > 0) {
+ myNames.addAll(Arrays.asList(schemeNames));
+ }
+ else {
+ myNames.add(UNNAMED_SCHEME_ITEM);
+ }
+ mySchemeList.setModel(new DefaultListModel() {
+ @Override
+ public int getSize() {
+ return myNames.size();
+ }
+
+ @Override
+ public Object getElementAt(int index) {
+ return myNames.get(index);
+ }
+ });
+ mySchemeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mySchemeList.addListSelectionListener(new ListSelectionListener() {
+ @Override
+ public void valueChanged(ListSelectionEvent e) {
+ int index = mySchemeList.getSelectedIndex();
+ if (index >= 0) {
+ mySelectedName = myNames.get(index);
+ if (!myUseCurrentScheme.isSelected() && !UNNAMED_SCHEME_ITEM.equals(mySelectedName)) myTargetNameField.setText(mySelectedName);
+ }
+ }
+ });
+ myUseCurrentScheme.setEnabled(currScheme != null);
+ myUseCurrentScheme.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (myUseCurrentScheme.isSelected()) {
+ myTargetNameField.setEnabled(false);
+ if (currScheme != null) {
+ myTargetNameField.setText(currScheme);
+ }
+ }
+ else {
+ myTargetNameField.setEnabled(true);
+ if (mySelectedName != null) myTargetNameField.setText(mySelectedName);
+ }
+ }
+ });
+ mySchemeList.getSelectionModel().setSelectionInterval(0,0);
+ init();
+ }
+
+ public String getSelectedName() {
+ return UNNAMED_SCHEME_ITEM.equals(mySelectedName) ? null : mySelectedName;
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createCenterPanel() {
+ return contentPane;
+ }
+
+ public boolean isUseCurrentScheme() {
+ return myUseCurrentScheme.isSelected();
+ }
+
+ @Nullable
+ public String getTargetName() {
+ String name = myTargetNameField.getText();
+ return name != null && !name.trim().isEmpty() ? name : null;
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.form b/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.form
new file mode 100644
index 0000000..9e42611
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.form
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.application.options.ImportSourceChooserDialog">
+ <grid id="cbd77" binding="myContentPane" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="10" left="10" bottom="10" right="10"/>
+ <constraints>
+ <xy x="48" y="54" width="436" height="297"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <grid id="e3588" 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="0" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
+ <preferred-size width="200" height="200"/>
+ </grid>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <scrollpane id="89ab8" 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"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="5063d" class="com.intellij.ui.components.JBList" binding="mySourceList">
+ <constraints/>
+ <properties/>
+ </component>
+ </children>
+ </scrollpane>
+ </children>
+ </grid>
+ </children>
+ </grid>
+</form>
diff --git a/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.java b/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.java
new file mode 100644
index 0000000..067c868
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.application.options;
+
+import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.openapi.options.Scheme;
+import com.intellij.openapi.options.SchemeImporterEP;
+import com.intellij.openapi.options.SchemesManager;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.ui.components.JBCheckBox;
+import com.intellij.ui.components.JBList;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class ImportSourceChooserDialog <S extends Scheme> extends DialogWrapper {
+ private JPanel myContentPane;
+ private JBList mySourceList;
+
+ private String mySelectedSourceName;
+ private final ListModel myListModel;
+
+ private final static String SHARED_IMPORT_SOURCE = ApplicationBundle.message("import.scheme.shared");
+
+ public ImportSourceChooserDialog(JComponent parent, Class<S> schemeClass, SchemesManager schemesManager) {
+ super(parent, true);
+ setTitle(ApplicationBundle.message("title.import.scheme.from"));
+ myListModel = new SourceListModel(SchemeImporterEP.getExtensions(schemeClass), schemesManager.isImportAvailable());
+ initSourceList();
+ init();
+ }
+
+ private void initSourceList() {
+ mySourceList.setModel(myListModel);
+ mySourceList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mySourceList.addListSelectionListener(new ListSelectionListener() {
+ @Override
+ public void valueChanged(ListSelectionEvent e) {
+ int index = mySourceList.getSelectedIndex();
+ if (index >= 0) {
+ setSelectedSourceName((String)myListModel.getElementAt(index));
+ }
+ }
+ });
+ mySourceList.setSelectedIndex(0);
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createCenterPanel() {
+ return myContentPane;
+ }
+
+ private void setSelectedSourceName(String name) {
+ mySelectedSourceName = name;
+ }
+
+ @Nullable
+ public String getSelectedSourceName() {
+ return mySelectedSourceName;
+ }
+
+ public boolean isImportFromSharedSelected() {
+ return SHARED_IMPORT_SOURCE.equals(mySelectedSourceName);
+ }
+
+ private class SourceListModel extends DefaultListModel {
+ private List<String> mySourceNames = new ArrayList<String>();
+
+ public SourceListModel(Collection<SchemeImporterEP<S>> extensions, boolean isSharedImportAvailable) {
+ for (SchemeImporterEP extension : extensions) {
+ mySourceNames.add(extension.name);
+ }
+ if (isSharedImportAvailable) {
+ mySourceNames.add(SHARED_IMPORT_SOURCE);
+ }
+ }
+
+ @Override
+ public int getSize() {
+ return mySourceNames.size();
+ }
+
+ @Override
+ public Object getElementAt(int index) {
+ return mySourceNames.get(index);
+ }
+ }
+
+}
diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesModel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesModel.java
index 91d0782..4b2764b 100644
--- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesModel.java
+++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesModel.java
@@ -209,6 +209,10 @@
myDispatcher.getMulticaster().currentSettingsChanged();
}
+ public void fireSchemeChanged(CodeStyleScheme scheme) {
+ myDispatcher.getMulticaster().schemeChanged(scheme);
+ }
+
public CodeStyleScheme getSelectedGlobalScheme() {
return myGlobalSelected;
}
diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java
index a4c5d97..151a92f 100644
--- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java
+++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java
@@ -15,18 +15,31 @@
*/
package com.intellij.application.options.codeStyle;
-import com.intellij.application.options.ExportSchemeAction;
-import com.intellij.application.options.SaveSchemeDialog;
-import com.intellij.application.options.SchemesToImportPopup;
+import com.intellij.application.options.*;
import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDialog;
+import com.intellij.openapi.fileChooser.FileChooserFactory;
+import com.intellij.openapi.options.SchemeImportException;
+import com.intellij.openapi.options.SchemeImporter;
+import com.intellij.openapi.options.SchemeImporterEP;
import com.intellij.openapi.options.SchemesManager;
+import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.popup.Balloon;
+import com.intellij.openapi.ui.popup.BalloonBuilder;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.codeStyle.CodeStyleScheme;
import com.intellij.psi.codeStyle.CodeStyleSchemes;
import com.intellij.psi.impl.source.codeStyle.CodeStyleSchemeImpl;
+import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.table.JBTable;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
@@ -35,6 +48,8 @@
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.*;
import java.util.List;
@@ -54,6 +69,7 @@
private final MySchemesTableModel mySchemesTableModel;
private final CodeStyleSchemesModel myModel;
private final Component myParent;
+ private final SchemesManager<CodeStyleScheme, CodeStyleSchemeImpl> mySchemesManager;
protected ManageCodeStyleSchemesDialog(final Component parent, CodeStyleSchemesModel schemesModel) {
@@ -98,15 +114,15 @@
}
});
- final SchemesManager<CodeStyleScheme, CodeStyleSchemeImpl> schemesManager = CodeStyleSchemesModel.getSchemesManager();
+ mySchemesManager = CodeStyleSchemesModel.getSchemesManager();
- if (schemesManager.isExportAvailable()) {
+ if (mySchemesManager.isExportAvailable()) {
myExportButton.setVisible(true);
myExportButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
CodeStyleScheme selected = getSelectedScheme();
- ExportSchemeAction.doExport((CodeStyleSchemeImpl)selected, schemesManager);
+ ExportSchemeAction.doExport((CodeStyleSchemeImpl)selected, mySchemesManager);
}
});
myExportButton.setMnemonic('S');
@@ -115,21 +131,12 @@
myExportButton.setVisible(false);
}
- if (schemesManager.isImportAvailable()) {
+ if (mySchemesManager.isImportAvailable() || SchemeImporterEP.getExtensions(CodeStyleScheme.class).size() > 0) {
myImportButton.setVisible(true);
myImportButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
- SchemesToImportPopup<CodeStyleScheme, CodeStyleSchemeImpl> popup =
- new SchemesToImportPopup<CodeStyleScheme, CodeStyleSchemeImpl>(parent) {
- @Override
- protected void onSchemeSelected(final CodeStyleSchemeImpl scheme) {
- if (scheme != null) {
- myModel.addScheme(scheme, true);
- }
- }
- };
- popup.show(schemesManager, myModel.getSchemes());
+ chooseAndImport();
}
});
}
@@ -140,6 +147,138 @@
init();
}
+
+ private void chooseAndImport() {
+ ImportSourceChooserDialog<CodeStyleScheme> importSourceChooserDialog =
+ new ImportSourceChooserDialog<CodeStyleScheme>(myContentPane, CodeStyleScheme.class, mySchemesManager);
+ importSourceChooserDialog.show();
+ if (importSourceChooserDialog.isOK()) {
+ if (importSourceChooserDialog.isImportFromSharedSelected()) {
+ SchemesToImportPopup<CodeStyleScheme, CodeStyleSchemeImpl> popup =
+ new SchemesToImportPopup<CodeStyleScheme, CodeStyleSchemeImpl>(myContentPane) {
+ @Override
+ protected void onSchemeSelected(final CodeStyleSchemeImpl scheme) {
+ if (scheme != null) {
+ myModel.addScheme(scheme, true);
+ }
+ }
+ };
+ popup.show(mySchemesManager, myModel.getSchemes());
+ }
+ else {
+ String selectedImporterName = importSourceChooserDialog.getSelectedSourceName();
+ if (selectedImporterName != null) {
+ try {
+ String schemeName = importExternalCodeStyle(selectedImporterName);
+ if (schemeName != null) {
+ showStatus(myImportButton,
+ ApplicationBundle.message("message.code.style.scheme.import.success", selectedImporterName, schemeName),
+ MessageType.INFO);
+ }
+ }
+ catch (SchemeImportException e) {
+ showStatus(myImportButton,
+ ApplicationBundle.message("message.code.style.scheme.import.failure", selectedImporterName, e.getMessage()),
+ MessageType.ERROR);
+ }
+ }
+ }
+ }
+ }
+
+ private static void showStatus(final Component component, final String message, MessageType messageType) {
+ BalloonBuilder balloonBuilder = JBPopupFactory.getInstance()
+ .createHtmlTextBalloonBuilder(message, messageType.getDefaultIcon(),
+ messageType.getPopupBackground(), null);
+ balloonBuilder.setFadeoutTime(5000);
+ final Balloon balloon = balloonBuilder.createBalloon();
+ final Rectangle rect = component.getBounds();
+ final Point p = new Point(rect.x, rect.y + rect.height);
+ final RelativePoint point = new RelativePoint(component, p);
+ balloon.show(point, Balloon.Position.below);
+ Disposer.register(ProjectManager.getInstance().getDefaultProject(), balloon);
+ }
+
+ @Nullable
+ private String importExternalCodeStyle(String importerName) throws SchemeImportException {
+ final SchemeImporter<CodeStyleScheme> importer = SchemeImporterEP.getImporter(importerName, CodeStyleScheme.class);
+ if (importer != null) {
+ FileChooserDialog fileChooser = FileChooserFactory.getInstance()
+ .createFileChooser(new FileChooserDescriptor(true, false, false, false, false, false) {
+ @Override
+ public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
+ return file.isDirectory() || importer.getSourceExtension().equals(file.getExtension());
+ }
+ @Override
+ public boolean isFileSelectable(VirtualFile file) {
+ return !file.isDirectory() && importer.getSourceExtension().equals(file.getExtension());
+ }
+ }, null, myContentPane);
+ VirtualFile[] selection = fileChooser.choose(null, null);
+ if (selection.length == 1) {
+ VirtualFile selectedFile = selection[0];
+ try {
+ InputStream nameInputStream = selectedFile.getInputStream();
+ String[] schemeNames;
+ try {
+ schemeNames = importer.readSchemeNames(nameInputStream);
+ }
+ finally {
+ nameInputStream.close();
+ }
+ CodeStyleScheme currScheme = myModel.getSelectedScheme();
+ ImportSchemeChooserDialog schemeChooserDialog =
+ new ImportSchemeChooserDialog(myContentPane, schemeNames, !currScheme.isDefault() ? currScheme.getName() : null);
+ schemeChooserDialog.show();
+ if (schemeChooserDialog.isOK()) {
+ String schemeName = schemeChooserDialog.getSelectedName();
+ String targetName = schemeChooserDialog.getTargetName();
+ CodeStyleScheme targetScheme = null;
+ if (schemeChooserDialog.isUseCurrentScheme()) {
+ targetScheme = myModel.getSelectedScheme();
+ }
+ else {
+ if (targetName == null) targetName = ApplicationBundle.message("code.style.scheme.import.unnamed");
+ for (CodeStyleScheme scheme : myModel.getSchemes()) {
+ if (targetName.equals(scheme.getName())) {
+ targetScheme = scheme;
+ break;
+ }
+ }
+ if (targetScheme == null) {
+ int row = mySchemesTableModel.createNewScheme(getSelectedScheme(), targetName);
+ mySchemesTable.getSelectionModel().setSelectionInterval(row, row);
+ targetScheme = mySchemesTableModel.getSchemeAt(row);
+ }
+ else {
+ int result = Messages.showYesNoDialog(myContentPane,
+ ApplicationBundle.message("message.code.style.scheme.already.exists", targetName),
+ ApplicationBundle.message("title.code.style.settings.import"),
+ Messages.getQuestionIcon());
+ if (result != Messages.OK) {
+ return null;
+ }
+ }
+ }
+ InputStream dataInputStream = selectedFile.getInputStream();
+ try {
+ importer.importScheme(dataInputStream, schemeName, targetScheme);
+ myModel.fireSchemeChanged(targetScheme);
+ }
+ finally {
+ dataInputStream.close();
+ }
+ return targetScheme.getName();
+ }
+ }
+ catch (IOException e) {
+ throw new SchemeImportException(e);
+ }
+ }
+ }
+ return null;
+ }
+
private void updateActions() {
CodeStyleScheme selectedScheme = getSelectedScheme();
myDeleteButton.setEnabled(!(selectedScheme.isDefault() || mySchemesTableModel.isProjectScheme(selectedScheme)));
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/HippieWordCompletionHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/HippieWordCompletionHandler.java
index e4dabb9..1660195 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/HippieWordCompletionHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/HippieWordCompletionHandler.java
@@ -27,11 +27,14 @@
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiFile;
-import com.intellij.psi.impl.cache.impl.id.IdTableBuilding;
+import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -42,6 +45,7 @@
*/
public class HippieWordCompletionHandler implements CodeInsightActionHandler {
private static final Key<CompletionState> KEY_STATE = new Key<CompletionState>("HIPPIE_COMPLETION_STATE");
+ private static final String WHITESPACE_CHARS = " \t\n";
private final boolean myForward;
public HippieWordCompletionHandler(boolean forward) {
@@ -64,7 +68,7 @@
String oldPrefix = completionState.oldPrefix;
CompletionVariant lastProposedVariant = completionState.lastProposedVariant;
- if (lastProposedVariant == null || oldPrefix == null || !prefixMatches(oldPrefix, currentPrefix) ||
+ if (lastProposedVariant == null || oldPrefix == null || !new CamelHumpMatcher(oldPrefix).isStartMatch(currentPrefix) ||
!currentPrefix.equals(lastProposedVariant.variant)) {
//we are starting over
oldPrefix = currentPrefix;
@@ -201,24 +205,15 @@
final int caretOffset = editor.getCaretModel().getOffset();
- HighlighterIterator iterator = ((EditorEx)editor).getHighlighter().createIterator(0);
- while (!iterator.atEnd()) {
- int start = iterator.getStart();
- int end = iterator.getEnd();
- if ((start > caretOffset || end < caretOffset) && //skip prefix itself
- end - start > matcher.getPrefix().length() && isWordLike(chars, start, end)) {
- final String word = chars.subSequence(start, end).toString();
- if (matcher.prefixMatches(word)) {
- CompletionVariant v = new CompletionVariant(word, start);
- if (end > caretOffset) {
- afterWords.add(v);
- }
- else {
- words.add(v);
- }
+ addWordsForEditor((EditorEx)editor, matcher, chars, words, afterWords, caretOffset);
+
+ for(FileEditor fileEditor: FileEditorManager.getInstance(file.getProject()).getAllEditors()) {
+ if (fileEditor instanceof TextEditor) {
+ Editor anotherEditor = ((TextEditor)fileEditor).getEditor();
+ if (anotherEditor != editor) {
+ addWordsForEditor((EditorEx)anotherEditor, matcher, anotherEditor.getDocument().getCharsSequence(), words, afterWords, 0);
}
}
- iterator.advance();
}
Set<String> allWords = new HashSet<String>();
@@ -245,29 +240,82 @@
return result;
}
+
+ private interface TokenProcessor {
+ boolean processToken(int start, int end);
+ }
- private static boolean prefixMatches(String prefix, String word) {
- return new CamelHumpMatcher(prefix == null ? "" : prefix).isStartMatch(word);
+ private static void addWordsForEditor(EditorEx editor,
+ final CamelHumpMatcher matcher,
+ final CharSequence chars,
+ final List<CompletionVariant> words,
+ final List<CompletionVariant> afterWords, final int caretOffset) {
+ int startOffset = 0;
+ TokenProcessor processor = new TokenProcessor() {
+ @Override
+ public boolean processToken(int start, int end) {
+ if ((start > caretOffset || end < caretOffset) && //skip prefix itself
+ end - start > matcher.getPrefix().length() && isWordLike(chars, start, end)) {
+ final String word = chars.subSequence(start, end).toString();
+ if (matcher.isStartMatch(word)) {
+ CompletionVariant v = new CompletionVariant(word, start);
+ if (end > caretOffset) {
+ afterWords.add(v);
+ }
+ else {
+ words.add(v);
+ }
+ }
+ }
+ return true;
+ }
+ };
+ processWords(editor, startOffset, processor);
+ }
+
+ private static void processWords(Editor editor, int startOffset, TokenProcessor processor) {
+ CharSequence chars = editor.getDocument().getCharsSequence();
+ HighlighterIterator iterator = ((EditorEx)editor).getHighlighter().createIterator(startOffset);
+ while (!iterator.atEnd()) {
+ int start = iterator.getStart();
+ int end = iterator.getEnd();
+ while (start < end) {
+ int nextWs = StringUtil.indexOfAny(chars, WHITESPACE_CHARS, start, end);
+ if (nextWs < 0) {
+ if (isWordLike(chars, start, end) && !processor.processToken(start, end)) {
+ return;
+ }
+ break;
+ }
+ if (isWordLike(chars, start, end) && !processor.processToken(start, nextWs)) {
+ return;
+ }
+ start = CharArrayUtil.shiftForward(chars, nextWs, WHITESPACE_CHARS);
+ }
+ iterator.advance();
+ }
}
private static CompletionData computeData(final Editor editor, final CharSequence charsSequence) {
final int offset = editor.getCaretModel().getOffset();
final CompletionData data = new CompletionData();
-
- final int caretOffset = editor.getCaretModel().getOffset();
-
- HighlighterIterator iterator = ((EditorEx)editor).getHighlighter().createIterator(offset - 1);
- int start = iterator.getStart();
- int end = iterator.getEnd();
- if (start <= offset && end >= offset) {
- if (isWordLike(charsSequence, start, end)) {
- data.myPrefix = charsSequence.subSequence(start, offset).toString();
- data.myWordUnderCursor = charsSequence.subSequence(start, end).toString();
- data.startOffset = start;
+
+ processWords(editor, offset - 1, new TokenProcessor() {
+ @Override
+ public boolean processToken(int start, int end) {
+ if (start > offset) {
+ return false;
+ }
+ if (end >= offset) {
+ data.myPrefix = charsSequence.subSequence(start, offset).toString();
+ data.myWordUnderCursor = charsSequence.subSequence(start, end).toString();
+ data.startOffset = start;
+ return false;
+ }
+ return true;
}
- }
- iterator.advance();
+ });
if (data.myPrefix == null) {
data.myPrefix = "";
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java
index 100e1e1..82cd682 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java
@@ -96,10 +96,6 @@
boolean errorFound = daemonCodeAnalyzer.getFileStatusMap().wasErrorFound(myDocument);
for(ExternalAnnotator externalAnnotator: externalAnnotators) {
- if (!errorFound) {
- externalAnnotator.annotate(psiRoot, myAnnotationHolder);
- }
-
final Object collectedInfo = externalAnnotator.collectInformation(psiRoot, myEditor, errorFound);
if (collectedInfo != null) {
myAnnotator2DataMap.put(externalAnnotator, new MyData(psiRoot, collectedInfo));
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
index 02879fb..295c177 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
@@ -513,42 +513,6 @@
}
}
- @NotNull
- private HighlightInfoType highlightTypeFromDescriptor(@NotNull ProblemDescriptor problemDescriptor, @NotNull HighlightSeverity severity) {
- final ProblemHighlightType highlightType = problemDescriptor.getHighlightType();
- switch (highlightType) {
- case GENERIC_ERROR_OR_WARNING:
- return mySeverityRegistrar.getHighlightInfoTypeBySeverity(severity);
- case LIKE_DEPRECATED:
- return new HighlightInfoType.HighlightInfoTypeImpl(severity, HighlightInfoType.DEPRECATED.getAttributesKey());
- case LIKE_UNKNOWN_SYMBOL:
- if (severity == HighlightSeverity.ERROR) {
- return new HighlightInfoType.HighlightInfoTypeImpl(severity, HighlightInfoType.WRONG_REF.getAttributesKey());
- }
- if (severity == HighlightSeverity.WARNING) {
- return new HighlightInfoType.HighlightInfoTypeImpl(severity, CodeInsightColors.WEAK_WARNING_ATTRIBUTES);
- }
- return mySeverityRegistrar.getHighlightInfoTypeBySeverity(severity);
- case LIKE_UNUSED_SYMBOL:
- return new HighlightInfoType.HighlightInfoTypeImpl(severity, HighlightInfoType.UNUSED_SYMBOL.getAttributesKey());
- case INFO:
- return HighlightInfoType.INFO;
- case WEAK_WARNING:
- return HighlightInfoType.WEAK_WARNING;
- case ERROR:
- return HighlightInfoType.WRONG_REF;
- case GENERIC_ERROR:
- return HighlightInfoType.ERROR;
- case INFORMATION:
- final TextAttributesKey attributes = ((ProblemDescriptorBase)problemDescriptor).getEnforcedTextAttributes();
- if (attributes != null) {
- return new HighlightInfoType.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, attributes);
- }
- return HighlightInfoType.INFORMATION;
- }
- throw new RuntimeException("Cannot map " + highlightType);
- }
-
@Override
protected void applyInformationWithProgress() {
UpdateHighlightersUtil.setHighlightersToEditor(myProject, myDocument, myStartOffset, myEndOffset, myInfos, getColorsScheme(), getId());
@@ -592,7 +556,7 @@
PsiElement element) {
if (element == null) return;
if (myIgnoreSuppressed && SuppressionUtil.inspectionResultSuppressed(element, tool.getTool())) return;
- HighlightInfoType level = highlightTypeFromDescriptor(descriptor, severity);
+ HighlightInfoType level = ProblemDescriptorUtil.highlightTypeFromDescriptor(descriptor, severity, mySeverityRegistrar);
HighlightInfo info = createHighlightInfo(descriptor, tool, level, emptyActionRegistered, element);
if (info == null) return;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.java
index 14617b0..279aa54 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -171,7 +171,7 @@
* @param offset target offset where line feed will be inserted
* @return offset to use for inserting closing brace
*/
- private static int calculateOffsetToInsertClosingBrace(PsiFile file, CharSequence text, final int offset) {
+ protected int calculateOffsetToInsertClosingBrace(PsiFile file, CharSequence text, final int offset) {
PsiElement element = PsiUtilCore.getElementAtOffset(file, offset);
ASTNode node = element.getNode();
if (node != null && node.getElementType() == TokenType.WHITE_SPACE) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
index 8b33bb7..0e5bcb2 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
@@ -315,7 +315,7 @@
if (i == paramCount + added - 1) {
myOneLineComponents[index] = new OneLineComponent();
setBackground(background);
- buf.append(myOneLineComponents[index].setup(text, flagsMap, background));
+ buf.append(myOneLineComponents[index].setup(escapeString(text), flagsMap, background));
add(myOneLineComponents[index], new GridBagConstraints(0, index, 1, 1, 1, 0, GridBagConstraints.WEST,
GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
index += 1;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java
index 2a4594e..134143d 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java
@@ -30,6 +30,7 @@
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupAdapter;
import com.intellij.openapi.ui.popup.JBPopupFactory;
@@ -232,7 +233,7 @@
gbConstraints.gridx = 1;
gbConstraints.insets = new Insets(0, 4, 0, 0);
- myExpandByCombo = new JComboBox(new Object[]{myDefaultShortcutItem, SPACE, TAB, ENTER});
+ myExpandByCombo = new ComboBox(new Object[]{myDefaultShortcutItem, SPACE, TAB, ENTER}, -1);
myExpandByCombo.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
@@ -309,6 +310,9 @@
final Runnable updateLabel = new Runnable() {
@Override
public void run() {
+ myExpandByCombo.setEnabled(isExpandableFromEditor());
+ updateHighlighter();
+
StringBuilder sb = new StringBuilder();
String oldPrefix = "";
for (TemplateContextType type : getApplicableContexts()) {
@@ -343,7 +347,7 @@
public boolean onClick(MouseEvent e, int clickCount) {
if (disposeContextPopup()) return false;
- final JPanel content = createPopupContextPanel(updateLabel);
+ final JPanel content = createPopupContextPanel(updateLabel, myContext);
Dimension prefSize = content.getPreferredSize();
if (myLastSize != null && (myLastSize.width > prefSize.width || myLastSize.height > prefSize.height)) {
content.setPreferredSize(new Dimension(Math.max(prefSize.width, myLastSize.width), Math.max(prefSize.height, myLastSize.height)));
@@ -374,7 +378,7 @@
return false;
}
- private JPanel createPopupContextPanel(final Runnable onChange) {
+ static JPanel createPopupContextPanel(final Runnable onChange, final Map<TemplateContextType, Boolean> context) {
JPanel panel = new JPanel(new BorderLayout());
MultiMap<TemplateContextType, TemplateContextType> hierarchy = new MultiMap<TemplateContextType, TemplateContextType>() {
@@ -383,7 +387,7 @@
return new LinkedHashMap<TemplateContextType, Collection<TemplateContextType>>();
}
};
- for (TemplateContextType type : myContext.keySet()) {
+ for (TemplateContextType type : context.keySet()) {
hierarchy.putValue(type.getBaseContextType(), type);
}
@@ -401,17 +405,15 @@
protected void onNodeStateChanged(CheckedTreeNode node) {
final TemplateContextType type = (TemplateContextType)((Pair)node.getUserObject()).first;
if (type != null) {
- myContext.put(type, node.isChecked());
+ context.put(type, node.isChecked());
}
- myExpandByCombo.setEnabled(isExpandableFromEditor());
- updateHighlighter();
onChange.run();
}
};
for (TemplateContextType type : hierarchy.get(null)) {
- addContextNode(hierarchy, root, type);
+ addContextNode(hierarchy, root, type, context);
}
((DefaultTreeModel)checkboxTree.getModel()).nodeStructureChanged(root);
@@ -434,23 +436,23 @@
return panel;
}
- private void addContextNode(MultiMap<TemplateContextType, TemplateContextType> hierarchy,
- CheckedTreeNode parent,
- TemplateContextType type) {
+ private static void addContextNode(MultiMap<TemplateContextType, TemplateContextType> hierarchy,
+ CheckedTreeNode parent,
+ TemplateContextType type, Map<TemplateContextType, Boolean> context) {
final Collection<TemplateContextType> children = hierarchy.get(type);
final String name = UIUtil.removeMnemonic(type.getPresentableName());
final CheckedTreeNode node = new CheckedTreeNode(Pair.create(children.isEmpty() ? type : null, name));
parent.add(node);
if (children.isEmpty()) {
- node.setChecked(myContext.get(type));
+ node.setChecked(context.get(type));
}
else {
for (TemplateContextType child : children) {
- addContextNode(hierarchy, node, child);
+ addContextNode(hierarchy, node, child, context);
}
final CheckedTreeNode other = new CheckedTreeNode(Pair.create(type, "Other"));
- other.setChecked(myContext.get(type));
+ other.setChecked(context.get(type));
node.add(other);
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java
index 19033d9..76a423a 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java
@@ -30,12 +30,11 @@
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SchemesManager;
import com.intellij.openapi.project.DumbAwareAction;
-import com.intellij.openapi.ui.InputValidator;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.ui.Splitter;
+import com.intellij.openapi.ui.*;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.*;
import com.intellij.util.Alarm;
@@ -848,12 +847,43 @@
}
};
+ final DumbAwareAction changeContext = new DumbAwareAction("Change context...") {
+
+ @Override
+ public void update(AnActionEvent e) {
+ boolean enabled = !getSelectedTemplates().isEmpty();
+ e.getPresentation().setEnabled(enabled);
+ super.update(e);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ Map<TemplateImpl, DefaultMutableTreeNode> templates = getSelectedTemplates();
+ Map<TemplateContextType, Boolean> context = ContainerUtil.newHashMap();
+ for (TemplateContextType type : TemplateManagerImpl.getAllContextTypes()) {
+ context.put(type, Boolean.FALSE);
+ }
+ JPanel contextPanel = LiveTemplateSettingsEditor.createPopupContextPanel(EmptyRunnable.INSTANCE, context);
+ DialogBuilder builder = new DialogBuilder(TemplateListPanel.this);
+ builder.setCenterPanel(contextPanel);
+ builder.setTitle("Change Context Type For Selected Templates");
+ int result = builder.show();
+ if (result == DialogWrapper.OK_EXIT_CODE) {
+ for (TemplateImpl template : templates.keySet()) {
+ getTemplateContext(template).putAll(context);
+ }
+ }
+ }
+ };
+
+
myTree.addMouseListener(new PopupHandler() {
@Override
public void invokePopup(Component comp, int x, int y) {
final DefaultActionGroup group = new DefaultActionGroup();
group.add(rename);
group.add(move);
+ group.add(changeContext);
ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UNKNOWN, group).getComponent().show(comp, x, y);
}
});
diff --git a/platform/lang-impl/src/com/intellij/conversion/impl/ConversionServiceImpl.java b/platform/lang-impl/src/com/intellij/conversion/impl/ConversionServiceImpl.java
index a428f57..09ad57a 100644
--- a/platform/lang-impl/src/com/intellij/conversion/impl/ConversionServiceImpl.java
+++ b/platform/lang-impl/src/com/intellij/conversion/impl/ConversionServiceImpl.java
@@ -172,18 +172,23 @@
return converters;
}
- public static boolean isConversionNeeded(String projectPath) throws CannotConvertException {
- final ConversionContextImpl context = new ConversionContextImpl(projectPath);
- final List<ConversionRunner> runners = getSortedConverters(context);
- if (runners.isEmpty()) {
- return false;
- }
- for (ConversionRunner runner : runners) {
- if (runner.isConversionNeeded()) {
- return true;
+ public static boolean isConversionNeeded(String projectPath) {
+ try {
+ final ConversionContextImpl context = new ConversionContextImpl(projectPath);
+ final List<ConversionRunner> runners = getSortedConverters(context);
+ if (runners.isEmpty()) {
+ return false;
}
+ for (ConversionRunner runner : runners) {
+ if (runner.isConversionNeeded()) {
+ return true;
+ }
+ }
+ saveConversionResult(context);
}
- saveConversionResult(context);
+ catch (CannotConvertException e) {
+ LOG.info("Cannot check whether conversion of project files is needed or not, conversion won't be performed", e);
+ }
return false;
}
diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleFoldingConfigurable.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleFoldingConfigurable.java
index a4a5f8f..bf1195b 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleFoldingConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleFoldingConfigurable.java
@@ -113,7 +113,7 @@
@Nullable
private String showEditDialog(final String initialValue) {
- return Messages.showInputDialog(this, myQuery, "Folding pattern", Messages.getQuestionIcon(), initialValue, new InputValidatorEx() {
+ return Messages.showInputDialog(this, myQuery, "Folding Pattern", Messages.getQuestionIcon(), initialValue, new InputValidatorEx() {
@Override
public boolean checkInput(String inputString) {
return !StringUtil.isEmpty(inputString);
diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java
index 25e7b12..d7d1ab8 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java
@@ -58,7 +58,6 @@
import java.awt.event.KeyEvent;
import java.io.*;
-import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
@@ -78,20 +77,10 @@
private final ModelHelper myHelper;
private long myLastSaveStamp;
- public ConsoleHistoryController(@NotNull final String type,
- @Nullable final String persistenceId,
- @NotNull final LanguageConsoleImpl console,
- @NotNull final ConsoleHistoryModel model) {
- this(type, persistenceId, console, model, Charset.defaultCharset());
- }
- public ConsoleHistoryController(@NotNull final String type,
- @Nullable final String persistenceId,
- @NotNull final LanguageConsoleImpl console,
- @NotNull final ConsoleHistoryModel model,
- @NotNull final Charset charset)
- {
+ public ConsoleHistoryController(@NotNull String type, @Nullable String persistenceId,
+ @NotNull LanguageConsoleImpl console, @NotNull ConsoleHistoryModel model) {
String id = persistenceId == null || StringUtil.isEmpty(persistenceId) ? console.getProject().getPresentableUrl() : persistenceId;
- myHelper = new ModelHelper(type, id, model, charset);
+ myHelper = new ModelHelper(type, id, model);
myConsole = console;
}
@@ -358,14 +347,11 @@
private final String myId;
private final ConsoleHistoryModel myModel;
private String myContent;
- @NotNull
- private final Charset myCharset;
- public ModelHelper(String type, String id, ConsoleHistoryModel model, @NotNull Charset charset) {
+ public ModelHelper(String type, String id, ConsoleHistoryModel model) {
myType = type;
myId = id;
myModel = model;
- myCharset = charset;
}
public ConsoleHistoryModel getModel() {
@@ -395,7 +381,7 @@
if (!file.exists()) return false;
HierarchicalStreamReader xmlReader = null;
try {
- xmlReader = new XppReader(new InputStreamReader(new FileInputStream(file), myCharset));
+ xmlReader = new XppReader(new InputStreamReader(new FileInputStream(file), CharsetToolkit.UTF8));
String text = loadHistory(xmlReader, id);
if (text != null) {
myContent = text;
@@ -430,7 +416,7 @@
catch (Exception e) {
// not recognized
}
- serializer.setOutput(os = new SafeFileOutputStream(file), myCharset.name());
+ serializer.setOutput(os = new SafeFileOutputStream(file), CharsetToolkit.UTF8);
saveHistory(serializer);
}
catch (Exception ex) {
diff --git a/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java b/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java
index 3d5e57b..ad7ee68 100644
--- a/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java
@@ -31,6 +31,7 @@
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.ProjectLoadingErrorsNotifier;
import com.intellij.openapi.project.ProjectBundle;
+import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.UnknownFeaturesCollector;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.messages.MessageBus;
@@ -176,6 +177,7 @@
final FacetType<?,?> type = myFacetTypeRegistry.findFacetType(typeId);
if (type == null) {
addInvalidFacet(child, model, underlyingFacet, ProjectBundle.message("error.message.unknown.facet.type.0", typeId));
+ UnknownFeaturesCollector.getInstance(myModule.getProject()).registerUnknownFeature("com.intellij.facetType", typeId);
continue;
}
@@ -190,10 +192,6 @@
FacetTypeId<?> underlyingTypeId = type.getUnderlyingFacetType();
if (underlyingTypeId != null) {
expectedUnderlyingType = myFacetTypeRegistry.findFacetType(underlyingTypeId);
- if (expectedUnderlyingType == null) {
- addInvalidFacet(child, model, underlyingFacet, ProjectBundle.message("error.message.cannot.find.underlying.facet.type.for.0", typeId));
- continue;
- }
}
FacetType actualUnderlyingType = underlyingFacet != null ? underlyingFacet.getType() : null;
if (expectedUnderlyingType != null) {
@@ -220,7 +218,10 @@
}
}
- private void addInvalidFacet(final FacetState state, ModifiableFacetModel model, final Facet underlyingFacet, final String errorMessage) {
+ private void addInvalidFacet(final FacetState state,
+ ModifiableFacetModel model,
+ final Facet underlyingFacet,
+ final String errorMessage) {
final InvalidFacetManager invalidFacetManager = InvalidFacetManager.getInstance(myModule.getProject());
final InvalidFacetType type = InvalidFacetType.getInstance();
final InvalidFacetConfiguration configuration = new InvalidFacetConfiguration(state, errorMessage);
diff --git a/platform/lang-impl/src/com/intellij/facet/impl/FacetTypeRegistryImpl.java b/platform/lang-impl/src/com/intellij/facet/impl/FacetTypeRegistryImpl.java
index f39cd26..3cee6a4 100644
--- a/platform/lang-impl/src/com/intellij/facet/impl/FacetTypeRegistryImpl.java
+++ b/platform/lang-impl/src/com/intellij/facet/impl/FacetTypeRegistryImpl.java
@@ -63,6 +63,7 @@
myTypeIds.remove(stringId);
}
+ @NotNull
@Override
public synchronized FacetTypeId[] getFacetTypeIds() {
loadExtensions();
@@ -70,6 +71,7 @@
return ids.toArray(new FacetTypeId[ids.size()]);
}
+ @NotNull
@Override
public synchronized FacetType[] getFacetTypes() {
loadExtensions();
@@ -79,6 +81,7 @@
return facetTypes;
}
+ @NotNull
@Override
public FacetType[] getSortedFacetTypes() {
final FacetType[] types = getFacetTypes();
@@ -94,11 +97,13 @@
return typeId == null ? null : myFacetTypes.get(typeId);
}
+ @NotNull
@Override
- @Nullable
- public synchronized <F extends Facet<C>, C extends FacetConfiguration> FacetType<F, C> findFacetType(FacetTypeId<F> typeId) {
+ public synchronized <F extends Facet<C>, C extends FacetConfiguration> FacetType<F, C> findFacetType(@NotNull FacetTypeId<F> typeId) {
loadExtensions();
- return myFacetTypes.get(typeId);
+ FacetType type = myFacetTypes.get(typeId);
+ LOG.assertTrue(type != null, "Cannot find facet by id '" + typeId + "'");
+ return type;
}
private void loadExtensions() {
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
index 41eb35d..5d45876 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
@@ -24,7 +24,6 @@
import com.intellij.find.*;
import com.intellij.find.findUsages.FindUsagesManager;
import com.intellij.find.impl.livePreview.SearchResults;
-import com.intellij.ide.highlighter.custom.CustomFileHighlighter;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.ParserDefinition;
@@ -45,10 +44,7 @@
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.TextEditor;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.LanguageFileType;
-import com.intellij.openapi.fileTypes.SyntaxHighlighter;
-import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
+import com.intellij.openapi.fileTypes.*;
import com.intellij.openapi.fileTypes.impl.AbstractFileType;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.Project;
@@ -408,6 +404,7 @@
final VirtualFile lastFile;
int startOffset = 0;
final SyntaxHighlighter highlighter;
+ final Lexer highlightingLexer;
TokenSet tokensOfInterest;
final StringSearcher searcher;
@@ -422,6 +419,7 @@
this.searcher = searcher;
this.matcher = matcher;
this.relevantLanguages = relevantLanguages;
+ highlightingLexer = highlighter.getHighlightingLexer();
}
}
@@ -441,12 +439,16 @@
CommentsLiteralsSearchData data = model.getUserData(ourCommentsLiteralsSearchDataKey);
if (data == null || !Comparing.equal(data.lastFile, file)) {
- SyntaxHighlighter lexer;
+ SyntaxHighlighter highlighter = getHighlighter(file, lang);
+
+ if (highlighter == null) {
+ LOG.error("Syntax highlighter is null:"+file);
+ return NOT_FOUND_RESULT;
+ }
TokenSet tokensOfInterest = TokenSet.EMPTY;
Set<Language> relevantLanguages = null;
if (lang != null) {
- lexer = getHighlighter(file, lang);
final Language finalLang = lang;
relevantLanguages = ApplicationManager.getApplication().runReadAction(new Computable<Set<Language>>() {
@Override
@@ -488,25 +490,23 @@
tokensOfInterest = TokenSet.orSet(tokensOfInterest, TokenSet.create(convenienceXmlAttrType));
}
}
- } else if (ftype instanceof AbstractFileType) {
+ } else {
+ LOG.assertTrue(ftype instanceof AbstractFileType, ftype);
if (model.isInCommentsOnly()) {
tokensOfInterest = TokenSet.create(CustomHighlighterTokenType.LINE_COMMENT, CustomHighlighterTokenType.MULTI_LINE_COMMENT);
}
if (model.isInStringLiteralsOnly()) {
tokensOfInterest = TokenSet.orSet(tokensOfInterest, TokenSet.create(CustomHighlighterTokenType.STRING, CustomHighlighterTokenType.SINGLE_QUOTED_STRING));
}
- lexer = new CustomFileHighlighter(((AbstractFileType)ftype).getSyntaxTable());
- } else {
- return NOT_FOUND_RESULT;
}
Matcher matcher = model.isRegularExpressions() ? compileRegExp(model, ""):null;
StringSearcher searcher = matcher != null ? null: createStringSearcher(model);
- data = new CommentsLiteralsSearchData(file, relevantLanguages, lexer, tokensOfInterest, searcher, matcher);
+ data = new CommentsLiteralsSearchData(file, relevantLanguages, highlighter, tokensOfInterest, searcher, matcher);
model.putUserData(ourCommentsLiteralsSearchDataKey, data);
}
- final Lexer lexer = data.highlighter.getHighlightingLexer();
+ final Lexer lexer = data.highlightingLexer;
lexer.start(text, model.isForward() && data.startOffset < offset ? data.startOffset : 0, text.length(), 0);
IElementType tokenType;
@@ -527,12 +527,22 @@
) {
int start = lexer.getTokenStart();
+ int end = lexer.getTokenEnd();
+ if (model.isInStringLiteralsOnly()) { // skip literal quotes itself from matching
+ char c = text.charAt(start);
+ if (c == '"' || c == '\'') {
+ while (start < end && c == text.charAt(start)) {
+ ++start;
+ if (c == text.charAt(end - 1) && start < end) --end;
+ }
+ }
+ }
while(true) {
FindResultImpl findResult = null;
if (data.searcher != null) {
- int i = data.searcher.scan(text, textArray, start, lexer.getTokenEnd());
+ int i = data.searcher.scan(text, textArray, start, end);
if (i != -1 && i >= start) {
final int matchEnd = i + model.getStringToFind().length();
@@ -544,7 +554,7 @@
}
}
} else {
- data.matcher.reset(text.subSequence(start, lexer.getTokenEnd()));
+ data.matcher.reset(text.subSequence(start, end));
if (data.matcher.find()) {
final int matchEnd = start + data.matcher.end();
if (start >= offset || !scanningForward) {
@@ -563,7 +573,7 @@
return findResult;
} else {
- if (findResult.getStartOffset() >= offset) return prevFindResult;
+ if (findResult.getEndOffset() >= offset) return prevFindResult;
prevFindResult = findResult;
start = findResult.getEndOffset();
continue;
@@ -621,9 +631,12 @@
return tokensOfInterest;
}
- private static SyntaxHighlighter getHighlighter(VirtualFile file, Language lang) {
- SyntaxHighlighter syntaxHighlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(lang, null, file);
- assert syntaxHighlighter != null:"Syntax highlighter is null:"+file;
+ private static @Nullable SyntaxHighlighter getHighlighter(VirtualFile file, @Nullable Language lang) {
+ SyntaxHighlighter syntaxHighlighter = lang != null ? SyntaxHighlighterFactory.getSyntaxHighlighter(lang, null, file) : null;
+ if (lang == null || syntaxHighlighter instanceof PlainSyntaxHighlighter) {
+ syntaxHighlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(file.getFileType(), null, file);
+ }
+
return syntaxHighlighter;
}
diff --git a/platform/lang-impl/src/com/intellij/formatting/AlignmentImpl.java b/platform/lang-impl/src/com/intellij/formatting/AlignmentImpl.java
index a641c51..427fa18 100644
--- a/platform/lang-impl/src/com/intellij/formatting/AlignmentImpl.java
+++ b/platform/lang-impl/src/com/intellij/formatting/AlignmentImpl.java
@@ -161,18 +161,87 @@
myOffsetRespBlocks.add(block);
}
+ @Nullable
+ private AbstractBlockWrapper getLeftRespNeighbor(@NotNull AbstractBlockWrapper block) {
+ AbstractBlockWrapper nearLeft = null;
+ int distance = Integer.MAX_VALUE;
+ for (AbstractBlockWrapper offsetBlock : myOffsetRespBlocks) if (offsetBlock != null) {
+ int curDistance = block.getStartOffset() - offsetBlock.getStartOffset();
+ if (curDistance < distance && curDistance > 0) {
+ nearLeft = offsetBlock;
+ distance = curDistance;
+ }
+ }
+ return nearLeft;
+ }
+
+ @NotNull
+ private static AbstractBlockWrapper extendBlockFromStart(@NotNull AbstractBlockWrapper block) {
+ while (true) {
+ AbstractBlockWrapper parent = block.getParent();
+ if (parent != null && parent.getStartOffset() == block.getStartOffset()) {
+ block = parent;
+ }
+ else {
+ return block;
+ }
+ }
+ }
+
+ @NotNull
+ private static AbstractBlockWrapper extendBlockFromEnd(@NotNull AbstractBlockWrapper block) {
+ while (true) {
+ AbstractBlockWrapper parent = block.getParent();
+ if (parent != null && parent.getEndOffset() == block.getEndOffset()) {
+ block = parent;
+ }
+ else {
+ return block;
+ }
+ }
+ }
+
private boolean continueOffsetResponsibleBlockRetrieval(@Nullable AbstractBlockWrapper block) {
// We don't want to align block that doesn't start new line if it's not configured for 'by columns' alignment.
if (!myAllowBackwardShift && block != null && !block.getWhiteSpace().containsLineFeeds()) {
return false;
}
- for (AbstractBlockWrapper offsetBlock : myOffsetRespBlocks) {
- if (offsetBlock == block) {
- continue;
- }
- if (!onDifferentLines(offsetBlock, block) && block != null && offsetBlock.getStartOffset() < block.getStartOffset()) {
+
+ if (block != null) {
+ AbstractBlockWrapper prevAlignBlock = getLeftRespNeighbor(block);
+ if (!onDifferentLines(prevAlignBlock, block)) {
return false;
}
+
+ //blocks are on different lines
+ if (myAllowBackwardShift
+ && myAnchor == Anchor.RIGHT
+ && prevAlignBlock != null
+ && prevAlignBlock.getWhiteSpace().containsLineFeeds() // {prevAlignBlock} starts new indent => can be moved
+ ) {
+ // extend block on position for right align
+ prevAlignBlock = extendBlockFromStart(prevAlignBlock);
+
+ AbstractBlockWrapper current = block;
+ do {
+ if (current.getStartOffset() < prevAlignBlock.getEndOffset()) {
+ return false; //{prevAlignBlock{current}} | {current}{prevAlignBlock}, no new lines
+ }
+ if (current.getWhiteSpace().containsLineFeeds()) {
+ break; // correct new line was found
+ }
+ else {
+ AbstractBlockWrapper prev = current.getPreviousBlock();
+ if (prev != null) {
+ prev = extendBlockFromEnd(prev);
+ }
+ current = prev;
+ }
+ } while (current != null);
+ if (current == null) {
+ return false; //root block is the top
+ }
+ }
}
return myParentAlignment == null || myParentAlignment.continueOffsetResponsibleBlockRetrieval(block);
}
diff --git a/platform/lang-impl/src/com/intellij/ide/FileIconPatcherImpl.java b/platform/lang-impl/src/com/intellij/ide/FileIconPatcherImpl.java
index e0fb470..64fce21 100644
--- a/platform/lang-impl/src/com/intellij/ide/FileIconPatcherImpl.java
+++ b/platform/lang-impl/src/com/intellij/ide/FileIconPatcherImpl.java
@@ -21,7 +21,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.PsiManager;
import com.intellij.util.PsiIconUtil;
import org.jetbrains.annotations.NotNull;
@@ -33,9 +33,10 @@
@Override
@Nullable
public Icon getIcon(@NotNull final VirtualFile file, final int flags, final Project project) {
- if(project == null) return null;
+ if (project == null) return null;
- final PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
+ final PsiFileSystemItem psiFile = file.isDirectory() ? PsiManager.getInstance(project).findDirectory(file)
+ : PsiManager.getInstance(project).findFile(file);
return psiFile == null ? null : PsiIconUtil.getProvidersIcon(psiFile, flags);
}
}
\ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/ide/NativeIconProvider.java b/platform/lang-impl/src/com/intellij/ide/NativeIconProvider.java
new file mode 100644
index 0000000..d709da6
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/NativeIconProvider.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.ide;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.INativeFileType;
+import com.intellij.openapi.fileTypes.UnknownFileType;
+import com.intellij.openapi.util.Iconable;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFileSystemItem;
+import com.intellij.psi.impl.ElementBase;
+import com.intellij.ui.DeferredIconImpl;
+import com.intellij.util.Function;
+import com.intellij.util.ui.update.ComparableObject;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.io.File;
+import java.util.*;
+
+/**
+ * @author yole
+ */
+public class NativeIconProvider extends IconProvider {
+ private final Map<Ext, Icon> myIconCache = new HashMap<Ext, Icon>();
+ // on Windows .exe and .ico files provide their own icons which can differ for each file, cache them by full file path
+ private final Set<Ext> myCustomIconExtensions =
+ SystemInfo.isWindows ? new HashSet<Ext>(Arrays.asList(new Ext("exe"), new Ext("ico"))) : new HashSet<Ext>();
+ private final Map<String, Icon> myCustomIconCache = new HashMap<String, Icon>();
+
+ private static final Ext NO_EXT = new Ext(null);
+
+ private static final Ext CLOSED_DIR = new Ext(null, 0);
+
+ @Nullable
+ @Override
+ public Icon getIcon(@NotNull PsiElement element, @Iconable.IconFlags int flags) {
+ if (element instanceof PsiFileSystemItem) {
+ VirtualFile file = ((PsiFileSystemItem)element).getVirtualFile();
+ return doGetIcon(file, flags);
+ }
+ return null;
+ }
+
+ @Nullable
+ private Icon doGetIcon(@NotNull VirtualFile file, final int flags) {
+ if (!isNativeFileType(file)) return null;
+
+ final Ext ext = getExtension(file, flags);
+ final String filePath = file.getPath();
+
+ Icon icon;
+ synchronized (myIconCache) {
+ if (!myCustomIconExtensions.contains(ext)) {
+ icon = ext != null ? myIconCache.get(ext) : null;
+ }
+ else {
+ icon = filePath != null ? myCustomIconCache.get(filePath) : null;
+ }
+ }
+ if (icon != null) {
+ return icon;
+ }
+ return new DeferredIconImpl<VirtualFile>(ElementBase.ICON_PLACEHOLDER.getValue(), file, false, new Function<VirtualFile, Icon>() {
+ @Override
+ public Icon fun(VirtualFile virtualFile) {
+ final File f = new File(filePath);
+ if (!f.exists()) {
+ return null;
+ }
+ Icon icon;
+ try { // VM will ensure lock to init -static final field--, note we should have no read access here, to avoid deadlock with EDT needed to init component
+ assert SwingComponentHolder.ourFileChooser != null || !ApplicationManager.getApplication().isReadAccessAllowed();
+ icon = getNativeIcon(f);
+ }
+ catch (Exception e) { // see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4854174
+ return null;
+ }
+ if (ext != null) {
+ synchronized (myIconCache) {
+ if (!myCustomIconExtensions.contains(ext)) {
+ myIconCache.put(ext, icon);
+ }
+ else if (filePath != null) {
+ myCustomIconCache.put(filePath, icon);
+ }
+ }
+ }
+ return icon;
+ }
+ });
+ }
+
+ @Nullable
+ public static Icon getNativeIcon(@Nullable File file) {
+ return file == null ? null : SwingComponentHolder.ourFileChooser.getIcon(file);
+ }
+
+ private static Ext getExtension(final VirtualFile file, final int flags) {
+ if (file.isDirectory()) {
+ if (file.getExtension() == null) {
+ return CLOSED_DIR;
+ } else {
+ return new Ext(file.getExtension(), flags);
+ }
+ }
+
+ return file.getExtension() != null ? new Ext(file.getExtension()) : NO_EXT;
+ }
+
+ static class SwingComponentHolder {
+ private static final JFileChooser ourFileChooser = new JFileChooser();
+ }
+
+ protected boolean isNativeFileType(VirtualFile file) {
+ FileType type = file.getFileType();
+
+ if (type instanceof INativeFileType) return ((INativeFileType)type).useNativeIcon();
+ return type instanceof UnknownFileType && !file.isDirectory();
+ }
+
+ private static class Ext extends ComparableObject.Impl {
+ private final Object[] myText;
+
+ private Ext(@Nullable String text) {
+ myText = new Object[] {text};
+ }
+
+ private Ext(@Nullable String text, final int flags) {
+ myText = new Object[] {text, flags};
+ }
+
+ @Override
+ @NotNull
+ public Object[] getEqualityObjects() {
+ return myText;
+ }
+
+ @Override
+ public String toString() {
+ return myText[0] != null ? myText[0].toString() : null;
+ }
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
index fb332bb..c54493b 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
@@ -34,6 +34,8 @@
import com.intellij.openapi.actionSystem.impl.ActionManagerImpl;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.colors.EditorFontType;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileEditor.impl.EditorHistoryManager;
import com.intellij.openapi.keymap.KeymapUtil;
@@ -71,6 +73,7 @@
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.OnOffButton;
import com.intellij.ui.popup.AbstractPopup;
+import com.intellij.ui.popup.PopupPositionManager;
import com.intellij.util.Alarm;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
@@ -89,6 +92,8 @@
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
+import static com.intellij.ui.popup.PopupPositionManager.Position.*;
+
/**
* @author Konstantin Bulenkov
*/
@@ -107,10 +112,15 @@
private JBPopup myPopup;
private int myLeftWidth;
private SearchListModel myListModel = new SearchListModel();
+ private int myMoreClassesIndex = -1;
+ private int myMoreFilesIndex = -1;
+ private int myMoreActionsIndex = -1;
+ private int myMoreSettingsIndex = -1;
private TitleIndexes myTitleIndexes;
private Map<String, String> myConfigurables = new HashMap<String, String>();
private Alarm myAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, ApplicationManager.getApplication());
+ private Alarm myUpdateAlarm = new Alarm(ApplicationManager.getApplication());
private JBList myList = new JBList(myListModel) {
{
setOpaque(false);
@@ -142,11 +152,9 @@
}, null);
}
- private int myTopHitsCount;
- private int myInitialWidth;
- private int myInitialHeight;
private Balloon myBalloon;
private JLabel mySearchLabel;
+ private int myPopupActualWidth;
public SearchEverywhereAction() {
myContentPanel = new JPanel(new BorderLayout());
@@ -184,7 +192,7 @@
final int i = myList.locationToIndex(e.getPoint());
if (i != -1) {
myList.setSelectedIndex(i);
- doNavigate();
+ doNavigate(i);
}
}
});
@@ -272,7 +280,7 @@
focusManager.requestDefaultFocus(true);
}
else if (keyCode == KeyEvent.VK_ENTER) {
- doNavigate();
+ doNavigate(myList.getSelectedIndex());
}
}
});
@@ -291,7 +299,7 @@
myCalcThread = null;
}
myAlarm.cancelAllRequests();
- myListModel.clear();
+ clearModel();
myContentPanel.remove(field);
myContentPanel.add(mySearchLabel);
@@ -307,14 +315,37 @@
});
}
+ private void clearModel() {
+ myListModel.clear();
+ myMoreClassesIndex = -1;
+ myMoreFilesIndex = -1;
+ myMoreActionsIndex = -1;
+ myMoreSettingsIndex = -1;
+ }
+
private SearchTextField getField() {
return myBalloon != null ? myPopupField : field;
}
- private void doNavigate() {
+ private void doNavigate(int index) {
+ final Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(getField().getTextEditor()));
+ if (isMoreItem(index)) {
+ String actionId = null;
+ if (index == myMoreClassesIndex) actionId = "GotoClass";
+ else if (index == myMoreFilesIndex) actionId = "GotoFile";
+ else if (index == myMoreSettingsIndex) actionId = "ShowSettings";
+ else if (index == myMoreActionsIndex) actionId = "GotoAction";
+ if (actionId != null) {
+ final AnAction action = ActionManager.getInstance().getAction(actionId);
+ GotoActionAction.openOptionOrPerformAction(action, getField().getText(), project, getField(), myActionEvent);
+ if (myPopup != null && myPopup.isVisible()) {
+ myPopup.cancel();
+ }
+ return;
+ }
+ }
final String pattern = getField().getText();
final Object value = myList.getSelectedValue();
- final Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(getField().getTextEditor()));
IdeFocusManager focusManager = IdeFocusManager.findInstanceByComponent(field.getTextEditor());
if (myPopup != null && myPopup.isVisible()) {
myPopup.cancel();
@@ -356,6 +387,10 @@
focusManager.requestDefaultFocus(true);
}
+ private boolean isMoreItem(int index) {
+ return index == myMoreClassesIndex || index == myMoreFilesIndex || index == myMoreSettingsIndex || index == myMoreActionsIndex;
+ }
+
private void rebuildList(final String pattern) {
if (myCalcThread != null) {
myCalcThread.cancel();
@@ -377,13 +412,16 @@
myPopupField.setOpaque(true);
initSearchField(myPopupField);
myPopupField.getTextEditor().setColumns(25);
- myBalloon = JBPopupFactory.getInstance().createBalloonBuilder(myPopupField)
+ final JPanel panel = new JPanel(new BorderLayout());
+ panel.add(new JLabel("Search Everywhere:"), BorderLayout.NORTH);
+ panel.add(myPopupField, BorderLayout.CENTER);
+ myBalloon = JBPopupFactory.getInstance().createBalloonBuilder(panel)
.setShowCallout(false)
.setHideOnKeyOutside(false)
.setHideOnAction(true)
.setAnimationCycle(0)
.setDialogMode(false)
- .setBorderColor(new JBColor(new Color(156, 192, 255), new Color(77, 77, 77)))
+ .setBorderColor(new JBColor(new Color(156, 192, 255), Gray._77))
.setFillColor(new JBColor(new Color(77, 121, 231), new Color(60, 63, 65)))
.createBalloon();
myBalloon.show(JBPopupFactory.getInstance().guessBestPopupLocation(e.getDataContext()), Balloon.Position.below);
@@ -454,8 +492,10 @@
Component cmp;
PsiFile file;
myLocationString = null;
- if (value instanceof VirtualFile && myProject != null && (file = PsiManager.getInstance(myProject).findFile((VirtualFile)value)) != null) {
- cmp = new GotoFileCellRenderer(list.getWidth()).getListCellRendererComponent(list, file, index, isSelected, cellHasFocus);
+ if (isMoreItem(index)) {
+ cmp = More.get(isSelected);
+ } else if (value instanceof VirtualFile && myProject != null && (file = PsiManager.getInstance(myProject).findFile((VirtualFile)value)) != null) {
+ cmp = new GotoFileCellRenderer(list.getWidth()).getListCellRendererComponent(list, file, index, isSelected, cellHasFocus);
} else if (value instanceof PsiElement) {
cmp = myPsiRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
} else {
@@ -477,9 +517,12 @@
cmp = panel;
}
- final Color bg = isSelected ? UIUtil.getListSelectionBackground() : getRightBackground();
- cmp.setBackground(bg);
- myMainPanel.setBorder(new CustomLineBorder(bg, 0, 0, 1, 0));
+ //cmp.setBackground(bg);
+ Color bg = cmp.getBackground();
+ if (bg == null) {
+ bg = UIUtil.getListBackground(isSelected);
+ }
+ myMainPanel.setBorder(new CustomLineBorder(bg, 0, 0, 2, 0));
String title = myTitleIndexes.getTitle(index);
myMainPanel.removeAll();
if (title != null) {
@@ -487,6 +530,11 @@
myMainPanel.add(SeparatorComponent.createLabeledLineSeparator(" " + title, getRightBackground()), BorderLayout.NORTH);
}
myMainPanel.add(cmp, BorderLayout.CENTER);
+ final int width = myMainPanel.getPreferredSize().width;
+ if (width > myPopupActualWidth) {
+ myPopupActualWidth = width;
+ schedulePopupUpdate();
+ }
return myMainPanel;
}
@@ -578,6 +626,16 @@
}
}
+ private void schedulePopupUpdate() {
+ myUpdateAlarm.cancelAllRequests();
+ myUpdateAlarm.addRequest(new Runnable() {
+ @Override
+ public void run() {
+ updatePopupBounds();
+ }
+ }, 50);
+ }
+
private static JBColor getTitlePanelBackground() {
return new JBColor(Gray._242, JBColor.background());
}
@@ -620,7 +678,7 @@
@Override
public void run() {
myTitleIndexes.clear();
- myListModel.clear();
+ clearModel();
myAlreadyAddedFiles.clear();
}
});
@@ -659,13 +717,13 @@
Object[] objects = myActionModel.getElementsByName(o.elementName, true, pattern);
for (Object object : objects) {
myProgressIndicator.checkCanceled();
- if (isSetting(object) && settings.size() < 15) {
+ if (isSetting(object) && settings.size() < 5) {
settings.add(object);
}
else if (isToolWindowAction(object) && toolWindows.size() < 10) {
toolWindows.add((AnAction)((Map.Entry)object).getKey());
}
- else if (isActionValue(object) && actions.size() < 15) {
+ else if (isActionValue(object) && actions.size() < 5) {
actions.add((AnAction)((Map.Entry)object).getKey());
}
}
@@ -689,12 +747,14 @@
myListModel.addElement(action);
}
}
+ myMoreActionsIndex = actions.size() >= 5 ? myListModel.size() - 1 : -1;
if (settings.size() > 0) {
myTitleIndexes.settings = myListModel.size();
for (Object setting : settings) {
myListModel.addElement(setting);
}
}
+ myMoreSettingsIndex = settings.size() >= 5 ? myListModel.size() - 1 : -1;
}
});
}
@@ -719,7 +779,6 @@
filesCounter++;
}
}
- if (filesCounter > 15) break;
}
}
@@ -734,6 +793,7 @@
for (Object file : files) {
myListModel.addElement(file);
}
+ myMoreFilesIndex = files.size() >= 15 ? myListModel.size() - 1 : -1;
}
}
});
@@ -780,6 +840,7 @@
for (Object cls : classes) {
myListModel.addElement(cls);
}
+ myMoreClassesIndex = classes.size() >= 15 ? myListModel.size() - 1 : -1;
}
}
});
@@ -951,10 +1012,13 @@
myRenderer.recalculateWidth();
if (myPopup == null || !myPopup.isVisible()) {
+ final Font editorFont = EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.PLAIN);
+ myList.setFont(editorFont);
+ getField().getTextEditor().setFont(editorFont);
+ More.instance.label.setFont(editorFont);
final ActionCallback callback = ListDelegationUtil.installKeyboardDelegation(getField().getTextEditor(), myList);
final ComponentPopupBuilder builder = JBPopupFactory.getInstance()
.createComponentPopupBuilder(new JBScrollPane(myList), null);
- myInitialWidth = myInitialHeight = 0;
myPopup = builder
.setRequestFocus(false)
.setCancelKeyEnabled(false)
@@ -997,29 +1061,16 @@
//rebuildList("");
}
else {
- final Dimension size = myList.getPreferredSize();
- Dimension sz = new Dimension(Math.max(getField().getWidth(), size.width), size.height);
- if (sz.width > 800 || sz.height > 800) {
- final int extra = new JBScrollPane().getVerticalScrollBar().getWidth();
- sz = new Dimension(Math.min(800, Math.max(getField().getWidth(), size.width + extra)), Math.min(800, size.height + extra));
- sz.width += 16;
- }
- else {
- sz.height++;
- sz.height++;
- sz.width++;
- sz.width++;
- }
- myPopup.setSize(sz);
- final Point screen = getField().getLocationOnScreen();
- final int x;
- if (getField() == field) {
- x = screen.x + getField().getWidth() - myPopup.getSize().width;
- } else {
- x = screen.x - myLeftWidth - 5;
- }
-
- //myPopup.setLocation(new Point(x, myPopup.getLocationOnScreen().y));
+ updatePopupBounds();
+ //final Point screen = getField().getLocationOnScreen();
+ //final int x;
+ //if (getField() == field) {
+ // x = screen.x + getField().getWidth() - myPopup.getSize().width;
+ //} else {
+ // x = screen.x - myLeftWidth - 5;
+ //}
+ //
+ ////myPopup.setLocation(new Point(x, myPopup.getLocationOnScreen().y));
}
}
});
@@ -1083,6 +1134,34 @@
}
}
+ private void updatePopupBounds() {
+ if (myPopup == null || !myPopup.isVisible()) {
+ return;
+ }
+ final Dimension size = myList.getPreferredSize();
+ if (size.width < myPopupActualWidth) {
+ size.width = myPopupActualWidth;
+ }
+ Dimension sz = new Dimension(Math.max(getField().getWidth(), size.width), size.height);
+ if (sz.width > 800 || sz.height > 800) {
+ final int extra = new JBScrollPane().getVerticalScrollBar().getWidth();
+ sz = new Dimension(Math.min(800, Math.max(getField().getWidth(), size.width + extra)), Math.min(800, size.height + extra));
+ sz.width += 16;
+ }
+ else {
+ sz.height++;
+ sz.height++;
+ sz.width++;
+ sz.width++;
+ }
+ myPopup.setSize(sz);
+ adjustPopup();
+ }
+
+ private void adjustPopup() {
+ new PopupPositionManager.PositionAdjuster(getField().getTextEditor().getParent()).adjust(myPopup, BOTTOM, RIGHT, LEFT, TOP);
+ }
+
private static boolean isToolWindowAction(Object o) {
return isActionValue(o) && (o instanceof Map.Entry && ((Map.Entry)o).getKey() instanceof ActivateToolWindowAction);
}
@@ -1167,8 +1246,7 @@
catch (NoSuchFieldException e) {
}
- catch (IllegalAccessException e) {
- e.printStackTrace();
+ catch (IllegalAccessException ignore) {
}
}
@@ -1181,4 +1259,20 @@
fireContentsChanged(this, 0, getSize() - 1);
}
}
+
+ static class More extends JPanel {
+ static final More instance = new More();
+ final JLabel label = new JLabel(" ... more");
+
+ private More() {
+ super(new BorderLayout());
+ add(label, BorderLayout.WEST);
+ }
+
+ static More get(boolean isSelected) {
+ instance.setBackground(UIUtil.getListBackground(isSelected));
+ instance.label.setForeground(UIUtil.getListForeground(isSelected));
+ return instance;
+ }
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeHighlighterProvider.java b/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeHighlighterProvider.java
index 45b00de..cea90638 100644
--- a/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeHighlighterProvider.java
+++ b/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeHighlighterProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ide.highlighter.custom.CustomFileHighlighter;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -32,7 +33,7 @@
public class CustomFileTypeHighlighterProvider implements SyntaxHighlighterProvider {
@Override
@Nullable
- public SyntaxHighlighter create(final FileType fileType, @Nullable final Project project, @Nullable final VirtualFile file) {
+ public SyntaxHighlighter create(@NotNull final FileType fileType, @Nullable final Project project, @Nullable final VirtualFile file) {
if (fileType instanceof AbstractFileType) {
return new CustomFileHighlighter(((CustomSyntaxTableFileType) fileType).getSyntaxTable());
}
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java
index 0f4e1c6..0a9679b 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java
@@ -64,6 +64,6 @@
private static <P extends JpsElement> void addSourceFolder(VirtualFile vFile, ContentEntry entry,
JpsModuleSourceRootType<P> markAsRootType) {
- entry.addSourceFolder(vFile, markAsRootType, ModuleSourceRootEditHandler.getEditHandler(markAsRootType).createDefaultProperties());
+ entry.addSourceFolder(vFile, markAsRootType, markAsRootType.createDefaultProperties());
}
}
diff --git a/platform/lang-impl/src/com/intellij/ide/todo/TodoConfiguration.java b/platform/lang-impl/src/com/intellij/ide/todo/TodoConfiguration.java
deleted file mode 100644
index c4ef507..0000000
--- a/platform/lang-impl/src/com/intellij/ide/todo/TodoConfiguration.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.intellij.ide.todo;
-
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.components.NamedComponent;
-import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.JDOMExternalizable;
-import com.intellij.openapi.util.WriteExternalException;
-import com.intellij.psi.search.*;
-import com.intellij.util.EventDispatcher;
-import com.intellij.util.messages.MessageBus;
-import org.jdom.Element;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * @author Vladimir Kondratyev
- */
-public class TodoConfiguration implements NamedComponent, JDOMExternalizable {
- private TodoPattern[] myTodoPatterns;
- private TodoFilter[] myTodoFilters;
- private IndexPattern[] myIndexPatterns;
-
- private final EventDispatcher<PropertyChangeListener> myPropertyChangeMulticaster = EventDispatcher.create(PropertyChangeListener.class);
-
- @NonNls public static final String PROP_TODO_PATTERNS = "todoPatterns";
- @NonNls public static final String PROP_TODO_FILTERS = "todoFilters";
- @NonNls private static final String ELEMENT_PATTERN = "pattern";
- @NonNls private static final String ELEMENT_FILTER = "filter";
- private final MessageBus myMessageBus;
-
- /**
- * Invoked by reflection
- */
- TodoConfiguration(@NotNull MessageBus messageBus) {
- myMessageBus = messageBus;
- resetToDefaultTodoPatterns();
- }
-
- public void resetToDefaultTodoPatterns() {
- myTodoPatterns = new TodoPattern[]{
- new TodoPattern("\\btodo\\b.*", TodoAttributesUtil.createDefault(), false),
- new TodoPattern("\\bfixme\\b.*", TodoAttributesUtil.createDefault(), false),
- };
- myTodoFilters = new TodoFilter[]{};
- buildIndexPatterns();
- }
-
- private void buildIndexPatterns() {
- myIndexPatterns = new IndexPattern[myTodoPatterns.length];
- for(int i=0; i<myTodoPatterns.length; i++) {
- myIndexPatterns [i] = myTodoPatterns [i].getIndexPattern();
- }
- }
-
- public static TodoConfiguration getInstance() {
- return ServiceManager.getService(TodoConfiguration.class);
- }
-
- @Override
- @NotNull
- public String getComponentName() {
- return "TodoConfiguration";
- }
-
- @NotNull
- public TodoPattern[] getTodoPatterns() {
- return myTodoPatterns;
- }
-
- @NotNull
- public IndexPattern[] getIndexPatterns() {
- return myIndexPatterns;
- }
-
- public void setTodoPatterns(@NotNull TodoPattern[] todoPatterns) {
- doSetTodoPatterns(todoPatterns, true);
- }
-
- private void doSetTodoPatterns(@NotNull TodoPattern[] todoPatterns, final boolean shouldNotifyIndices) {
- TodoPattern[] oldTodoPatterns = myTodoPatterns;
- IndexPattern[] oldIndexPatterns = myIndexPatterns;
-
- myTodoPatterns = todoPatterns;
- buildIndexPatterns();
-
- // only trigger index refresh actual index patterns have changed
- if (shouldNotifyIndices && !Arrays.deepEquals(myIndexPatterns, oldIndexPatterns)) {
- final PropertyChangeEvent event =
- new PropertyChangeEvent(this, IndexPatternProvider.PROP_INDEX_PATTERNS, oldTodoPatterns, todoPatterns);
- myMessageBus.syncPublisher(IndexPatternProvider.INDEX_PATTERNS_CHANGED).propertyChange(event);
- }
-
- // only trigger gui and code daemon refresh when either the index patterns or presentation attributes have changed
- if (!Arrays.deepEquals(myTodoPatterns, oldTodoPatterns)) {
- final PropertyChangeListener multicaster = myPropertyChangeMulticaster.getMulticaster();
- multicaster.propertyChange(new PropertyChangeEvent(this, PROP_TODO_PATTERNS, oldTodoPatterns, todoPatterns));
- }
- }
-
- /**
- * @return <code>TodoFilter</code> with specified <code>name</code>. Method returns
- * <code>null</code> if there is no filter with <code>name</code>.
- */
- public TodoFilter getTodoFilter(String name) {
- for (TodoFilter filter : myTodoFilters) {
- if (filter.getName().equals(name)) {
- return filter;
- }
- }
- return null;
- }
-
- /**
- * @return all <code>TodoFilter</code>s.
- */
- @NotNull
- public TodoFilter[] getTodoFilters() {
- return myTodoFilters;
- }
-
- public void setTodoFilters(@NotNull TodoFilter[] filters) {
- TodoFilter[] oldFilters = myTodoFilters;
- myTodoFilters = filters;
- myPropertyChangeMulticaster.getMulticaster().propertyChange(new PropertyChangeEvent(this, PROP_TODO_FILTERS, oldFilters, filters));
- }
-
- public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) {
- myPropertyChangeMulticaster.addListener(listener);
- }
- public void addPropertyChangeListener(@NotNull PropertyChangeListener listener, @NotNull Disposable parentDisposable) {
- myPropertyChangeMulticaster.addListener(listener,parentDisposable);
- }
- public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) {
- myPropertyChangeMulticaster.removeListener(listener);
- }
-
- @Override
- public void readExternal(Element element) throws InvalidDataException {
- List<TodoPattern> patternsList = new ArrayList<TodoPattern>();
- List<TodoFilter> filtersList = new ArrayList<TodoFilter>();
- for (Object o : element.getChildren()) {
- Element child = (Element)o;
- if (ELEMENT_PATTERN.equals(child.getName())) {
- TodoPattern pattern = new TodoPattern(TodoAttributesUtil.createDefault());
- pattern.readExternal(child, TodoAttributesUtil.getDefaultColorSchemeTextAttributes());
- patternsList.add(pattern);
- }
- else if (ELEMENT_FILTER.equals(child.getName())) {
- TodoPattern[] patterns = patternsList.toArray(new TodoPattern[patternsList.size()]);
- TodoFilter filter = new TodoFilter();
- filter.readExternal(child, patterns);
- filtersList.add(filter);
- }
- }
- doSetTodoPatterns(patternsList.toArray(new TodoPattern[patternsList.size()]), false);
- setTodoFilters(filtersList.toArray(new TodoFilter[filtersList.size()]));
- }
-
- @Override
- public void writeExternal(Element element) throws WriteExternalException {
- final TodoPattern[] todoPatterns = myTodoPatterns;
- for (TodoPattern pattern : todoPatterns) {
- Element child = new Element(ELEMENT_PATTERN);
- pattern.writeExternal(child);
- element.addContent(child);
- }
- for (TodoFilter filter : myTodoFilters) {
- Element child = new Element(ELEMENT_FILTER);
- filter.writeExternal(child, todoPatterns);
- element.addContent(child);
- }
- }
-
- public void colorSettingsChanged() {
- for (TodoPattern pattern : myTodoPatterns) {
- TodoAttributes attributes = pattern.getAttributes();
- if (!attributes.shouldUseCustomTodoColor()) {
- attributes.setUseCustomTodoColor(false, TodoAttributesUtil.getDefaultColorSchemeTextAttributes());
- }
- }
- }
-}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
index dde9d2a..8de17ab 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
@@ -508,7 +508,7 @@
@Nullable
protected PsiFile getPsiFile(final Project project) {
- return PsiDocumentManager.getInstance(project).getPsiFile(myEditor.getDocument());
+ return myEditor == null ? null : PsiDocumentManager.getInstance(project).getPsiFile(myEditor.getDocument());
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
index f4886f4..1970b47 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
@@ -798,18 +798,6 @@
String[] cached = getNamesSync(checkboxState);
if (cached != null) return cached;
- Window window = (Window)SwingUtilities.getAncestorOfClass(Window.class, myTextField);
- //LOG.assertTrue (myTextField != null);
- //LOG.assertTrue (window != null);
- Window ownerWindow = null;
- if (window != null) {
- window.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
- ownerWindow = window.getOwner();
- if (ownerWindow != null) {
- ownerWindow.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
- }
- }
-
if (checkboxState &&
myModel instanceof ContributorsBasedGotoByModel &&
((ContributorsBasedGotoByModel)myModel).sameNamesForProjectAndLibraries() &&
@@ -825,12 +813,6 @@
assert result != null : "Model "+myModel+ "("+myModel.getClass()+") returned null names";
setNamesSync(checkboxState, result);
- if (window != null) {
- window.setCursor(Cursor.getDefaultCursor());
- if (ownerWindow != null) {
- ownerWindow.setCursor(Cursor.getDefaultCursor());
- }
- }
return result;
}
@@ -898,15 +880,6 @@
cancelCalcElementsThread();
}
});
- ApplicationManager.getApplication().addApplicationListener(new ApplicationAdapter() {
- @Override
- public void beforeWriteActionStart(Object action) {
- CalcElementsThread prevThread = cancelCalcElementsThread();
- if (prevThread != null) {
- prevThread.scheduleRestart();
- }
- }
- }, myTextPopup);
myTextPopup.show(layeredPane);
}
@@ -1503,7 +1476,7 @@
private final Alarm myShowCardAlarm = new Alarm();
- void scheduleRestart() {
+ private void scheduleRestart() {
scheduleCalcElements(new CalcElementsThread(myPattern, myCheckboxState, myCallback, myModalityState, myCanCancel, myScopeExpanded));
}
@@ -1520,6 +1493,15 @@
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
+ ApplicationAdapter listener = new ApplicationAdapter() {
+ @Override
+ public void beforeWriteActionStart(Object action) {
+ cancel();
+ scheduleRestart();
+ ApplicationManager.getApplication().removeApplicationListener(this);
+ }
+ };
+ ApplicationManager.getApplication().addApplicationListener(listener);
try {
boolean everywhere = myCheckboxState;
if (!ourLoadNamesEachTime) ensureNamesLoaded(everywhere);
@@ -1528,6 +1510,9 @@
catch (ProcessCanceledException e) {
//OK
}
+ finally {
+ ApplicationManager.getApplication().removeApplicationListener(listener);
+ }
}
});
}
diff --git a/platform/lang-impl/src/com/intellij/lexer/PrefixSuffixStripperLexer.java b/platform/lang-impl/src/com/intellij/lexer/PrefixSuffixStripperLexer.java
index 2a52a07..8bf8d3c 100644
--- a/platform/lang-impl/src/com/intellij/lexer/PrefixSuffixStripperLexer.java
+++ b/platform/lang-impl/src/com/intellij/lexer/PrefixSuffixStripperLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
import com.intellij.psi.tree.IElementType;
import com.intellij.util.text.CharArrayUtil;
+import org.jetbrains.annotations.NotNull;
public class PrefixSuffixStripperLexer extends LexerBase {
private CharSequence myBuffer;
@@ -49,7 +50,7 @@
}
@Override
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
myBuffer = buffer;
myBufferArray = CharArrayUtil.fromSequenceWithoutCopying(buffer);
myTokenStart = startOffset;
@@ -87,6 +88,7 @@
return myBufferEnd;
}
+ @NotNull
@Override
public CharSequence getBufferSequence() {
return myBuffer;
diff --git a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java
index 75d9296..e353198 100644
--- a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java
+++ b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java
@@ -119,10 +119,8 @@
public void load(@NotNull final Element rootElement) throws IOException {
super.load(rootElement);
- final List attributes = rootElement.getAttributes();
- for (Object attribute : attributes) {
- final Attribute attr = (Attribute)attribute;
- myOptions.put(attr.getName(), attr.getValue());
+ for (Attribute attribute : rootElement.getAttributes()) {
+ myOptions.put(attribute.getName(), attribute.getValue());
}
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java b/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java
index 6ac59b2..37e7089 100644
--- a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java
@@ -154,7 +154,7 @@
@Override
public boolean isModified() {
if (!myManager.isIgnoredFilesListEqualToCurrent(myFileTypePanel.myIgnoreFilesField.getText())) return true;
- HashSet types = new HashSet(Arrays.asList(getModifiableFileTypes()));
+ HashSet<FileType> types = new HashSet<FileType>(Arrays.asList(getModifiableFileTypes()));
return !myTempPatternsTable.equals(myManager.getExtensionMap()) || !myTempFileTypes.equals(types) ||
!myOriginalToEditedMap.isEmpty() ||
!myTempTemplateDataLanguages.equals(TemplateDataLanguagePatterns.getInstance().getAssocTable());
diff --git a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/NativeFileIconProvider.java b/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/NativeFileIconProvider.java
deleted file mode 100644
index 9521bc7..0000000
--- a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/NativeFileIconProvider.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.intellij.openapi.fileTypes.impl;
-
-import com.intellij.ide.FileIconProvider;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.impl.ElementBase;
-import com.intellij.ui.DeferredIconImpl;
-import com.intellij.util.Function;
-import com.intellij.util.ui.update.ComparableObject;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import java.io.File;
-import java.util.*;
-
-/**
- * @author yole
- */
-public class NativeFileIconProvider implements FileIconProvider {
- private final Map<Ext, Icon> myIconCache = new HashMap<Ext, Icon>();
- // on Windows .exe and .ico files provide their own icons which can differ for each file, cache them by full file path
- private final Set<Ext> myCustomIconExtensions =
- SystemInfo.isWindows ? new HashSet<Ext>(Arrays.asList(new Ext("exe"), new Ext("ico"))) : new HashSet<Ext>();
- private final Map<String, Icon> myCustomIconCache = new HashMap<String, Icon>();
-
- private static final Ext NO_EXT = new Ext(null);
-
- private static final Ext CLOSED_DIR = new Ext(null, 0);
-
- @Override
- public Icon getIcon(@NotNull VirtualFile file, final int flags, @Nullable Project project) {
- if (!isNativeFileType(file)) return null;
-
- final Ext ext = getExtension(file, flags);
- final String filePath = file.getPath();
-
- Icon icon;
- synchronized (myIconCache) {
- if (!myCustomIconExtensions.contains(ext)) {
- icon = ext != null ? myIconCache.get(ext) : null;
- }
- else {
- icon = filePath != null ? myCustomIconCache.get(filePath) : null;
- }
- }
- if (icon != null) {
- return icon;
- }
- return new DeferredIconImpl<VirtualFile>(ElementBase.ICON_PLACEHOLDER.getValue(), file, false, new Function<VirtualFile, Icon>() {
- @Override
- public Icon fun(VirtualFile virtualFile) {
- final File f = new File(filePath);
- if (!f.exists()) {
- return null;
- }
- Icon icon;
- try { // VM will ensure lock to init -static final field--, note we should have no read access here, to avoid deadlock with EDT needed to init component
- assert SwingComponentHolder.ourFileChooser != null || !ApplicationManager.getApplication().isReadAccessAllowed();
- icon = getNativeIcon(f);
- }
- catch (Exception e) { // see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4854174
- return null;
- }
- if (ext != null) {
- synchronized (myIconCache) {
- if (!myCustomIconExtensions.contains(ext)) {
- myIconCache.put(ext, icon);
- }
- else if (filePath != null) {
- myCustomIconCache.put(filePath, icon);
- }
- }
- }
- return icon;
- }
- });
- }
-
- @Nullable
- public static Icon getNativeIcon(@Nullable File file) {
- return file == null ? null : SwingComponentHolder.ourFileChooser.getIcon(file);
- }
-
- private static Ext getExtension(final VirtualFile file, final int flags) {
- if (file.isDirectory()) {
- if (file.getExtension() == null) {
- return CLOSED_DIR;
- } else {
- return new Ext(file.getExtension(), flags);
- }
- }
-
- return file.getExtension() != null ? new Ext(file.getExtension()) : NO_EXT;
- }
-
- static class SwingComponentHolder {
- private static final JFileChooser ourFileChooser = new JFileChooser();
- }
-
- protected boolean isNativeFileType(VirtualFile file) {
- return ElementBase.isNativeFileType(file.getFileType());
- }
-
- private static class Ext extends ComparableObject.Impl {
- private final Object[] myText;
-
- private Ext(@Nullable String text) {
- myText = new Object[] {text};
- }
-
- private Ext(@Nullable String text, final int flags) {
- myText = new Object[] {text, flags};
- }
-
- @Override
- @NotNull
- public Object[] getEqualityObjects() {
- return myText;
- }
-
- @Override
- public String toString() {
- return myText[0] != null ? myText[0].toString() : null;
- }
- }
-}
diff --git a/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/ANSIColoredConsoleColorsPage.java b/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/ANSIColoredConsoleColorsPage.java
index af7e2b9..3b3ebf3 100644
--- a/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/ANSIColoredConsoleColorsPage.java
+++ b/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/ANSIColoredConsoleColorsPage.java
@@ -35,6 +35,7 @@
"<logExpired>An expired log entry</logExpired>\n" +
"\n" +
"# Process output highlighted using ANSI colors codes\n" +
+ "<black>ANSI: black</black>\n" +
"<red>ANSI: red</red>\n" +
"<green>ANSI: green</green>\n" +
"<yellow>ANSI: yellow</yellow>\n" +
@@ -42,6 +43,14 @@
"<magenta>ANSI: magenta</magenta>\n" +
"<cyan>ANSI: cyan</cyan>\n" +
"<gray>ANSI: gray</gray>\n" +
+ "<darkGray>ANSI: dark gray</darkGray>\n" +
+ "<redBright>ANSI: bright red</redBright>\n" +
+ "<greenBright>ANSI: bright green</greenBright>\n" +
+ "<yellowBright>ANSI: bright yellow</yellowBright>\n" +
+ "<blueBright>ANSI: bright blue</blueBright>\n" +
+ "<magentaBright>ANSI: bright magenta</magentaBright>\n" +
+ "<cyanBright>ANSI: bright cyan</cyanBright>\n" +
+ "<white>ANSI: white</white>\n" +
"\n" +
"<stdsys>Process finished with exit code 1</stdsys>\n";
@@ -55,6 +64,7 @@
new AttributesDescriptor(OptionsBundle.message("options.general.color.descriptor.console.warning"), ConsoleViewContentType.LOG_WARNING_OUTPUT_KEY),
new AttributesDescriptor(OptionsBundle.message("options.general.color.descriptor.console.expired"), ConsoleViewContentType.LOG_EXPIRED_ENTRY),
+ new AttributesDescriptor(OptionsBundle.message("color.settings.console.black"), ConsoleHighlighter.BLACK),
new AttributesDescriptor(OptionsBundle.message("color.settings.console.red"), ConsoleHighlighter.RED),
new AttributesDescriptor(OptionsBundle.message("color.settings.console.green"), ConsoleHighlighter.GREEN),
new AttributesDescriptor(OptionsBundle.message("color.settings.console.yellow"), ConsoleHighlighter.YELLOW),
@@ -62,6 +72,15 @@
new AttributesDescriptor(OptionsBundle.message("color.settings.console.magenta"), ConsoleHighlighter.MAGENTA),
new AttributesDescriptor(OptionsBundle.message("color.settings.console.cyan"), ConsoleHighlighter.CYAN),
new AttributesDescriptor(OptionsBundle.message("color.settings.console.gray"), ConsoleHighlighter.GRAY),
+
+ new AttributesDescriptor(OptionsBundle.message("color.settings.console.darkGray"), ConsoleHighlighter.DARKGRAY),
+ new AttributesDescriptor(OptionsBundle.message("color.settings.console.redBright"), ConsoleHighlighter.RED_BRIGHT),
+ new AttributesDescriptor(OptionsBundle.message("color.settings.console.greenBright"), ConsoleHighlighter.GREEN_BRIGHT),
+ new AttributesDescriptor(OptionsBundle.message("color.settings.console.yellowBright"), ConsoleHighlighter.YELLOW_BRIGHT),
+ new AttributesDescriptor(OptionsBundle.message("color.settings.console.blueBright"), ConsoleHighlighter.BLUE_BRIGHT),
+ new AttributesDescriptor(OptionsBundle.message("color.settings.console.magentaBright"), ConsoleHighlighter.MAGENTA_BRIGHT),
+ new AttributesDescriptor(OptionsBundle.message("color.settings.console.cyanBright"), ConsoleHighlighter.CYAN_BRIGHT),
+ new AttributesDescriptor(OptionsBundle.message("color.settings.console.white"), ConsoleHighlighter.WHITE),
};
private static final Map<String, TextAttributesKey> ADDITIONAL_HIGHLIGHT_DESCRIPTORS = new HashMap<String, TextAttributesKey>();
@@ -74,6 +93,7 @@
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("logWarning", ConsoleViewContentType.LOG_WARNING_OUTPUT_KEY);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("logExpired", ConsoleViewContentType.LOG_EXPIRED_ENTRY);
+ ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("black", ConsoleHighlighter.BLACK);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("red", ConsoleHighlighter.RED);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("green", ConsoleHighlighter.GREEN);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("yellow", ConsoleHighlighter.YELLOW);
@@ -81,6 +101,15 @@
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("magenta", ConsoleHighlighter.MAGENTA);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("cyan", ConsoleHighlighter.CYAN);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("gray", ConsoleHighlighter.GRAY);
+
+ ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("darkGray", ConsoleHighlighter.DARKGRAY);
+ ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("redBright", ConsoleHighlighter.RED_BRIGHT);
+ ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("greenBright", ConsoleHighlighter.GREEN_BRIGHT);
+ ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("yellowBright", ConsoleHighlighter.YELLOW_BRIGHT);
+ ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("blueBright", ConsoleHighlighter.BLUE_BRIGHT);
+ ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("magentaBright", ConsoleHighlighter.MAGENTA_BRIGHT);
+ ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("cyanBright", ConsoleHighlighter.CYAN_BRIGHT);
+ ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("white", ConsoleHighlighter.WHITE);
}
private static final ColorDescriptor[] COLORS = {
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/AttachRootButtonDescriptor.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/AttachRootButtonDescriptor.java
index 2b72f74..cad5f60 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/AttachRootButtonDescriptor.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/AttachRootButtonDescriptor.java
@@ -30,10 +30,25 @@
public abstract class AttachRootButtonDescriptor {
private final OrderRootType myOrderRootType;
protected final String myButtonText;
+ private final Icon myToolbarIcon;
+ /**
+ * Creates a descriptor for 'attach' button shown in popup when user click on '+' button.
+ * Consider using {@link #AttachRootButtonDescriptor(com.intellij.openapi.roots.OrderRootType, javax.swing.Icon, String)} instead.
+ */
protected AttachRootButtonDescriptor(@NotNull OrderRootType orderRootType, @NotNull String buttonText) {
myOrderRootType = orderRootType;
myButtonText = buttonText;
+ myToolbarIcon = null;
+ }
+
+ /**
+ * Creates a descriptor for 'attach' button shown in toolbar of a library editor
+ */
+ protected AttachRootButtonDescriptor(@NotNull OrderRootType orderRootType, @NotNull Icon toolbarIcon, @NotNull String description) {
+ myOrderRootType = orderRootType;
+ myButtonText = description;
+ myToolbarIcon = toolbarIcon;
}
public abstract VirtualFile[] selectFiles(@NotNull JComponent parent, @Nullable VirtualFile initialSelection,
@@ -55,4 +70,9 @@
public VirtualFile[] scanForActualRoots(@NotNull VirtualFile[] rootCandidates, JComponent parent) {
return rootCandidates;
}
+
+ @Nullable
+ public Icon getToolbarIcon() {
+ return myToolbarIcon;
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/LibraryRootsComponentDescriptor.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/LibraryRootsComponentDescriptor.java
index 5936a7d..fd75cc3 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/LibraryRootsComponentDescriptor.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/LibraryRootsComponentDescriptor.java
@@ -76,7 +76,7 @@
}
/**
- * @return descriptors for 'Attach' buttons in the library roots editor
+ * @return descriptors for additional 'Attach' buttons in the library roots editor
*/
@NotNull
public abstract List<? extends AttachRootButtonDescriptor> createAttachButtons();
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/RootDetectionUtil.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/RootDetectionUtil.java
index 620eb8c..d96b400 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/RootDetectionUtil.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/RootDetectionUtil.java
@@ -15,6 +15,8 @@
*/
package com.intellij.openapi.roots.libraries.ui.impl;
+import com.intellij.ide.util.ChooseElementsDialog;
+import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
@@ -26,13 +28,13 @@
import com.intellij.openapi.roots.libraries.ui.LibraryRootsComponentDescriptor;
import com.intellij.openapi.roots.libraries.ui.LibraryRootsDetector;
import com.intellij.openapi.roots.libraries.ui.OrderRoot;
-import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.ArrayUtil;
+import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.util.List;
@@ -116,12 +118,19 @@
}
}
LOG.assertTrue(!types.isEmpty(), "No allowed root types found for " + detector);
- List<String> sortedNames = new ArrayList<String>(types.keySet());
- Collections.sort(sortedNames, String.CASE_INSENSITIVE_ORDER);
- final int i = Messages.showChooseDialog("Choose category for selected files:", "Attach Files",
- ArrayUtil.toStringArray(sortedNames), sortedNames.get(0), null);
- if (i != -1) {
- final Pair<OrderRootType, Boolean> pair = types.get(sortedNames.get(i));
+ List<String> names = new ArrayList<String>(types.keySet());
+ String title = "Choose Categories of Selected Files";
+ String description = XmlStringUtil.wrapInHtml(ApplicationNamesInfo.getInstance().getProductName() + " cannot determine what kind of files the chosen items contain.<br>" +
+ "Choose the appropriate categories from the list.");
+ ChooseElementsDialog<String> dialog;
+ if (parentComponent != null) {
+ dialog = new ChooseRootTypeElementsDialog(parentComponent, names, title, description);
+ }
+ else {
+ dialog = new ChooseRootTypeElementsDialog(project, names, title, description);
+ }
+ for (String rootType : dialog.showAndGetResult()) {
+ final Pair<OrderRootType, Boolean> pair = types.get(rootType);
for (VirtualFile candidate : rootCandidates) {
result.add(new OrderRoot(candidate, pair.getFirst(), pair.getSecond()));
}
@@ -139,4 +148,25 @@
}
return true;
}
+
+ private static class ChooseRootTypeElementsDialog extends ChooseElementsDialog<String> {
+ public ChooseRootTypeElementsDialog(Project project, List<String> names, String title, String description) {
+ super(project, names, title, description, true);
+ }
+
+ private ChooseRootTypeElementsDialog(Component parent, List<String> names, String title, String description) {
+ super(parent, names, title, description, true);
+ }
+
+ @Override
+ protected String getItemText(String item) {
+ return item;
+ }
+
+ @Nullable
+ @Override
+ protected Icon getItemIcon(String item) {
+ return null;
+ }
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaSourceRootEditHandlerBase.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaSourceRootEditHandlerBase.java
index a2aa899..e17d4c5 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaSourceRootEditHandlerBase.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaSourceRootEditHandlerBase.java
@@ -22,7 +22,6 @@
import com.intellij.ui.roots.IconActionComponent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.jps.model.JpsElementFactory;
import org.jetbrains.jps.model.JpsSimpleElement;
import org.jetbrains.jps.model.java.JavaSourceRootProperties;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
@@ -38,12 +37,6 @@
super(rootType);
}
- @NotNull
- @Override
- public JpsSimpleElement<JavaSourceRootProperties> createDefaultProperties() {
- return JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties());
- }
-
@Nullable
@Override
public String getPropertiesString(@NotNull JpsSimpleElement<JavaSourceRootProperties> properties) {
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleSourceRootEditHandler.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleSourceRootEditHandler.java
index fae804f..069ca2d 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleSourceRootEditHandler.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleSourceRootEditHandler.java
@@ -83,9 +83,6 @@
@NotNull
public abstract String getUnmarkRootButtonText();
- @NotNull
- public abstract P createDefaultProperties();
-
@Nullable
public String getPropertiesString(@NotNull P properties) {
return null;
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java
index 9abe519..edb911b 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java
@@ -18,9 +18,9 @@
import com.intellij.ide.DeleteProvider;
import com.intellij.ide.TitledHandler;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.module.ModifiableModuleModel;
@@ -36,7 +36,6 @@
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.projectImport.ProjectAttachProcessor;
-import com.intellij.util.ArrayUtil;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.Function;
import com.intellij.util.PlatformUtils;
@@ -75,7 +74,8 @@
public void deleteElement(@NotNull DataContext dataContext) {
final Module[] modules = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext);
assert modules != null;
- final Project project = PlatformDataKeys.PROJECT.getData(dataContext);
+ final Project project = CommonDataKeys.PROJECT.getData(dataContext);
+ assert project != null;
String names = StringUtil.join(Arrays.asList(modules), new Function<Module, String>() {
@Override
public String fun(final Module module) {
@@ -115,7 +115,7 @@
private static String getConfirmationText(Module[] modules, String names) {
if (ProjectAttachProcessor.canAttachToProject()) {
- return "Would you like to detach the project" + (modules.length > 1 ? "s " : " ") + names + "?";
+ return ProjectBundle.message("project.remove.confirmation.prompt", names, modules.length);
}
return ProjectBundle.message("module.remove.confirmation.prompt", names, modules.length);
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java
index e7e68c3..62159b6 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java
@@ -66,7 +66,7 @@
final SourceFolder sourceFolder = contentEntryEditor.getSourceFolder(selectedFile);
if (isSelected) {
if (sourceFolder == null) { // not marked yet
- P properties = myEditHandler.createDefaultProperties();
+ P properties = myEditHandler.getRootType().createDefaultProperties();
contentEntryEditor.addSourceFolder(selectedFile, myEditHandler.getRootType(), properties);
}
else if (!myEditHandler.getRootType().equals(sourceFolder.getRootType())) {
@@ -75,7 +75,7 @@
properties = (P)((SourceFolderImpl)sourceFolder).getJpsElement().getProperties().getBulkModificationSupport().createCopy();
}
else {
- properties = myEditHandler.createDefaultProperties();
+ properties = myEditHandler.getRootType().createDefaultProperties();
}
contentEntryEditor.removeSourceFolder(sourceFolder);
contentEntryEditor.addSourceFolder(selectedFile, myEditHandler.getRootType(), properties);
diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java
index b0c22a6..5bf8b52 100644
--- a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java
+++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java
@@ -639,6 +639,10 @@
}
}
+ /**
+ * @return position <code>x</code> for which <code>myDocument.getText().substring(x, startOffset)</code> contains
+ * <code>blankLinesNumber</code> line feeds and <code>myDocument.getText.charAt(x-1) == '\n'</code>
+ */
private int getBlankLineOffset(int blankLinesNumber, int startOffset) {
int startLine = myDocument.getLineNumber(startOffset);
if (startLine <= 0) {
diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEntryWrapper.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEntryWrapper.java
index a801774..158c559 100644
--- a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEntryWrapper.java
+++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEntryWrapper.java
@@ -119,25 +119,17 @@
@SuppressWarnings("AssignmentToForLoopParameter")
public void updateBlankLines(@NotNull Document document) {
- int startLine = document.getLineNumber(getStartOffset());
myBlankLinesBefore = 0;
- if (startLine <= 0) {
- return;
- }
-
+ int lineFeeds = 0;
CharSequence text = document.getCharsSequence();
- int lastLineFeed = document.getLineStartOffset(startLine) - 1;
- for (int i = lastLineFeed - 1; i >= 0; i--) {
- i = CharArrayUtil.shiftBackward(text, i, " \t");
- if (text.charAt(i) == '\n') {
- ++myBlankLinesBefore;
- }
- else {
- break;
- }
+ for (int current = getStartOffset() - 1; current >= 0; current--) {
+ current = CharArrayUtil.shiftBackward(text, current, " \t");
+ if (text.charAt(current) == '\n') lineFeeds++;
+ else break;
}
+ if (lineFeeds > 0) myBlankLinesBefore = lineFeeds - 1;
}
-
+
public void setNext(@Nullable ArrangementEntryWrapper<E> next) {
myNext = next;
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java b/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java
deleted file mode 100644
index 15224f5..0000000
--- a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.psi.impl.cache.impl.id;
-
-import com.intellij.ide.highlighter.HighlighterFactory;
-import com.intellij.lang.Language;
-import com.intellij.lang.LanguageParserDefinitions;
-import com.intellij.lang.ParserDefinition;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter;
-import com.intellij.openapi.editor.highlighter.EditorHighlighter;
-import com.intellij.openapi.editor.highlighter.HighlighterIterator;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.FileTypes;
-import com.intellij.openapi.fileTypes.LanguageFileType;
-import com.intellij.openapi.fileTypes.StdFileTypes;
-import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.CustomHighlighterTokenType;
-import com.intellij.psi.impl.cache.impl.BaseFilterLexer;
-import com.intellij.psi.impl.cache.CacheUtil;
-import com.intellij.psi.impl.cache.impl.IndexPatternUtil;
-import com.intellij.psi.impl.cache.impl.OccurrenceConsumer;
-import com.intellij.psi.impl.cache.impl.todo.TodoIndexEntry;
-import com.intellij.psi.impl.cache.impl.todo.TodoIndexers;
-import com.intellij.psi.search.IndexPattern;
-import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.tree.TokenSet;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.indexing.DataIndexer;
-import com.intellij.util.indexing.FileBasedIndexImpl;
-import com.intellij.util.indexing.FileContent;
-import com.intellij.util.indexing.SubstitutedFileType;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Author: dmitrylomov
- */
-public abstract class PlatformIdTableBuilding {
- static final HashMap<FileType, DataIndexer<TodoIndexEntry, Integer, FileContent>> ourTodoIndexers =
- new HashMap<FileType, DataIndexer<TodoIndexEntry, Integer, FileContent>>();
- private static final TokenSet ABSTRACT_FILE_COMMENT_TOKENS =
- TokenSet.create(CustomHighlighterTokenType.LINE_COMMENT, CustomHighlighterTokenType.MULTI_LINE_COMMENT);
-
- private PlatformIdTableBuilding() {}
-
- @Nullable
- public static DataIndexer<TodoIndexEntry, Integer, FileContent> getTodoIndexer(FileType fileType, final VirtualFile virtualFile) {
- final DataIndexer<TodoIndexEntry, Integer, FileContent> indexer = ourTodoIndexers.get(fileType);
-
- if (indexer != null) {
- return indexer;
- }
-
- final DataIndexer<TodoIndexEntry, Integer, FileContent> extIndexer;
- if (fileType instanceof SubstitutedFileType && !((SubstitutedFileType)fileType).isSameFileType()) {
- SubstitutedFileType sft = (SubstitutedFileType)fileType;
- extIndexer =
- new CompositeTodoIndexer(getTodoIndexer(sft.getOriginalFileType(), virtualFile), getTodoIndexer(sft.getFileType(), virtualFile));
- }
- else {
- extIndexer = TodoIndexers.INSTANCE.forFileType(fileType);
- }
- if (extIndexer != null) {
- return extIndexer;
- }
-
- if (fileType instanceof LanguageFileType) {
- final Language lang = ((LanguageFileType)fileType).getLanguage();
- final ParserDefinition parserDef = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
- final TokenSet commentTokens = parserDef != null ? parserDef.getCommentTokens() : null;
- if (commentTokens != null) {
- return new TokenSetTodoIndexer(commentTokens, virtualFile);
- }
- }
-
- if (fileType instanceof CustomSyntaxTableFileType) {
- return new TokenSetTodoIndexer(ABSTRACT_FILE_COMMENT_TOKENS, virtualFile);
- }
-
- return null;
- }
-
- public static boolean checkCanUseCachedEditorHighlighter(final CharSequence chars, final EditorHighlighter editorHighlighter) {
- assert editorHighlighter instanceof LexerEditorHighlighter;
- final boolean b = ((LexerEditorHighlighter)editorHighlighter).checkContentIsEqualTo(chars);
- if (!b) {
- final Logger logger = Logger.getInstance(IdTableBuilding.class.getName());
- logger.warn("Unexpected mismatch of editor highlighter content with indexing content");
- }
- return b;
- }
-
- @Deprecated
- public static void registerTodoIndexer(FileType fileType, DataIndexer<TodoIndexEntry, Integer, FileContent> indexer) {
- ourTodoIndexers.put(fileType, indexer);
- }
-
- public static boolean isTodoIndexerRegistered(FileType fileType) {
- return ourTodoIndexers.containsKey(fileType) || TodoIndexers.INSTANCE.forFileType(fileType) != null;
- }
-
- private static class CompositeTodoIndexer implements DataIndexer<TodoIndexEntry, Integer, FileContent> {
-
- private final DataIndexer<TodoIndexEntry, Integer, FileContent>[] indexers;
-
- public CompositeTodoIndexer(DataIndexer<TodoIndexEntry, Integer, FileContent>... indexers) {
- this.indexers = indexers;
- }
-
- @NotNull
- @Override
- public Map<TodoIndexEntry, Integer> map(FileContent inputData) {
- Map<TodoIndexEntry, Integer> result = ContainerUtil.newTroveMap();
- for (DataIndexer<TodoIndexEntry, Integer, FileContent> indexer : indexers) {
- for (Map.Entry<TodoIndexEntry, Integer> entry : indexer.map(inputData).entrySet()) {
- TodoIndexEntry key = entry.getKey();
- if (result.containsKey(key)) {
- result.put(key, result.get(key) + entry.getValue());
- } else {
- result.put(key, entry.getValue());
- }
- }
- }
- return result;
- }
- }
-
- private static class TokenSetTodoIndexer implements DataIndexer<TodoIndexEntry, Integer, FileContent> {
- @NotNull private final TokenSet myCommentTokens;
- private final VirtualFile myFile;
-
- public TokenSetTodoIndexer(@NotNull final TokenSet commentTokens, @NotNull final VirtualFile file) {
- myCommentTokens = commentTokens;
- myFile = file;
- }
-
- @Override
- @NotNull
- public Map<TodoIndexEntry, Integer> map(final FileContent inputData) {
- if (IndexPatternUtil.getIndexPatternCount() > 0) {
- final CharSequence chars = inputData.getContentAsText();
- final OccurrenceConsumer occurrenceConsumer = new OccurrenceConsumer(null, true);
- EditorHighlighter highlighter;
-
- final EditorHighlighter editorHighlighter = inputData.getUserData(FileBasedIndexImpl.EDITOR_HIGHLIGHTER);
- if (editorHighlighter != null && checkCanUseCachedEditorHighlighter(chars, editorHighlighter)) {
- highlighter = editorHighlighter;
- }
- else {
- highlighter = HighlighterFactory.createHighlighter(null, myFile);
- highlighter.setText(chars);
- }
-
- final int documentLength = chars.length();
- BaseFilterLexer.TodoScanningData[] todoScanningDatas = null;
- final HighlighterIterator iterator = highlighter.createIterator(0);
-
- while (!iterator.atEnd()) {
- final IElementType token = iterator.getTokenType();
-
- if (myCommentTokens.contains(token) || CacheUtil.isInComments(token)) {
- int start = iterator.getStart();
- if (start >= documentLength) break;
- int end = iterator.getEnd();
-
- todoScanningDatas = BaseFilterLexer.advanceTodoItemsCount(
- chars.subSequence(start, Math.min(end, documentLength)),
- occurrenceConsumer,
- todoScanningDatas
- );
- if (end > documentLength) break;
- }
- iterator.advance();
- }
- final Map<TodoIndexEntry, Integer> map = new HashMap<TodoIndexEntry, Integer>();
- for (IndexPattern pattern : IndexPatternUtil.getIndexPatterns()) {
- final int count = occurrenceConsumer.getOccurrenceCount(pattern);
- if (count > 0) {
- map.put(new TodoIndexEntry(pattern.getPatternString(), pattern.isCaseSensitive()), count);
- }
- }
- return map;
- }
- return Collections.emptyMap();
- }
- }
-
- public static class PlainTextTodoIndexer implements DataIndexer<TodoIndexEntry, Integer, FileContent> {
- @Override
- @NotNull
- public Map<TodoIndexEntry, Integer> map(final FileContent inputData) {
- String chars = inputData.getContentAsText().toString(); // matching strings is faster than HeapCharBuffer
-
- final IndexPattern[] indexPatterns = IndexPatternUtil.getIndexPatterns();
- if (indexPatterns.length <= 0) {
- return Collections.emptyMap();
- }
- OccurrenceConsumer occurrenceConsumer = new OccurrenceConsumer(null, true);
- for (IndexPattern indexPattern : indexPatterns) {
- Pattern pattern = indexPattern.getPattern();
- if (pattern != null) {
- Matcher matcher = pattern.matcher(chars);
- while (matcher.find()) {
- if (matcher.start() != matcher.end()) {
- occurrenceConsumer.incTodoOccurrence(indexPattern);
- }
- }
- }
- }
- Map<TodoIndexEntry, Integer> map = new HashMap<TodoIndexEntry, Integer>();
- for (IndexPattern indexPattern : indexPatterns) {
- final int count = occurrenceConsumer.getOccurrenceCount(indexPattern);
- if (count > 0) {
- map.put(new TodoIndexEntry(indexPattern.getPatternString(), indexPattern.isCaseSensitive()), count);
- }
- }
- return map;
- }
-
- }
-
- static {
- IdTableBuilding.registerIdIndexer(FileTypes.PLAIN_TEXT, new IdTableBuilding.PlainTextIndexer());
- registerTodoIndexer(FileTypes.PLAIN_TEXT, new PlainTextTodoIndexer());
-
- IdTableBuilding.registerIdIndexer(StdFileTypes.IDEA_MODULE, null);
- IdTableBuilding.registerIdIndexer(StdFileTypes.IDEA_WORKSPACE, null);
- IdTableBuilding.registerIdIndexer(StdFileTypes.IDEA_PROJECT, null);
-
- registerTodoIndexer(StdFileTypes.IDEA_MODULE, null);
- registerTodoIndexer(StdFileTypes.IDEA_WORKSPACE, null);
- registerTodoIndexer(StdFileTypes.IDEA_PROJECT, null);
- }
-}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java b/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java
deleted file mode 100644
index 7ddbf02..0000000
--- a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.intellij.psi.impl.cache.impl.todo;
-
-import com.intellij.lang.Language;
-import com.intellij.lang.LanguageParserDefinitions;
-import com.intellij.lang.ParserDefinition;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.LanguageFileType;
-import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
-import com.intellij.openapi.project.ProjectCoreUtil;
-import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.impl.cache.impl.id.PlatformIdTableBuilding;
-import com.intellij.psi.search.IndexPatternProvider;
-import com.intellij.psi.tree.TokenSet;
-import com.intellij.util.indexing.*;
-import com.intellij.util.io.DataExternalizer;
-import com.intellij.util.io.KeyDescriptor;
-import com.intellij.util.messages.MessageBus;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * @author Eugene Zhuravlev
- * Date: Jan 20, 2008
- */
-public class TodoIndex extends FileBasedIndexExtension<TodoIndexEntry, Integer> {
- @NonNls public static final ID<TodoIndexEntry, Integer> NAME = ID.create("TodoIndex");
-
- public TodoIndex(MessageBus messageBus) {
- messageBus.connect().subscribe(IndexPatternProvider.INDEX_PATTERNS_CHANGED, new PropertyChangeListener() {
- @Override
- public void propertyChange(PropertyChangeEvent evt) {
- FileBasedIndex.getInstance().requestRebuild(NAME);
- }
- });
- }
-
- private final KeyDescriptor<TodoIndexEntry> myKeyDescriptor = new KeyDescriptor<TodoIndexEntry>() {
- @Override
- public int getHashCode(final TodoIndexEntry value) {
- return value.hashCode();
- }
-
- @Override
- public boolean isEqual(final TodoIndexEntry val1, final TodoIndexEntry val2) {
- return val1.equals(val2);
- }
-
- @Override
- public void save(final DataOutput out, final TodoIndexEntry value) throws IOException {
- out.writeUTF(value.pattern);
- out.writeBoolean(value.caseSensitive);
- }
-
- @Override
- public TodoIndexEntry read(final DataInput in) throws IOException {
- final String pattern = in.readUTF();
- final boolean caseSensitive = in.readBoolean();
- return new TodoIndexEntry(pattern, caseSensitive);
- }
- };
-
- private final DataExternalizer<Integer> myValueExternalizer = new DataExternalizer<Integer>() {
- @Override
- public void save(final DataOutput out, final Integer value) throws IOException {
- out.writeInt(value.intValue());
- }
-
- @Override
- public Integer read(final DataInput in) throws IOException {
- return Integer.valueOf(in.readInt());
- }
- };
-
- private final DataIndexer<TodoIndexEntry, Integer, FileContent> myIndexer = new DataIndexer<TodoIndexEntry, Integer, FileContent>() {
- @Override
- @NotNull
- public Map<TodoIndexEntry,Integer> map(final FileContent inputData) {
- final VirtualFile file = inputData.getFile();
- final DataIndexer<TodoIndexEntry, Integer, FileContent> indexer = PlatformIdTableBuilding
- .getTodoIndexer(inputData.getFileType(), file);
- if (indexer != null) {
- return indexer.map(inputData);
- }
- return Collections.emptyMap();
- }
- };
-
- private final FileBasedIndex.InputFilter myInputFilter = new FileBasedIndex.InputFilter() {
- @Override
- public boolean acceptInput(final VirtualFile file) {
- if (!(file.getFileSystem() instanceof LocalFileSystem)) {
- return false; // do not index TODOs in library sources
- }
-
- final FileType fileType = file.getFileType();
-
- if (fileType instanceof LanguageFileType) {
- final Language lang = ((LanguageFileType)fileType).getLanguage();
- final ParserDefinition parserDef = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
- final TokenSet commentTokens = parserDef != null ? parserDef.getCommentTokens() : null;
- return commentTokens != null;
- }
-
- return PlatformIdTableBuilding.isTodoIndexerRegistered(fileType) ||
- fileType instanceof CustomSyntaxTableFileType;
- }
- };
-
- @Override
- public int getVersion() {
- return 4;
- }
-
- @Override
- public boolean dependsOnFileContent() {
- return true;
- }
-
- @NotNull
- @Override
- public ID<TodoIndexEntry, Integer> getName() {
- return NAME;
- }
-
- @NotNull
- @Override
- public DataIndexer<TodoIndexEntry, Integer, FileContent> getIndexer() {
- return myIndexer;
- }
-
- @Override
- public KeyDescriptor<TodoIndexEntry> getKeyDescriptor() {
- return myKeyDescriptor;
- }
-
- @Override
- public DataExternalizer<Integer> getValueExternalizer() {
- return myValueExternalizer;
- }
-
- @Override
- public FileBasedIndex.InputFilter getInputFilter() {
- return myInputFilter;
- }
-}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternBuilder.java b/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternBuilder.java
deleted file mode 100644
index 65e8712..0000000
--- a/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternBuilder.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.intellij.psi.impl.search;
-
-import com.intellij.lexer.Lexer;
-import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.tree.TokenSet;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * @author yole
- */
-public interface IndexPatternBuilder {
- ExtensionPointName<IndexPatternBuilder> EP_NAME = ExtensionPointName.create("com.intellij.indexPatternBuilder");
-
- @Nullable
- Lexer getIndexingLexer(PsiFile file);
- @Nullable
- TokenSet getCommentTokenSet(PsiFile file);
- int getCommentStartDelta(IElementType tokenType);
- int getCommentEndDelta(IElementType tokenType);
-}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternSearcher.java b/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternSearcher.java
deleted file mode 100644
index 26004ca..0000000
--- a/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternSearcher.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.intellij.psi.impl.search;
-
-import com.intellij.lang.Language;
-import com.intellij.lang.LanguageParserDefinitions;
-import com.intellij.lang.ParserDefinition;
-import com.intellij.lexer.Lexer;
-import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.SyntaxHighlighter;
-import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
-import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
-import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
-import com.intellij.psi.impl.cache.TodoCacheManager;
-import com.intellij.psi.search.IndexPattern;
-import com.intellij.psi.search.IndexPatternOccurrence;
-import com.intellij.psi.search.IndexPatternProvider;
-import com.intellij.psi.search.searches.IndexPatternSearch;
-import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.tree.TokenSet;
-import com.intellij.util.Processor;
-import com.intellij.util.QueryExecutor;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.text.CharSequenceSubSequence;
-import gnu.trove.TIntArrayList;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * @author yole
- */
-public class IndexPatternSearcher implements QueryExecutor<IndexPatternOccurrence, IndexPatternSearch.SearchParameters> {
- @Override
- public boolean execute(@NotNull final IndexPatternSearch.SearchParameters queryParameters,
- @NotNull final Processor<IndexPatternOccurrence> consumer) {
- final PsiFile file = queryParameters.getFile();
- VirtualFile virtualFile = file.getVirtualFile();
- if (file instanceof PsiBinaryFile || file instanceof PsiCompiledElement || virtualFile == null) {
- return true;
- }
-
- final TodoCacheManager cacheManager = TodoCacheManager.SERVICE.getInstance(file.getProject());
- final IndexPatternProvider patternProvider = queryParameters.getPatternProvider();
- int count = patternProvider != null
- ? cacheManager.getTodoCount(virtualFile, patternProvider)
- : cacheManager.getTodoCount(virtualFile, queryParameters.getPattern());
- return count == 0 || executeImpl(queryParameters, consumer);
- }
-
- protected static boolean executeImpl(IndexPatternSearch.SearchParameters queryParameters,
- Processor<IndexPatternOccurrence> consumer) {
- final IndexPatternProvider patternProvider = queryParameters.getPatternProvider();
- final PsiFile file = queryParameters.getFile();
- TIntArrayList commentStarts = new TIntArrayList();
- TIntArrayList commentEnds = new TIntArrayList();
-
- final CharSequence chars = file.getViewProvider().getContents();
- findCommentTokenRanges(file, chars, queryParameters.getRange(), commentStarts, commentEnds);
-
- for (int i = 0; i < commentStarts.size(); i++) {
- int commentStart = commentStarts.get(i);
- int commentEnd = commentEnds.get(i);
-
- if (patternProvider != null) {
- for (final IndexPattern pattern : patternProvider.getIndexPatterns()) {
- if (!collectPatternMatches(pattern, chars, commentStart, commentEnd, file, queryParameters.getRange(), consumer)) {
- return false;
- }
- }
- }
- else {
- if (!collectPatternMatches(queryParameters.getPattern(), chars, commentStart, commentEnd, file, queryParameters.getRange(),
- consumer)) {
- return false;
- }
- }
- }
-
- return true;
- }
-
-
- private static final TokenSet COMMENT_TOKENS =
- TokenSet.create(CustomHighlighterTokenType.LINE_COMMENT, CustomHighlighterTokenType.MULTI_LINE_COMMENT);
-
- private static void findCommentTokenRanges(final PsiFile file,
- final CharSequence chars,
- final TextRange range,
- final TIntArrayList commentStarts,
- final TIntArrayList commentEnds) {
- if (file instanceof PsiPlainTextFile) {
- FileType fType = file.getFileType();
- if (fType instanceof CustomSyntaxTableFileType) {
- Lexer lexer = SyntaxHighlighterFactory.getSyntaxHighlighter(fType, file.getProject(), file.getVirtualFile()).getHighlightingLexer();
- findComments(lexer, chars, range, COMMENT_TOKENS, commentStarts, commentEnds, null);
- }
- else {
- commentStarts.add(0);
- commentEnds.add(file.getTextLength());
- }
- }
- else {
- final FileViewProvider viewProvider = file.getViewProvider();
- final Set<Language> relevantLanguages = viewProvider.getLanguages();
- for (Language lang : relevantLanguages) {
- final TIntArrayList commentStartsList = new TIntArrayList();
- final TIntArrayList commentEndsList = new TIntArrayList();
-
- final SyntaxHighlighter syntaxHighlighter =
- SyntaxHighlighterFactory.getSyntaxHighlighter(lang, file.getProject(), file.getVirtualFile());
- Lexer lexer = syntaxHighlighter.getHighlightingLexer();
- TokenSet commentTokens = null;
- IndexPatternBuilder builderForFile = null;
- for (IndexPatternBuilder builder : Extensions.getExtensions(IndexPatternBuilder.EP_NAME)) {
- Lexer lexerFromBuilder = builder.getIndexingLexer(file);
- if (lexerFromBuilder != null) {
- lexer = lexerFromBuilder;
- commentTokens = builder.getCommentTokenSet(file);
- builderForFile = builder;
- }
- }
- if (builderForFile == null) {
- final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
- if (parserDefinition != null) {
- commentTokens = parserDefinition.getCommentTokens();
- }
- }
-
- if (commentTokens != null) {
- findComments(lexer, chars, range, commentTokens, commentStartsList, commentEndsList, builderForFile);
- mergeCommentLists(commentStarts, commentEnds, commentStartsList, commentEndsList);
- }
- }
- }
- }
-
- private static void mergeCommentLists(TIntArrayList commentStarts,
- TIntArrayList commentEnds,
- TIntArrayList commentStartsList,
- TIntArrayList commentEndsList) {
- if (commentStarts.isEmpty() && commentEnds.isEmpty()) {
- commentStarts.add(commentStartsList.toNativeArray());
- commentEnds.add(commentEndsList.toNativeArray());
- return;
- }
-
- ContainerUtil.mergeSortedArrays(commentStarts, commentEnds, commentStartsList, commentEndsList);
- }
-
- private static void findComments(final Lexer lexer,
- final CharSequence chars,
- final TextRange range,
- final TokenSet commentTokens,
- final TIntArrayList commentStarts,
- final TIntArrayList commentEnds,
- final IndexPatternBuilder builderForFile) {
- for (lexer.start(chars); ; lexer.advance()) {
- IElementType tokenType = lexer.getTokenType();
- if (tokenType == null) break;
-
- if (range != null) {
- if (lexer.getTokenEnd() <= range.getStartOffset()) continue;
- if (lexer.getTokenStart() >= range.getEndOffset()) break;
- }
-
- boolean isComment = commentTokens.contains(tokenType);
- if (!isComment) {
- final Language commentLang = tokenType.getLanguage();
- final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(commentLang);
- if (parserDefinition != null) {
- final TokenSet langCommentTokens = parserDefinition.getCommentTokens();
- isComment = langCommentTokens.contains(tokenType);
- }
- }
-
- if (isComment) {
- final int startDelta = builderForFile != null ? builderForFile.getCommentStartDelta(lexer.getTokenType()) : 0;
- final int endDelta = builderForFile != null ? builderForFile.getCommentEndDelta(lexer.getTokenType()) : 0;
-
- int start = lexer.getTokenStart() + startDelta;
- int end = lexer.getTokenEnd() - endDelta;
- assert start <= end : "Invalid comment range: " +
- new TextRange(start, end) +
- "; lexer token range=" +
- new TextRange(lexer.getTokenStart(), lexer.getTokenEnd()) +
- "; delta=" +
- new TextRange(startDelta, endDelta) +
- "; lexer=" +
- lexer +
- "; builder=" +
- builderForFile +
- "; chars length:" +
- chars.length();
- assert end <= chars.length() : "Invalid comment end: " +
- new TextRange(start, end) +
- "; lexer token range=" +
- new TextRange(lexer.getTokenStart(), lexer.getTokenEnd()) +
- "; delta=" +
- new TextRange(startDelta, endDelta) +
- "; lexer=" +
- lexer +
- "; builder=" +
- builderForFile +
- "; chars length:" +
- chars.length();
- commentStarts.add(start);
- commentEnds.add(end);
- }
- }
- }
-
- private static boolean collectPatternMatches(IndexPattern indexPattern,
- CharSequence chars,
- int commentStart,
- int commentEnd,
- PsiFile file,
- TextRange range,
- Processor<IndexPatternOccurrence> consumer) {
- Pattern pattern = indexPattern.getPattern();
- if (pattern != null) {
- ProgressManager.checkCanceled();
-
- CharSequence input = new CharSequenceSubSequence(chars, commentStart, commentEnd);
- Matcher matcher = pattern.matcher(input);
- while (true) {
- //long time1 = System.currentTimeMillis();
- boolean found = matcher.find();
- //long time2 = System.currentTimeMillis();
- //System.out.println("scanned text of length " + (lexer.getTokenEnd() - lexer.getTokenStart() + " in " + (time2 - time1) + " ms"));
-
- if (!found) break;
- int start = matcher.start() + commentStart;
- int end = matcher.end() + commentStart;
- if (start != end) {
- if (range == null || range.getStartOffset() <= start && end <= range.getEndOffset()) {
- if (!consumer.process(new IndexPatternOccurrenceImpl(file, start, end, indexPattern))) {
- return false;
- }
- }
- }
-
- ProgressManager.checkCanceled();
- }
- }
- return true;
- }
-}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/TodoItemImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/search/TodoItemImpl.java
deleted file mode 100644
index 708a20f..0000000
--- a/platform/lang-impl/src/com/intellij/psi/impl/search/TodoItemImpl.java
+++ /dev/null
@@ -1,71 +0,0 @@
-
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.intellij.psi.impl.search;
-
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.search.TodoItem;
-import com.intellij.psi.search.TodoPattern;
-import org.jetbrains.annotations.NotNull;
-
-public class TodoItemImpl implements TodoItem {
- private final PsiFile myFile;
- private final int myStartOffset;
- private final int myEndOffset;
- private final TodoPattern myPattern;
-
- public TodoItemImpl(@NotNull PsiFile file, int startOffset, int endOffset, @NotNull TodoPattern pattern) {
- myFile = file;
- myStartOffset = startOffset;
- myEndOffset = endOffset;
- myPattern = pattern;
- }
-
- @NotNull
- @Override
- public PsiFile getFile() {
- return myFile;
- }
-
- @NotNull
- @Override
- public TextRange getTextRange() {
- return new TextRange(myStartOffset, myEndOffset);
- }
-
- @NotNull
- @Override
- public TodoPattern getPattern() {
- return myPattern;
- }
-
- public int hashCode(){
- return myFile.hashCode()+myStartOffset+myEndOffset+myPattern.hashCode();
- }
-
- public boolean equals(Object obj){
- if(!(obj instanceof TodoItemImpl)){
- return false;
- }
- TodoItemImpl todoItem=(TodoItemImpl)obj;
- return myFile.equals(todoItem.myFile) &&
- myStartOffset == todoItem.myStartOffset &&
- myEndOffset == todoItem.myEndOffset &&
- myPattern.equals(todoItem.myPattern);
- }
-}
\ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateBlackAndWhiteLexer.java b/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateBlackAndWhiteLexer.java
index 081e11e..c7d3dce 100644
--- a/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateBlackAndWhiteLexer.java
+++ b/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateBlackAndWhiteLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
import com.intellij.lexer.Lexer;
import com.intellij.lexer.LexerPosition;
import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class TemplateBlackAndWhiteLexer extends Lexer {
@@ -39,11 +40,12 @@
}
@Override
- public void start(final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
+ public void start(@NotNull final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
myBaseLexer.start(buffer, startOffset, endOffset, initialState);
setupTemplateToken();
}
+ @NotNull
@Override
public CharSequence getBufferSequence() {
return myBaseLexer.getBufferSequence();
@@ -139,13 +141,14 @@
}
}
+ @NotNull
@Override
public LexerPosition getCurrentPosition() {
return new Position(myTemplateLexer.getCurrentPosition(), myBaseLexer.getCurrentPosition());
}
@Override
- public void restore(LexerPosition position) {
+ public void restore(@NotNull LexerPosition position) {
final Position p = (Position)position;
myBaseLexer.restore(p.getBasePosition());
final LexerPosition templatePos = p.getTemplatePosition();
diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleDuplicatesFinder.java b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleDuplicatesFinder.java
index e87dc3c..6c067e5 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleDuplicatesFinder.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleDuplicatesFinder.java
@@ -13,6 +13,7 @@
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -23,10 +24,12 @@
private final ArrayList<PsiElement> myPattern;
private final Set<String> myParameters;
public static final Key<PsiElement> PARAMETER = Key.create("PARAMETER");
+ private final Collection<String> myOutputVariables;
public SimpleDuplicatesFinder(@NotNull final PsiElement statement1,
@NotNull final PsiElement statement2,
- AbstractVariableData[] variableData) {
+ AbstractVariableData[] variableData, Collection<String> variables) {
+ myOutputVariables = variables;
myParameters = new HashSet<String>();
for (AbstractVariableData data : variableData) {
myParameters.add(data.getOriginalName());
@@ -117,13 +120,17 @@
return match;
}
- private static boolean matchPattern(@Nullable final PsiElement pattern,
+ private boolean matchPattern(@Nullable final PsiElement pattern,
@Nullable final PsiElement candidate,
@NotNull final SimpleMatch match) {
ProgressManager.checkCanceled();
if (pattern == null || candidate == null) return pattern == candidate;
final PsiElement[] children1 = PsiEquivalenceUtil.getFilteredChildren(pattern, null, true);
final PsiElement[] children2 = PsiEquivalenceUtil.getFilteredChildren(candidate, null, true);
+ if (pattern.getUserData(PARAMETER) != null && pattern.getParent().getClass() == candidate.getParent().getClass()) {
+ match.changeParameter(pattern.getText(), candidate.getText());
+ return true;
+ }
if (children1.length != children2.length) return false;
for (int i = 0; i < children1.length; i++) {
@@ -137,7 +144,13 @@
match.changeParameter(pattern.getText(), candidate.getText());
return true;
}
- if (!pattern.textMatches(candidate)) return false;
+ if (myOutputVariables.contains(pattern.getText())) {
+ match.changeOutput(candidate.getText());
+ return true;
+ }
+ if (!pattern.textMatches(candidate)) {
+ return false;
+ }
}
return true;
diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleMatch.java b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleMatch.java
index c1e967e9..623af56 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleMatch.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleMatch.java
@@ -13,6 +13,8 @@
PsiElement myStartElement;
PsiElement myEndElement;
private final Map<String, String> myChangedParameters;
+ private String myChangedOutput;
+
public SimpleMatch(@NotNull final PsiElement start, @NotNull final PsiElement endElement) {
myStartElement = start;
myEndElement = endElement;
@@ -34,4 +36,13 @@
public void changeParameter(@NotNull final String from, @NotNull final String to) {
myChangedParameters.put(from, to);
}
+
+ public void changeOutput(@NotNull final String to) {
+ myChangedOutput = to;
+ }
+
+ public String getChangedOutput() {
+ return myChangedOutput;
+ }
+
}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialogBase.java b/platform/lang-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialogBase.java
new file mode 100644
index 0000000..e923abb
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialogBase.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring.memberPullUp;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.classMembers.AbstractMemberInfoStorage;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+import com.intellij.refactoring.classMembers.MemberInfoChange;
+import com.intellij.refactoring.classMembers.MemberInfoModel;
+import com.intellij.refactoring.ui.AbstractMemberSelectionTable;
+import com.intellij.refactoring.ui.MemberSelectionPanelBase;
+import com.intellij.refactoring.ui.RefactoringDialog;
+import com.intellij.usageView.UsageViewUtil;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Max Medvedev
+ */
+public abstract class PullUpDialogBase<Storage extends AbstractMemberInfoStorage<Member, Class, MemberInfo>,
+ MemberInfo extends MemberInfoBase<Member>,
+ Member extends PsiElement,
+ Class extends PsiElement> extends RefactoringDialog {
+ protected MemberSelectionPanelBase<Member, MemberInfo, AbstractMemberSelectionTable<Member, MemberInfo>> myMemberSelectionPanel;
+ protected MemberInfoModel<Member, MemberInfo> myMemberInfoModel;
+ protected final Class myClass;
+ protected final List<Class> mySuperClasses;
+ protected final Storage myMemberInfoStorage;
+ protected List<MemberInfo> myMemberInfos;
+ private JComboBox myClassCombo;
+
+ public PullUpDialogBase(Project project, Class aClass, List<Class> superClasses, Storage memberInfoStorage, String title) {
+ super(project, true);
+ myClass = aClass;
+ mySuperClasses = superClasses;
+ myMemberInfoStorage = memberInfoStorage;
+ myMemberInfos = myMemberInfoStorage.getClassMemberInfos(aClass);
+
+ setTitle(title);
+ }
+
+ @Nullable
+ public Class getSuperClass() {
+ if (myClassCombo != null) {
+ return (Class) myClassCombo.getSelectedItem();
+ }
+ else {
+ return null;
+ }
+ }
+
+ public List<MemberInfo> getSelectedMemberInfos() {
+ ArrayList<MemberInfo> list = new ArrayList<MemberInfo>(myMemberInfos.size());
+ for (MemberInfo info : myMemberInfos) {
+ if (info.isChecked() && myMemberInfoModel.isMemberEnabled(info)) {
+ list.add(info);
+ }
+ }
+ return list;
+ }
+
+ protected JComponent createNorthPanel() {
+ JPanel panel = new JPanel();
+
+ panel.setLayout(new GridBagLayout());
+ GridBagConstraints gbConstraints = new GridBagConstraints();
+
+ gbConstraints.insets = new Insets(4, 0, 4, 8);
+ gbConstraints.weighty = 1;
+ gbConstraints.weightx = 1;
+ gbConstraints.gridy = 0;
+ gbConstraints.gridwidth = GridBagConstraints.REMAINDER;
+ gbConstraints.fill = GridBagConstraints.BOTH;
+ gbConstraints.anchor = GridBagConstraints.WEST;
+ final JLabel classComboLabel = new JLabel();
+ panel.add(classComboLabel, gbConstraints);
+
+ myClassCombo = new JComboBox(mySuperClasses.toArray());
+ initClassCombo(myClassCombo);
+ classComboLabel.setText(RefactoringBundle.message("pull.up.members.to", UsageViewUtil.getLongName(myClass)));
+ classComboLabel.setLabelFor(myClassCombo);
+ final Class preselection = getPreselection();
+ int indexToSelect = 0;
+ if (preselection != null) {
+ indexToSelect = mySuperClasses.indexOf(preselection);
+ }
+ myClassCombo.setSelectedIndex(indexToSelect);
+ myClassCombo.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ if (e.getStateChange() == ItemEvent.SELECTED) {
+ updateMemberInfo();
+ }
+ }
+ });
+ gbConstraints.gridy++;
+ panel.add(myClassCombo, gbConstraints);
+
+ return panel;
+ }
+
+ protected abstract void initClassCombo(JComboBox classCombo);
+
+ protected abstract Class getPreselection();
+
+ private void updateMemberInfo() {
+ final Class targetClass = (Class) myClassCombo.getSelectedItem();
+ myMemberInfos = myMemberInfoStorage.getIntermediateMemberInfosList(targetClass);
+ }
+
+ protected JComponent createCenterPanel() {
+ JPanel panel = new JPanel(new BorderLayout());
+ myMemberSelectionPanel = new MemberSelectionPanelBase<Member, MemberInfo, AbstractMemberSelectionTable<Member, MemberInfo>>(RefactoringBundle.message("members.to.be.pulled.up"), createMemberSelectionTable(myMemberInfos));
+ myMemberInfoModel = createMemberInfoModel();
+ myMemberInfoModel.memberInfoChanged(new MemberInfoChange<Member, MemberInfo>(myMemberInfos));
+ myMemberSelectionPanel.getTable().setMemberInfoModel(myMemberInfoModel);
+ myMemberSelectionPanel.getTable().addMemberInfoChangeListener(myMemberInfoModel);
+ panel.add(myMemberSelectionPanel, BorderLayout.CENTER);
+
+ addCustomElementsToCentralPanel(panel);
+
+ return panel;
+ }
+
+ protected void addCustomElementsToCentralPanel(JPanel panel) { }
+
+ protected abstract AbstractMemberSelectionTable<Member,MemberInfo> createMemberSelectionTable(List<MemberInfo> infos);
+
+ protected abstract MemberInfoModel<Member, MemberInfo> createMemberInfoModel();
+}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionPanel.java b/platform/lang-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionPanel.java
new file mode 100644
index 0000000..af9b30d
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionPanel.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring.ui;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+
+import javax.swing.*;
+
+/**
+ * Nikolay.Tropin
+ * 8/20/13
+ */
+public abstract class AbstractMemberSelectionPanel<T extends PsiElement, M extends MemberInfoBase<T>> extends JPanel {
+ public abstract AbstractMemberSelectionTable<T, M> getTable();
+}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/ui/MemberSelectionPanelBase.java b/platform/lang-impl/src/com/intellij/refactoring/ui/MemberSelectionPanelBase.java
new file mode 100644
index 0000000..4ac3c97
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/refactoring/ui/MemberSelectionPanelBase.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring.ui;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+import com.intellij.ui.ScrollPaneFactory;
+import com.intellij.ui.SeparatorFactory;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author Max Medvedev
+ */
+public class MemberSelectionPanelBase<Member extends PsiElement,
+ MemberInfo extends MemberInfoBase<Member>,
+ Table extends AbstractMemberSelectionTable<Member, MemberInfo>> extends AbstractMemberSelectionPanel<Member, MemberInfo> {
+ private final Table myTable;
+
+ /**
+ * @param title if title contains 'm' - it would look and feel as mnemonic
+ */
+ public MemberSelectionPanelBase(String title, Table table) {
+ super();
+ setLayout(new BorderLayout());
+
+ myTable = table;
+ JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable);
+ add(SeparatorFactory.createSeparator(title, myTable), BorderLayout.NORTH);
+ add(scrollPane, BorderLayout.CENTER);
+ }
+
+ public Table getTable() {
+ return myTable;
+ }
+}
+
diff --git a/platform/lang-impl/src/com/intellij/tools/Tool.java b/platform/lang-impl/src/com/intellij/tools/Tool.java
index ab59802..23f4d78 100644
--- a/platform/lang-impl/src/com/intellij/tools/Tool.java
+++ b/platform/lang-impl/src/com/intellij/tools/Tool.java
@@ -19,6 +19,7 @@
import com.intellij.execution.ExecutionException;
import com.intellij.execution.RunnerRegistry;
import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.execution.configurations.PathEnvironmentVariableUtil;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.process.ProcessHandler;
@@ -341,6 +342,7 @@
commandLine.getParametersList().prependAll("-a", exePath);
}
else {
+ exePath = PathEnvironmentVariableUtil.findAbsolutePathOnMac(exePath);
commandLine.setExePath(exePath);
}
}
diff --git a/platform/lang-impl/src/com/intellij/ui/popup/PopupPositionManager.java b/platform/lang-impl/src/com/intellij/ui/popup/PopupPositionManager.java
index f2e23ea..f9a43f9 100644
--- a/platform/lang-impl/src/com/intellij/ui/popup/PopupPositionManager.java
+++ b/platform/lang-impl/src/com/intellij/ui/popup/PopupPositionManager.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.ui.popup;
import com.intellij.codeInsight.lookup.LookupAdapter;
@@ -18,16 +33,22 @@
import javax.swing.*;
import java.awt.*;
-import java.util.*;
-import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
/**
* @author pegov
+ * @author Konstantin Bulenkov
*/
public class PopupPositionManager {
private PopupPositionManager() {
}
+ public enum Position {
+ TOP, BOTTOM, LEFT, RIGHT
+ }
+
public static void positionPopupInBestPosition(final JBPopup hint,
@Nullable final Editor editor,
@Nullable DataContext dataContext) {
@@ -113,7 +134,7 @@
}
}
- private static class PositionAdjuster {
+ public static class PositionAdjuster {
private static final int GAP = 5;
private final Component myRelativeTo;
@@ -157,32 +178,25 @@
* @param popup
*/
public void adjust(final JBPopup popup) {
+ adjust(popup, Position.RIGHT, Position.LEFT, Position.TOP, Position.BOTTOM);
+ }
+
+ public void adjust(final JBPopup popup, Position... traversalPolicy) {
final Dimension d = getPopupSize(popup);
Rectangle popupRect = null;
- Rectangle r = positionRight(d);
- if (myScreenRect.contains(r)) {
- popupRect = r;
- }
+ Rectangle r = null;
- if (popupRect == null) {
- r = positionLeft(d);
- if (myScreenRect.contains(r)) {
- popupRect = r;
+ for (Position position : traversalPolicy) {
+ switch (position) {
+ case TOP: r = positionAbove(d); break;
+ case BOTTOM: r = positionUnder(d); break;
+ case LEFT: r = positionLeft(d); break;
+ case RIGHT: r = positionRight(d); break;
}
- }
-
- if (popupRect == null) {
- r = positionAbove(d);
if (myScreenRect.contains(r)) {
popupRect = r;
- }
- }
-
- if (popupRect == null) {
- r = positionUnder(d);
- if (myScreenRect.contains(r)) {
- popupRect = r;
+ break;
}
}
@@ -197,7 +211,7 @@
}
else {
// ok, popup does not fit, will try to resize it
- final List<Rectangle> boxes = new ArrayList<Rectangle>();
+ final java.util.List<Rectangle> boxes = new ArrayList<Rectangle>();
// right
boxes.add(crop(myScreenRect, new Rectangle(myRelativeOnScreen.x + myRelativeTo.getWidth() + GAP, myRelativeOnScreen.y,
myScreenRect.width, myScreenRect.height)));
diff --git a/platform/lang-impl/src/com/intellij/ui/popup/util/DetailController.java b/platform/lang-impl/src/com/intellij/ui/popup/util/DetailController.java
index 235bda0..d8325bb 100644
--- a/platform/lang-impl/src/com/intellij/ui/popup/util/DetailController.java
+++ b/platform/lang-impl/src/com/intellij/ui/popup/util/DetailController.java
@@ -19,16 +19,13 @@
import com.intellij.util.Alarm;
import javax.swing.*;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-import javax.swing.event.TreeSelectionEvent;
-import javax.swing.event.TreeSelectionListener;
import java.io.File;
-public class DetailController implements TreeSelectionListener, ListSelectionListener {
+public class DetailController {
private final MasterController myMasterController;
private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
private DetailView myDetailView;
+ private ItemWrapper mySelectedItem;
public DetailController(MasterController myMasterController) {
this.myMasterController = myMasterController;
@@ -61,7 +58,11 @@
return myMasterController.getPathLabel();
}
- void doUpdateDetailView() {
+ public ItemWrapper getSelectedItem() {
+ return mySelectedItem;
+ }
+
+ public void doUpdateDetailView(boolean now) {
final Object[] values = myMasterController.getSelectedItems();
ItemWrapper wrapper = null;
if (values != null && values.length == 1) {
@@ -71,35 +72,30 @@
else {
getLabel().setText(" ");
}
- final ItemWrapper wrapper1 = wrapper;
+ mySelectedItem = wrapper;
myUpdateAlarm.cancelAllRequests();
- myUpdateAlarm.addRequest(new Runnable() {
- @Override
- public void run() {
- doUpdateDetailViewWithItem(wrapper1);
- }
- }, 100);
+ if (now) {
+ doUpdateDetailViewWithItem(mySelectedItem);
+ }
+ else {
+ myUpdateAlarm.addRequest(new Runnable() {
+ @Override
+ public void run() {
+ doUpdateDetailViewWithItem(mySelectedItem);
+ myUpdateAlarm.cancelAllRequests();
+ }
+ }, 100);
+ }
}
- public void selectionChanged() {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- doUpdateDetailView();
- }
- });
- }
-
- public void setTree(final JTree tree) {
- tree.getSelectionModel().addTreeSelectionListener(this);
+ public void updateDetailView() {
+ doUpdateDetailView(false);
}
public void setList(final JBList list) {
final ListSelectionModel listSelectionModel = list.getSelectionModel();
listSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
- listSelectionModel.addListSelectionListener(this);
-
if (list.getModel().getSize() == 0) {
list.clearSelection();
}
@@ -108,14 +104,4 @@
public void setDetailView(DetailView detailView) {
myDetailView = detailView;
}
-
- @Override
- public void valueChanged(TreeSelectionEvent event) {
- selectionChanged();
- }
-
- @Override
- public void valueChanged(ListSelectionEvent event) {
- selectionChanged();
- }
}
\ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java b/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java
index 8cd75d8..c3f71bd 100644
--- a/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java
+++ b/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java
@@ -30,6 +30,8 @@
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.*;
@@ -348,15 +350,15 @@
return this;
}
- public MasterDetailPopupBuilder setTree(final JTree tree) {
- setChooser(tree);
- myDetailController.setTree(tree);
- return this;
- }
-
public MasterDetailPopupBuilder setList(final JBList list) {
setChooser(list);
myDetailController.setList(list);
+ list.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+ @Override
+ public void valueChanged(ListSelectionEvent event) {
+ myDetailController.updateDetailView();
+ }
+ });
return this;
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
index eb1a7e8..436fdb9 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
@@ -30,7 +30,6 @@
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.impl.EditorHighlighterCache;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -57,6 +56,7 @@
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiDocumentTransactionListener;
+import com.intellij.psi.impl.cache.impl.id.PlatformIdTableBuilding;
import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.psi.search.EverythingGlobalScope;
import com.intellij.psi.search.GlobalSearchScope;
@@ -1551,7 +1551,7 @@
initFileContent(newFc, project, dominantContentFile);
if (content instanceof AuthenticContent) {
- newFc.putUserData(EDITOR_HIGHLIGHTER, EditorHighlighterCache.getEditorHighlighterForCachesBuilding(document));
+ newFc.putUserData(PlatformIdTableBuilding.EDITOR_HIGHLIGHTER, EditorHighlighterCache.getEditorHighlighterForCachesBuilding(document));
}
final int inputId = Math.abs(getFileId(vFile));
@@ -1571,8 +1571,6 @@
private final TaskQueue myContentlessIndicesUpdateQueue = new TaskQueue(10000);
- public static final Key<EditorHighlighter> EDITOR_HIGHLIGHTER = new Key<EditorHighlighter>("Editor");
-
@Nullable
private PsiFile findDominantPsiForDocument(@NotNull Document document, @Nullable Project project) {
synchronized (myTransactionMap) {
diff --git a/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java b/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java
index 7ad2905..7e879f4 100644
--- a/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java
+++ b/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java
@@ -71,7 +71,7 @@
* @param fileBaseName file base name
* @return {@code File} instance or null if not found
*/
- public static File findInOriginalPath(@NotNull String fileBaseName) {
+ private static File findInOriginalPath(@NotNull String fileBaseName) {
String originalPath;
if (SystemInfo.isMac) {
originalPath = System.getenv(PATH_ENV_VAR_NAME);
@@ -135,4 +135,30 @@
}
return result;
}
+
+ /**
+ * Finds the absolute path of an executable file in PATH by the given relative path.
+ * This method makes sense for Mac only, because other OSs pass correct environment variables to IDE process
+ * letting {@link ProcessBuilder#start} sees correct PATH environment variable.
+ *
+ * @param exePath String relative path (or just a base name)
+ * @return the absolute path if the executable file found, and the given {@code exePath} otherwise
+ */
+ @NotNull
+ public static String findAbsolutePathOnMac(@NotNull String exePath) {
+ if (SystemInfo.isMac) {
+ if (!exePath.contains(File.separator)) {
+ File originalResolvedExeFile = findInOriginalPath(exePath);
+ // don't modify exePath if the absolute path can be found in the original PATH
+ if (originalResolvedExeFile == null) {
+ File resolvedExeFile = findInPath(exePath);
+ if (resolvedExeFile != null) {
+ exePath = resolvedExeFile.getAbsolutePath();
+ }
+ }
+ }
+ }
+ return exePath;
+ }
+
}
diff --git a/platform/platform-api/src/com/intellij/execution/process/ColoredOutputTypeRegistry.java b/platform/platform-api/src/com/intellij/execution/process/ColoredOutputTypeRegistry.java
index 85eea8a..7fff038 100644
--- a/platform/platform-api/src/com/intellij/execution/process/ColoredOutputTypeRegistry.java
+++ b/platform/platform-api/src/com/intellij/execution/process/ColoredOutputTypeRegistry.java
@@ -7,7 +7,6 @@
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.Key;
-import com.intellij.ui.JBColor;
import org.jetbrains.annotations.NonNls;
import java.awt.*;
@@ -24,10 +23,24 @@
private final Map<String, Key> myRegisteredKeys = new HashMap<String, Key>();
- private final TextAttributesKey[] myAnsiColorKeys = new TextAttributesKey[] {
- ConsoleViewContentType.NORMAL_OUTPUT_KEY,
- ConsoleHighlighter.RED, ConsoleHighlighter.GREEN, ConsoleHighlighter.YELLOW, ConsoleHighlighter.BLUE,
- ConsoleHighlighter.MAGENTA, ConsoleHighlighter.CYAN
+ private static final TextAttributesKey[] myAnsiColorKeys = new TextAttributesKey[]{
+ ConsoleHighlighter.BLACK,
+ ConsoleHighlighter.RED,
+ ConsoleHighlighter.GREEN,
+ ConsoleHighlighter.YELLOW,
+ ConsoleHighlighter.BLUE,
+ ConsoleHighlighter.MAGENTA,
+ ConsoleHighlighter.CYAN,
+ ConsoleHighlighter.GRAY,
+
+ ConsoleHighlighter.DARKGRAY,
+ ConsoleHighlighter.RED_BRIGHT,
+ ConsoleHighlighter.GREEN_BRIGHT,
+ ConsoleHighlighter.YELLOW_BRIGHT,
+ ConsoleHighlighter.BLUE_BRIGHT,
+ ConsoleHighlighter.MAGENTA_BRIGHT,
+ ConsoleHighlighter.CYAN_BRIGHT,
+ ConsoleHighlighter.WHITE,
};
/*
@@ -73,7 +86,7 @@
attribute = attribute.substring(1);
}
if (attribute.endsWith("m")) {
- attribute = attribute.substring(0, attribute.length()-1);
+ attribute = attribute.substring(0, attribute.length() - 1);
}
if (attribute.equals("0")) {
return ProcessOutputTypes.STDOUT;
@@ -88,25 +101,43 @@
catch (NumberFormatException e) {
continue;
}
- if (value == 4) {
+ if (value == 1) {
+ attrs.setFontType(Font.BOLD);
+ }
+ else if (value == 4) {
attrs.setEffectType(EffectType.LINE_UNDERSCORE);
}
- else if (value == 1) {
- attrs.setFontType(Font.BOLD);
+ else if (value == 22) {
+ attrs.setFontType(Font.PLAIN);
+ }
+ else if (value == 24) { //not underlined
+ attrs.setEffectType(null);
}
else if (value >= 30 && value <= 37) {
attrs.setForegroundColor(getAnsiColor(value - 30));
}
+ else if (value == 38) {
+ //TODO: 256 colors foreground
+ }
+ else if (value == 39) {
+ attrs.setForegroundColor(getColorByKey(ConsoleViewContentType.NORMAL_OUTPUT_KEY));
+ }
else if (value >= 40 && value <= 47) {
attrs.setBackgroundColor(getAnsiColor(value - 40));
}
- else if (value == 90) {
- // black, high intensity
- attrs.setForegroundColor(EditorColorsManager.getInstance().getGlobalScheme().getAttributes(ConsoleHighlighter.GRAY).getForegroundColor());
+ else if (value == 48) {
+ //TODO: 256 colors background
}
- else if (value >= 91 && value < 96) {
- // TODO separate colors for high intensity?
- attrs.setForegroundColor(EditorColorsManager.getInstance().getGlobalScheme().getAttributes(myAnsiColorKeys [value-90]).getForegroundColor());
+ else if (value == 49) {
+ attrs.setBackgroundColor(getColorByKey(ConsoleViewContentType.NORMAL_OUTPUT_KEY));
+ }
+ else if (value >= 90 && value <= 97) {
+ attrs.setForegroundColor(
+ getAnsiColor(value - 82));
+ }
+ else if (value >= 100 && value <= 107) {
+ attrs.setBackgroundColor(
+ getAnsiColor(value - 92));
}
}
if (attrs.getEffectType() == EffectType.LINE_UNDERSCORE) {
@@ -119,10 +150,18 @@
return newKey;
}
- private Color getAnsiColor(final int value) {
- if (value == 7) {
- return JBColor.WHITE;
+ private static Color getAnsiColor(final int value) {
+ return getColorByKey(getAnsiColorKey(value));
+ }
+
+ private static Color getColorByKey(TextAttributesKey colorKey) {
+ return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(colorKey).getForegroundColor();
+ }
+
+ public static TextAttributesKey getAnsiColorKey(int value) {
+ if (value >= 16) {
+ return ConsoleViewContentType.NORMAL_OUTPUT_KEY;
}
- return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(myAnsiColorKeys[value]).getForegroundColor();
+ return myAnsiColorKeys[value];
}
}
diff --git a/platform/platform-api/src/com/intellij/execution/process/ConsoleHighlighter.java b/platform/platform-api/src/com/intellij/execution/process/ConsoleHighlighter.java
index 9f32da4..014e218 100644
--- a/platform/platform-api/src/com/intellij/execution/process/ConsoleHighlighter.java
+++ b/platform/platform-api/src/com/intellij/execution/process/ConsoleHighlighter.java
@@ -15,52 +15,64 @@
*/
package com.intellij.execution.process;
-import com.intellij.openapi.editor.HighlighterColors;
+import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.editor.colors.TextAttributesKey;
-import com.intellij.openapi.editor.markup.TextAttributes;
-import com.intellij.ui.JBColor;
-import com.intellij.util.ui.PlatformColors;
import org.jetbrains.annotations.NonNls;
-import java.awt.*;
-
/**
* @author oleg
*/
public class ConsoleHighlighter {
+ @NonNls static final String BLACK_ID = "CONSOLE_BLACK_OUTPUT";
@NonNls static final String RED_ID = "CONSOLE_RED_OUTPUT";
@NonNls static final String GREEN_ID = "CONSOLE_GREEN_OUTPUT";
@NonNls static final String YELLOW_ID = "CONSOLE_YELLOW_OUTPUT";
@NonNls static final String BLUE_ID = "CONSOLE_BLUE_OUTPUT";
@NonNls static final String MAGENTA_ID = "CONSOLE_MAGENTA_OUTPUT";
@NonNls static final String CYAN_ID = "CONSOLE_CYAN_OUTPUT";
- @NonNls static final String GRAY_ID = "CONSOLE_GRAY_OUTPUT";
+ @NonNls static final String GRAY_ID = "CONSOLE_GRAY_OUTPUT"; //ISO white
- public static final TextAttributes RED_DEFAULT_ATTRS = HighlighterColors.TEXT.getDefaultAttributes().clone();
- public static final TextAttributes GREEN_DEFAULT_ATTRS = HighlighterColors.TEXT.getDefaultAttributes().clone();
- public static final TextAttributes YELLOW_DEFAULT_ATTRS = HighlighterColors.TEXT.getDefaultAttributes().clone();
- public static final TextAttributes BLUE_DEFAULT_ATTRS = HighlighterColors.TEXT.getDefaultAttributes().clone();
- public static final TextAttributes MAGENTA_DEFAULT_ATTRS = HighlighterColors.TEXT.getDefaultAttributes().clone();
- public static final TextAttributes CYAN_DEFAULT_ATTRS = HighlighterColors.TEXT.getDefaultAttributes().clone();
- public static final TextAttributes GRAY_DEFAULT_ATTRS = HighlighterColors.TEXT.getDefaultAttributes().clone();
- static {
- RED_DEFAULT_ATTRS.setForegroundColor(JBColor.RED);
- GREEN_DEFAULT_ATTRS.setForegroundColor(new Color(0, 128, 0));
- YELLOW_DEFAULT_ATTRS.setForegroundColor(new Color(255, 204, 0));
- BLUE_DEFAULT_ATTRS.setForegroundColor(PlatformColors.BLUE);
- MAGENTA_DEFAULT_ATTRS.setForegroundColor(JBColor.MAGENTA);
- CYAN_DEFAULT_ATTRS.setForegroundColor(JBColor.CYAN.darker());
- GRAY_DEFAULT_ATTRS.setForegroundColor(JBColor.GRAY.darker());
- }
+ @NonNls static final String DARKGRAY_ID = "CONSOLE_DARKGRAY_OUTPUT";
+ @NonNls static final String RED_BRIGHT_ID = "CONSOLE_RED_BRIGHT_OUTPUT";
+ @NonNls static final String GREEN_BRIGHT_ID = "CONSOLE_GREEN_BRIGHT_OUTPUT";
+ @NonNls static final String YELLOW_BRIGHT_ID = "CONSOLE_YELLOW_BRIGHT_OUTPUT";
+ @NonNls static final String BLUE_BRIGHT_ID = "CONSOLE_BLUE_BRIGHT_OUTPUT";
+ @NonNls static final String MAGENTA_BRIGHT_ID = "CONSOLE_MAGENTA_BRIGHT_OUTPUT";
+ @NonNls static final String CYAN_BRIGHT_ID = "CONSOLE_CYAN_BRIGHT_OUTPUT";
+ @NonNls static final String WHITE_ID = "CONSOLE_WHITE_OUTPUT"; //ISO bright white
- public static final TextAttributesKey RED = TextAttributesKey.createTextAttributesKey(RED_ID, RED_DEFAULT_ATTRS);
- public static final TextAttributesKey GREEN = TextAttributesKey.createTextAttributesKey(GREEN_ID, GREEN_DEFAULT_ATTRS);
- public static final TextAttributesKey YELLOW = TextAttributesKey.createTextAttributesKey(YELLOW_ID, YELLOW_DEFAULT_ATTRS);
- public static final TextAttributesKey BLUE = TextAttributesKey.createTextAttributesKey(BLUE_ID, BLUE_DEFAULT_ATTRS);
- public static final TextAttributesKey MAGENTA = TextAttributesKey.createTextAttributesKey(MAGENTA_ID, MAGENTA_DEFAULT_ATTRS);
- public static final TextAttributesKey CYAN = TextAttributesKey.createTextAttributesKey(CYAN_ID, CYAN_DEFAULT_ATTRS);
- public static final TextAttributesKey GRAY = TextAttributesKey.createTextAttributesKey(GRAY_ID, GRAY_DEFAULT_ATTRS);
+ public static final TextAttributesKey BLACK =
+ TextAttributesKey.createTextAttributesKey(BLACK_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+ public static final TextAttributesKey RED = TextAttributesKey.createTextAttributesKey(RED_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+ public static final TextAttributesKey GREEN =
+ TextAttributesKey.createTextAttributesKey(GREEN_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+ public static final TextAttributesKey YELLOW =
+ TextAttributesKey.createTextAttributesKey(YELLOW_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+ public static final TextAttributesKey BLUE = TextAttributesKey.createTextAttributesKey(BLUE_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+ public static final TextAttributesKey MAGENTA =
+ TextAttributesKey.createTextAttributesKey(MAGENTA_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+ public static final TextAttributesKey CYAN = TextAttributesKey.createTextAttributesKey(CYAN_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+ public static final TextAttributesKey GRAY = TextAttributesKey.createTextAttributesKey(GRAY_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+
+
+ public static final TextAttributesKey DARKGRAY =
+ TextAttributesKey.createTextAttributesKey(DARKGRAY_ID, GRAY);
+ public static final TextAttributesKey RED_BRIGHT =
+ TextAttributesKey.createTextAttributesKey(RED_BRIGHT_ID, RED);
+ public static final TextAttributesKey GREEN_BRIGHT =
+ TextAttributesKey.createTextAttributesKey(GREEN_BRIGHT_ID, GREEN);
+ public static final TextAttributesKey YELLOW_BRIGHT =
+ TextAttributesKey.createTextAttributesKey(YELLOW_BRIGHT_ID, YELLOW);
+ public static final TextAttributesKey BLUE_BRIGHT =
+ TextAttributesKey.createTextAttributesKey(BLUE_BRIGHT_ID, BLUE);
+ public static final TextAttributesKey MAGENTA_BRIGHT =
+ TextAttributesKey.createTextAttributesKey(MAGENTA_BRIGHT_ID, MAGENTA);
+ public static final TextAttributesKey CYAN_BRIGHT =
+ TextAttributesKey.createTextAttributesKey(CYAN_BRIGHT_ID, CYAN);
+ public static final TextAttributesKey WHITE =
+ TextAttributesKey.createTextAttributesKey(WHITE_ID, ConsoleViewContentType.NORMAL_OUTPUT_KEY);
+
private ConsoleHighlighter() {
}
diff --git a/platform/platform-api/src/com/intellij/execution/util/ExecUtil.java b/platform/platform-api/src/com/intellij/execution/util/ExecUtil.java
index 5047c58..dc27fa2 100644
--- a/platform/platform-api/src/com/intellij/execution/util/ExecUtil.java
+++ b/platform/platform-api/src/com/intellij/execution/util/ExecUtil.java
@@ -23,14 +23,13 @@
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.*;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
public class ExecUtil {
private static final NotNullLazyValue<Boolean> hasGkSudo = new NotNullLazyValue<Boolean>() {
@@ -167,18 +166,93 @@
return null;
}
+ /**
+ * Run the command with superuser privileges using safe escaping and quoting.
+ *
+ * No shell substitutions, input/output redirects, etc. in the command are applied.
+ *
+ * @param command the command and its arguments, can contain any characters
+ * @param prompt the prompt string for the users
+ * @param workDir working directory
+ * @return the results of running the process
+ */
@NotNull
- public static ProcessOutput sudoAndGetOutput(@NotNull final String scriptPath,
- @NotNull final String prompt) throws IOException, ExecutionException {
+ public static ProcessOutput sudoAndGetOutput(@NotNull List<String> command,
+ @NotNull String prompt,
+ @Nullable String workDir) throws IOException, ExecutionException {
+ if (SystemInfo.isMac) {
+ final String escapedCommandLine = StringUtil.join(command, new Function<String, String>() {
+ @Override
+ public String fun(String s) {
+ return escapeAppleScriptArgument(s);
+ }
+ }, " & \" \" & ");
+ final String escapedScript = "do shell script " + escapedCommandLine + " with administrator privileges";
+ return execAndGetOutput(Arrays.asList(getOsascriptPath(), "-e", escapedScript), workDir);
+ }
+ else if ("root".equals(System.getenv("USER"))) {
+ return execAndGetOutput(command, workDir);
+ }
+ else if (hasGkSudo.getValue()) {
+ final List<String> sudoCommand = new ArrayList<String>();
+ sudoCommand.add("gksudo");
+ sudoCommand.add("--message");
+ sudoCommand.add(prompt);
+ sudoCommand.add("--");
+ sudoCommand.addAll(command);
+ return execAndGetOutput(sudoCommand, workDir);
+ }
+ else if (hasKdeSudo.getValue()) {
+ final List<String> sudoCommand = new ArrayList<String>();
+ sudoCommand.add("kdesudo");
+ sudoCommand.add("--comment");
+ sudoCommand.add(prompt);
+ sudoCommand.add("--");
+ sudoCommand.addAll(command);
+ return execAndGetOutput(sudoCommand, workDir);
+ }
+ else if (SystemInfo.isUnix && hasTerminalApp()) {
+ final String escapedCommandLine = StringUtil.join(command, new Function<String, String>() {
+ @Override
+ public String fun(String s) {
+ return escapeUnixShellArgument(s);
+ }
+ }, " ");
+ final File script = createTempExecutableScript(
+ "sudo", ".sh",
+ "#!/bin/sh\n" +
+ "echo " + escapeUnixShellArgument(prompt) + "\n" +
+ "echo\n" +
+ "sudo -- " + escapedCommandLine + "\n" +
+ "STATUS=$?\n" +
+ "echo\n" +
+ "read -p \"Press Enter to close this window...\" TEMP\n" +
+ "exit $STATUS\n");
+ return execAndGetOutput(getTerminalCommand("Install", script.getAbsolutePath()), workDir);
+ }
+ throw new UnsupportedSystemException();
+ }
+
+ @NotNull
+ private static String escapeAppleScriptArgument(@NotNull String arg) {
+ return "quoted form of \"" + arg.replace("\"", "\\\"") + "\"";
+ }
+
+ @NotNull
+ private static String escapeUnixShellArgument(@NotNull String arg) {
+ return "'" + arg.replace("'", "\\'") + "'";
+ }
+
+ /** @deprecated relies on platform-dependent escaping, use {@link #sudoAndGetOutput(List, String, String)} instead (to remove in IDEA 14) */
+ @SuppressWarnings({"UnusedDeclaration", "deprecation"})
+ public static ProcessOutput sudoAndGetOutput(@NotNull String scriptPath, @NotNull String prompt) throws IOException, ExecutionException {
return sudoAndGetOutput(scriptPath, prompt, null);
}
- /**
- * @param scriptPath is already escaped file path
- */
+ /** @deprecated relies on platform-dependent escaping, use {@link #sudoAndGetOutput(List, String, String)} instead (to remove in IDEA 14) */
@NotNull
- public static ProcessOutput sudoAndGetOutput(@NotNull final String scriptPath,
- @NotNull final String prompt,
+ public static ProcessOutput sudoAndGetOutput(@NotNull String scriptPath,
+ @NotNull String prompt,
@Nullable String workDir) throws IOException, ExecutionException {
if (SystemInfo.isMac) {
final String script = "do shell script \"" + scriptPath + "\" with administrator privileges";
@@ -209,9 +283,10 @@
throw new UnsupportedSystemException();
}
- public static int sudoAndGetResult(@NotNull final String scriptPath,
- @NotNull final String prompt) throws IOException, ExecutionException {
- return sudoAndGetOutput(scriptPath, prompt).getExitCode();
+ /** @deprecated relies on platform-dependent escaping, use {@link #sudoAndGetOutput(List, String, String)} instead (to remove in IDEA 14) */
+ @SuppressWarnings({"UnusedDeclaration", "deprecation"})
+ public static int sudoAndGetResult(@NotNull String scriptPath, @NotNull String prompt) throws IOException, ExecutionException {
+ return sudoAndGetOutput(scriptPath, prompt, null).getExitCode();
}
public static boolean hasTerminalApp() {
diff --git a/platform/platform-api/src/com/intellij/ide/highlighter/HighlighterFactory.java b/platform/platform-api/src/com/intellij/ide/highlighter/HighlighterFactory.java
deleted file mode 100644
index 8371c4a..0000000
--- a/platform/platform-api/src/com/intellij/ide/highlighter/HighlighterFactory.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.ide.highlighter;
-
-import com.intellij.openapi.editor.colors.EditorColorsScheme;
-import com.intellij.openapi.editor.highlighter.EditorHighlighter;
-import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.SyntaxHighlighter;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-
-public class HighlighterFactory {
- private HighlighterFactory() {}
-
- public static EditorHighlighter createHighlighter(SyntaxHighlighter highlighter, EditorColorsScheme settings) {
- return EditorHighlighterFactory.getInstance().createEditorHighlighter(highlighter, settings);
- }
-
- public static EditorHighlighter createHighlighter(Project project, String fileName) {
- return EditorHighlighterFactory.getInstance().createEditorHighlighter(project, fileName);
- }
-
- public static EditorHighlighter createHighlighter(Project project, VirtualFile file) {
- return EditorHighlighterFactory.getInstance().createEditorHighlighter(project, file);
- }
-
- public static EditorHighlighter createHighlighter(Project project, FileType fileType) {
- return EditorHighlighterFactory.getInstance().createEditorHighlighter(project, fileType);
- }
-
- public static EditorHighlighter createHighlighter(EditorColorsScheme settings, String fileName, Project project) {
- return EditorHighlighterFactory.getInstance().createEditorHighlighter(settings, fileName, project);
- }
-
- public static EditorHighlighter createHighlighter(FileType fileType, EditorColorsScheme settings, Project project) {
- return EditorHighlighterFactory.getInstance().createEditorHighlighter(fileType, settings, project);
- }
-
- public static EditorHighlighter createHighlighter(@NotNull VirtualFile vFile, EditorColorsScheme settings, Project project) {
- return EditorHighlighterFactory.getInstance().createEditorHighlighter(vFile, settings, project);
- }
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/ide/highlighter/WorkspaceFileType.java b/platform/platform-api/src/com/intellij/ide/highlighter/WorkspaceFileType.java
index d2d44ef..0b30e86 100644
--- a/platform/platform-api/src/com/intellij/ide/highlighter/WorkspaceFileType.java
+++ b/platform/platform-api/src/com/intellij/ide/highlighter/WorkspaceFileType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,33 +29,40 @@
@NonNls public static final String DEFAULT_EXTENSION = "iws";
@NonNls public static final String DOT_DEFAULT_EXTENSION = "." + DEFAULT_EXTENSION;
+ @Override
@NotNull
public String getName() {
return "IDEA_WORKSPACE";
}
+ @Override
@NotNull
public String getDescription() {
return IdeBundle.message("filetype.description.idea.workspace");
}
+ @Override
@NotNull
public String getDefaultExtension() {
return DEFAULT_EXTENSION;
}
+ @Override
public Icon getIcon() {
return AllIcons.Nodes.IdeaWorkspace;
}
+ @Override
public boolean isBinary() {
return false;
}
+ @Override
public boolean isReadOnly() {
return true;
}
+ @Override
public String getCharset(@NotNull VirtualFile file, final byte[] content) {
return CharsetToolkit.UTF8;
}
diff --git a/platform/platform-api/src/com/intellij/ide/util/PropertiesComponent.java b/platform/platform-api/src/com/intellij/ide/util/PropertiesComponent.java
index 92f1e6b..f3b883d 100644
--- a/platform/platform-api/src/com/intellij/ide/util/PropertiesComponent.java
+++ b/platform/platform-api/src/com/intellij/ide/util/PropertiesComponent.java
@@ -35,6 +35,11 @@
public abstract void setValue(@NonNls String name, String value);
+ /**
+ * Set value or unset if equals to default value
+ */
+ public abstract void setValue(@NotNull String name, @NotNull String value, @NotNull String defaultValue);
+
public abstract String[] getValues(@NonNls String name);
public abstract void setValues(@NonNls String name, String[] values);
diff --git a/platform/platform-api/src/com/intellij/ide/wizard/AbstractWizard.java b/platform/platform-api/src/com/intellij/ide/wizard/AbstractWizard.java
index 6288409..7c379da 100644
--- a/platform/platform-api/src/com/intellij/ide/wizard/AbstractWizard.java
+++ b/platform/platform-api/src/com/intellij/ide/wizard/AbstractWizard.java
@@ -299,7 +299,11 @@
}
public void addStep(@NotNull final T step) {
- mySteps.add(step);
+ addStep(step, mySteps.size());
+ }
+
+ public void addStep(@NotNull final T step, int index) {
+ mySteps.add(index, step);
if (step instanceof StepAdapter) {
((StepAdapter)step).registerStepListener(myStepListener);
@@ -451,7 +455,7 @@
@Nullable
@Override
public JComponent getPreferredFocusedComponent() {
- JComponent component = mySteps.get(myCurrentStep).getPreferredFocusedComponent();
+ JComponent component = getCurrentStepObject().getPreferredFocusedComponent();
return component == null ? super.getPreferredFocusedComponent() : component;
}
diff --git a/platform/platform-api/src/com/intellij/lexer/DummyLexer.java b/platform/platform-api/src/com/intellij/lexer/DummyLexer.java
deleted file mode 100644
index e20f4e5..0000000
--- a/platform/platform-api/src/com/intellij/lexer/DummyLexer.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.lexer;
-
-import com.intellij.psi.tree.IElementType;
-
-public class DummyLexer extends LexerBase {
- private CharSequence myBuffer;
- private int myStartOffset;
- private int myEndOffset;
- private final IElementType myTokenType;
-
- public DummyLexer(IElementType type) {
- myTokenType = type;
- }
-
- public void start(final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
- myBuffer = buffer;
- myStartOffset = startOffset;
- myEndOffset = endOffset;
- }
-
- public CharSequence getBufferSequence() {
- return myBuffer;
- }
-
- public int getState() {
- return 0;
- }
-
- public IElementType getTokenType() {
- return (myStartOffset < myEndOffset ? myTokenType : null);
- }
-
- public int getTokenStart() {
- return myStartOffset;
- }
-
- public int getTokenEnd() {
- return myEndOffset;
- }
-
- public void advance() {
- myStartOffset = myEndOffset;
- }
-
- public LexerPosition getCurrentPosition() {
- return new LexerPositionImpl(0, getState());
- }
-
- public void restore(LexerPosition position) {
- }
-
- public int getBufferEnd() {
- return myEndOffset;
- }
-}
diff --git a/platform/platform-api/src/com/intellij/lexer/LookAheadLexer.java b/platform/platform-api/src/com/intellij/lexer/LookAheadLexer.java
index 17c9bd6..d2b081d 100644
--- a/platform/platform-api/src/com/intellij/lexer/LookAheadLexer.java
+++ b/platform/platform-api/src/com/intellij/lexer/LookAheadLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
import com.intellij.psi.tree.IElementType;
import com.intellij.util.containers.ImmutableUserMap;
import com.intellij.util.containers.Queue;
+import org.jetbrains.annotations.NotNull;
/**
* @author peter
@@ -73,6 +74,7 @@
assert !myTypeCache.isEmpty();
}
+ @NotNull
public CharSequence getBufferSequence() {
return myBaseLexer.getBufferSequence();
}
@@ -109,11 +111,12 @@
return myTokenStart;
}
+ @NotNull
public LookAheadLexerPosition getCurrentPosition() {
return new LookAheadLexerPosition(this, ImmutableUserMap.EMPTY);
}
- public final void restore(final LexerPosition _position) {
+ public final void restore(@NotNull final LexerPosition _position) {
restore((LookAheadLexerPosition) _position);
}
@@ -129,7 +132,7 @@
}
@Override
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
myBaseLexer.start(buffer, startOffset, endOffset, initialState & 0xFFFF);
myTokenStart = startOffset;
myTypeCache.clear();
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/CheckboxAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/CheckboxAction.java
index 6f1c4ecf..5f179ba 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/CheckboxAction.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/CheckboxAction.java
@@ -48,6 +48,7 @@
checkBox.setToolTipText(presentation.getDescription());
checkBox.setMnemonic(presentation.getMnemonic());
checkBox.setDisplayedMnemonicIndex(presentation.getDisplayedMnemonicIndex());
+ checkBox.setSelected(Boolean.TRUE.equals(presentation.getClientProperty(SELECTED_PROPERTY)));
checkBox.addActionListener(new ActionListener() {
@Override
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactory.java b/platform/platform-api/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactory.java
deleted file mode 100644
index 597b20a..0000000
--- a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactory.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.openapi.editor.highlighter;
-
-import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.editor.colors.EditorColorsScheme;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.SyntaxHighlighter;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * @author yole
- */
-public abstract class EditorHighlighterFactory {
-
- public static EditorHighlighterFactory getInstance() {
- return ServiceManager.getService(EditorHighlighterFactory.class);
- }
-
- public abstract EditorHighlighter createEditorHighlighter(final SyntaxHighlighter syntaxHighlighter, final EditorColorsScheme colors);
-
- public abstract EditorHighlighter createEditorHighlighter(final FileType fileType, final EditorColorsScheme settings, final Project project);
-
- public abstract EditorHighlighter createEditorHighlighter(final Project project, final FileType fileType);
-
- public abstract EditorHighlighter createEditorHighlighter(@NotNull final VirtualFile file, final EditorColorsScheme globalScheme, @Nullable final Project project);
-
- public abstract EditorHighlighter createEditorHighlighter(final Project project, final VirtualFile file);
-
- public abstract EditorHighlighter createEditorHighlighter(final Project project, final String fileName);
-
- public abstract EditorHighlighter createEditorHighlighter(final EditorColorsScheme settings, final String fileName, @Nullable final Project project);
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/FileTypeExtensionFactory.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/FileTypeExtensionFactory.java
deleted file mode 100644
index da2268b..0000000
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/FileTypeExtensionFactory.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @author max
- */
-package com.intellij.openapi.fileTypes;
-
-import com.intellij.openapi.util.KeyedExtensionFactory;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-
-public class FileTypeExtensionFactory<T> extends KeyedExtensionFactory<T, FileType> {
- public FileTypeExtensionFactory(@NotNull final Class<T> interfaceClass, @NonNls @NotNull final String epName) {
- super(interfaceClass, epName);
- }
-
- @Override
- public String getKey(@NotNull final FileType key) {
- return key.getName();
- }
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/LanguageFileTypeHighlighterProvider.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/LanguageFileTypeHighlighterProvider.java
index ad7ae09..40fdece 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/LanguageFileTypeHighlighterProvider.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileTypes/LanguageFileTypeHighlighterProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -24,7 +25,7 @@
*/
public class LanguageFileTypeHighlighterProvider implements SyntaxHighlighterProvider {
@Nullable
- public SyntaxHighlighter create(final FileType fileType, @Nullable final Project project, @Nullable final VirtualFile file) {
+ public SyntaxHighlighter create(@NotNull final FileType fileType, @Nullable final Project project, @Nullable final VirtualFile file) {
if (fileType instanceof LanguageFileType) {
return SyntaxHighlighterFactory.getSyntaxHighlighter(((LanguageFileType)fileType).getLanguage(), project, file);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighter.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighter.java
deleted file mode 100644
index 08a8000..0000000
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighter.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.openapi.fileTypes;
-
-import com.intellij.lexer.EmptyLexer;
-import com.intellij.lexer.Lexer;
-import com.intellij.openapi.editor.HighlighterColors;
-import com.intellij.openapi.editor.colors.TextAttributesKey;
-import com.intellij.psi.tree.IElementType;
-import org.jetbrains.annotations.NotNull;
-
-public class PlainSyntaxHighlighter implements SyntaxHighlighter {
- private static final TextAttributesKey[] ATTRS = new TextAttributesKey[] {HighlighterColors.TEXT};
-
- @NotNull
- public Lexer getHighlightingLexer() {
- return new EmptyLexer();
- }
-
- @NotNull
- public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
- return ATTRS;
- }
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighterFactory.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighterFactory.java
deleted file mode 100644
index b19651c..0000000
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/PlainSyntaxHighlighterFactory.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @author max
- */
-package com.intellij.openapi.fileTypes;
-
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-
-public class PlainSyntaxHighlighterFactory extends SyntaxHighlighterFactory {
- @NotNull
- public SyntaxHighlighter getSyntaxHighlighter(final Project project, final VirtualFile virtualFile) {
- return new PlainSyntaxHighlighter();
- }
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighter.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighter.java
deleted file mode 100644
index a6cf7a3..0000000
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighter.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.openapi.fileTypes;
-
-import com.intellij.lexer.Lexer;
-import com.intellij.openapi.editor.colors.TextAttributesKey;
-import com.intellij.psi.tree.IElementType;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Controls the syntax highlighting of a file.
- *
- * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
- * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.lang.Language, com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
- */
-public interface SyntaxHighlighter {
- /**
- * @deprecated
- * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
- * @see SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.lang.Language, com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
- */
- SyntaxHighlighterProvider PROVIDER =
- new FileTypeExtensionFactory<SyntaxHighlighterProvider>(SyntaxHighlighterProvider.class, "com.intellij.syntaxHighlighter").get();
-
- /**
- * Returns the lexer used for highlighting the file. The lexer is invoked incrementally when the file is changed, so it must be
- * capable of saving/restoring state and resuming lexing from the middle of the file.
- *
- * @return The lexer implementation.
- */
- @NotNull
- Lexer getHighlightingLexer();
-
- /**
- * Returns the list of text attribute keys used for highlighting the specified token type. The attributes of all attribute keys
- * returned for the token type are successively merged to obtain the color and attributes of the token.
- *
- * @param tokenType The token type for which the highlighting is requested.
- * @return The array of text attribute keys.
- */
- @NotNull
- TextAttributesKey[] getTokenHighlights(IElementType tokenType);
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java
deleted file mode 100644
index ad697f9..0000000
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.openapi.fileTypes;
-
-import com.intellij.lang.Language;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * @author max
- */
-public abstract class SyntaxHighlighterFactory {
- public static final SyntaxHighlighterLanguageFactory LANGUAGE_FACTORY = new SyntaxHighlighterLanguageFactory();
-
- /**
- * Returns syntax highlighter for the given language.
- *
- * @param language a {@code Language} to get highlighter for
- * @param project might be necessary to gather various project settings from
- * @param file might be necessary to collect file specific settings
- * @return {@code SyntaxHighlighter} interface implementation for the given file type
- */
- public static SyntaxHighlighter getSyntaxHighlighter(@NotNull Language language, @Nullable Project project, @Nullable VirtualFile file) {
- return LANGUAGE_FACTORY.forLanguage(language).getSyntaxHighlighter(project, file);
- }
-
- /**
- * Returns syntax highlighter for the given file type.
- * Note: it is recommended to use {@link #getSyntaxHighlighter(Language, Project, VirtualFile)} in most cases,
- * and use this method only when you are do not know the language you use.
- *
- * @param fileType a file type to use to select appropriate highlighter
- * @param project might be necessary to gather various project settings from
- * @param file might be necessary to collect file specific settings
- * @return {@code SyntaxHighlighter} interface implementation for the given file type
- */
- @Nullable
- public static SyntaxHighlighter getSyntaxHighlighter(FileType fileType, @Nullable Project project, @Nullable VirtualFile file) {
- return SyntaxHighlighter.PROVIDER.create(fileType, project, file);
- }
-
- /**
- * Override this method to provide syntax highlighting (coloring) capabilities for your language implementation.
- * By syntax highlighting we mean highlighting of keywords, comments, braces etc. where lexing the file content is enough
- * to identify proper highlighting attributes.
- * <p/>
- * Default implementation doesn't highlight anything.
- *
- * @param project might be necessary to gather various project settings from.
- * @param virtualFile might be necessary to collect file specific settings
- * @return <code>SyntaxHighlighter</code> interface implementation for this particular language.
- */
- @NotNull
- public abstract SyntaxHighlighter getSyntaxHighlighter(@Nullable Project project, @Nullable VirtualFile virtualFile);
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterLanguageFactory.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterLanguageFactory.java
deleted file mode 100644
index a223fa0..0000000
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterLanguageFactory.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @author max
- */
-package com.intellij.openapi.fileTypes;
-
-import com.intellij.lang.LanguageExtension;
-
-public class SyntaxHighlighterLanguageFactory extends LanguageExtension<SyntaxHighlighterFactory> {
- SyntaxHighlighterLanguageFactory() {
- super("com.intellij.lang.syntaxHighlighterFactory", new PlainSyntaxHighlighterFactory());
- }
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterProvider.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterProvider.java
deleted file mode 100644
index 6317dd7..0000000
--- a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterProvider.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Created by IntelliJ IDEA.
- * User: yole
- * Date: 06.11.2007
- * Time: 19:49:57
- */
-package com.intellij.openapi.fileTypes;
-
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.Nullable;
-
-public interface SyntaxHighlighterProvider {
- @Nullable
- SyntaxHighlighter create(FileType fileType, @Nullable Project project, @Nullable VirtualFile file);
-}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/options/SchemeImportException.java b/platform/platform-api/src/com/intellij/openapi/options/SchemeImportException.java
new file mode 100644
index 0000000..96835f1
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/openapi/options/SchemeImportException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.options;
+
+/**
+ * Thrown from SchemeImporter when a scheme can't be read for some reason.
+ *
+ * @see com.intellij.openapi.options.SchemeImporter
+ * @author Rustam Vishnyakov
+ */
+public class SchemeImportException extends Exception {
+ public SchemeImportException(String message) {
+ super(message);
+ }
+
+ public SchemeImportException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/openapi/options/SchemeImporter.java b/platform/platform-api/src/com/intellij/openapi/options/SchemeImporter.java
new file mode 100644
index 0000000..8bb8456
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/openapi/options/SchemeImporter.java
@@ -0,0 +1,39 @@
+package com.intellij.openapi.options;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.InputStream;
+
+/**
+ * Provides functionality to import a scheme from another non-IntelliJ IDEA format.
+ *
+ * @author Rustam Vishnyakov
+ */
+public interface SchemeImporter <T extends Scheme> {
+
+ /**
+ * @return An extension of a source file which can be imported, for example, "xml".
+ */
+ String getSourceExtension();
+
+ /**
+ * Attempts to read scheme names from the given stream. The stream may contain several schemes in which case all the available
+ * names are returned.
+ *
+ * @param inputStream The input stream to read the name from.
+ * @return Either scheme name or null if the scheme doesn't have a name.
+ * @throws SchemeImportException
+ */
+ @NotNull
+ String[] readSchemeNames(@NotNull InputStream inputStream) throws SchemeImportException;
+
+ /**
+ * Import a scheme from the given stream and source scheme name.
+ *
+ * @param inputStream The input stream to import from.
+ * @param sourceScheme The source scheme name (one of returned by <code>readSchemeNames</code> method).
+ * @param scheme The target scheme receiving data.
+ */
+ void importScheme(@NotNull InputStream inputStream, @Nullable String sourceScheme, T scheme) throws SchemeImportException;
+}
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/popup/JBPopupListener.java b/platform/platform-api/src/com/intellij/openapi/ui/popup/JBPopupListener.java
index 2964c19..1f004c7 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/popup/JBPopupListener.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/popup/JBPopupListener.java
@@ -21,12 +21,13 @@
void onClosed(LightweightWindowEvent event);
- class Adapter implements JBPopupListener{
+ class Adapter implements JBPopupListener {
+ @Override
public void beforeShown(LightweightWindowEvent event) {
}
+ @Override
public void onClosed(LightweightWindowEvent event) {
}
}
-
}
diff --git a/platform/platform-api/src/com/intellij/openapi/util/DimensionService.java b/platform/platform-api/src/com/intellij/openapi/util/DimensionService.java
index de2bd4b..b9ee6c0 100644
--- a/platform/platform-api/src/com/intellij/openapi/util/DimensionService.java
+++ b/platform/platform-api/src/com/intellij/openapi/util/DimensionService.java
@@ -22,6 +22,7 @@
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.ui.ScreenUtil;
+import com.intellij.util.containers.hash.LinkedHashMap;
import gnu.trove.TObjectIntHashMap;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -30,23 +31,20 @@
import javax.swing.*;
import java.awt.*;
-import java.util.HashMap;
import java.util.Map;
/**
* This class represents map between strings and rectangles. It's intended to store
* sizes of window, dialogs, etc.
*/
-@SuppressWarnings({"NonPrivateFieldAccessedInSynchronizedContext"})
@State(
- name = "DimensionService",
- storages = {@Storage(
- file = StoragePathMacros.APP_CONFIG + "/options.xml")})
+ name = "DimensionService",
+ storages = {@Storage(file = StoragePathMacros.APP_CONFIG + "/options.xml")})
public class DimensionService implements PersistentStateComponent<Element>, ApplicationComponent {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.util.DimensionService");
- private final Map<String,Point> myKey2Location;
- private final Map<String,Dimension> myKey2Size;
+ private final Map<String, Point> myKey2Location;
+ private final Map<String, Dimension> myKey2Size;
private final TObjectIntHashMap<String> myKey2ExtendedState;
@NonNls private static final String EXTENDED_STATE = "extendedState";
@NonNls private static final String KEY = "key";
@@ -62,24 +60,30 @@
return ApplicationManager.getApplication().getComponent(DimensionService.class);
}
- /** Invoked by reflection */
- private DimensionService(){
- myKey2Location=new HashMap<String, Point>();
- myKey2Size=new HashMap<String, Dimension>();
+ /**
+ * Invoked by reflection
+ */
+ private DimensionService() {
+ myKey2Location = new LinkedHashMap<String, Point>();
+ myKey2Size = new LinkedHashMap<String, Dimension>();
myKey2ExtendedState = new TObjectIntHashMap<String>();
}
- public void initComponent() {}
+ @Override
+ public void initComponent() {
+ }
- public void disposeComponent() {}
+ @Override
+ public void disposeComponent() {
+ }
/**
+ * @param key a String key to perform a query for.
* @return point stored under the specified <code>key</code>. The method returns
* <code>null</code> if there is no stored value under the <code>key</code>. If point
* is outside of current screen bounds then the method returns <code>null</code>. It
* properly works in multi-monitor configuration.
- * @exception java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
- * @param key a String key to perform a query for.
+ * @throws java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
*/
@Nullable
public synchronized Point getLocation(String key) {
@@ -88,47 +92,41 @@
@Nullable
public synchronized Point getLocation(@NotNull String key, Project project) {
- key = realKey(key, project);
-
- Point point = myKey2Location.get(key);
- if (point != null) {
- if (!ScreenUtil.getScreenRectangle(point).contains(point)){
- point = null;
- }
+ Point point = myKey2Location.get(realKey(key, project));
+ if (point != null && !ScreenUtil.getScreenRectangle(point).contains(point)) {
+ point = null;
}
- if(point!=null){
- return (Point)point.clone();
- }else{
- return null;
- }
+ return point != null ? (Point)point.clone() : null;
}
/**
* Store specified <code>point</code> under the <code>key</code>. If <code>point</code> is
* <code>null</code> then the value stored under <code>key</code> will be removed.
- * @param key a String key to store location for.
+ *
+ * @param key a String key to store location for.
* @param point location to save.
- * @exception java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
+ * @throws java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
*/
- public synchronized void setLocation(String key, Point point){
+ public synchronized void setLocation(String key, Point point) {
setLocation(key, point, guessProject());
}
- public synchronized void setLocation(@NotNull String key, Point point, Project project){
+ public synchronized void setLocation(@NotNull String key, Point point, Project project) {
key = realKey(key, project);
if (point != null) {
myKey2Location.put(key, (Point)point.clone());
- }else {
+ }
+ else {
myKey2Location.remove(key);
}
}
/**
+ * @param key a String key to perform a query for.
* @return point stored under the specified <code>key</code>. The method returns
* <code>null</code> if there is no stored value under the <code>key</code>.
- * @param key a String key to perform a query for.
- * @exception java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
+ * @throws java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
*/
@Nullable
public synchronized Dimension getSize(@NotNull @NonNls String key) {
@@ -137,37 +135,34 @@
@Nullable
public synchronized Dimension getSize(@NotNull @NonNls String key, Project project) {
- key = realKey(key, project);
-
- Dimension size=myKey2Size.get(key);
- if(size!=null){
- return (Dimension)size.clone();
- }else{
- return null;
- }
+ Dimension size = myKey2Size.get(realKey(key, project));
+ return size != null ? (Dimension)size.clone() : null;
}
/**
* Store specified <code>size</code> under the <code>key</code>. If <code>size</code> is
* <code>null</code> then the value stored under <code>key</code> will be removed.
- * @param key a String key to to save size for.
+ *
+ * @param key a String key to to save size for.
* @param size a Size to save.
- * @exception java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
+ * @throws java.lang.IllegalArgumentException if <code>key</code> is <code>null</code>.
*/
- public synchronized void setSize(@NotNull @NonNls String key, Dimension size){
+ public synchronized void setSize(@NotNull @NonNls String key, Dimension size) {
setSize(key, size, guessProject());
}
- public synchronized void setSize(@NotNull @NonNls String key, Dimension size, Project project){
+ public synchronized void setSize(@NotNull @NonNls String key, Dimension size, Project project) {
key = realKey(key, project);
if (size != null) {
myKey2Size.put(key, (Dimension)size.clone());
- }else {
+ }
+ else {
myKey2Size.remove(key);
}
}
+ @Override
public Element getState() {
Element element = new Element("state");
// Save locations
@@ -203,20 +198,19 @@
return element;
}
+ @Override
public void loadState(final Element element) {
myKey2Location.clear();
myKey2Size.clear();
myKey2ExtendedState.clear();
- for (final Object o : element.getChildren()) {
- Element e = (Element)o;
+ for (Element e : element.getChildren()) {
if (ELEMENT_LOCATION.equals(e.getName())) {
try {
myKey2Location.put(e.getAttributeValue(KEY), new Point(Integer.parseInt(e.getAttributeValue(ATTRIBUTE_X)),
Integer.parseInt(e.getAttributeValue(ATTRIBUTE_Y))));
}
catch (NumberFormatException ignored) {
- // ignored
}
}
else if (ELEMENT_SIZE.equals(e.getName())) {
@@ -225,7 +219,6 @@
Integer.parseInt(e.getAttributeValue(ATTRIBUTE_HEIGHT))));
}
catch (NumberFormatException ignored) {
- // ignored
}
}
else if (EXTENDED_STATE.equals(e.getName())) {
@@ -233,12 +226,12 @@
myKey2ExtendedState.put(e.getAttributeValue(KEY), Integer.parseInt(e.getAttributeValue(STATE)));
}
catch (NumberFormatException ignored) {
- // ignored
}
}
}
}
+ @Override
@NotNull
public String getComponentName() {
return "DimensionService";
diff --git a/platform/platform-api/src/com/intellij/openapi/util/KeyedExtensionFactory.java b/platform/platform-api/src/com/intellij/openapi/util/KeyedExtensionFactory.java
deleted file mode 100644
index 9827e2f..0000000
--- a/platform/platform-api/src/com/intellij/openapi/util/KeyedExtensionFactory.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.openapi.util;
-
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.extensions.KeyedFactoryEPBean;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-/**
- * @author yole
- */
-public abstract class KeyedExtensionFactory<T, KeyT> {
- private final Class<T> myInterfaceClass;
- private final ExtensionPointName<KeyedFactoryEPBean> myEpName;
-
- public KeyedExtensionFactory(@NotNull final Class<T> interfaceClass, @NonNls @NotNull final String epName) {
- myInterfaceClass = interfaceClass;
- myEpName = new ExtensionPointName<KeyedFactoryEPBean>(epName);
- }
-
- @NotNull
- public T get() {
- final KeyedFactoryEPBean[] epBeans = Extensions.getExtensions(myEpName);
- InvocationHandler handler = new InvocationHandler() {
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- //noinspection unchecked
- KeyT keyArg = (KeyT) args [0];
- String key = getKey(keyArg);
- Object result = getByKey(epBeans, key, method, args);
- if (result == null) {
- result = getByKey(epBeans, null, method, args);
- }
- return result;
- }
- };
- //noinspection unchecked
- return (T)Proxy.newProxyInstance(myInterfaceClass.getClassLoader(), new Class<?>[] { myInterfaceClass }, handler );
- }
-
- public T getByKey(@NotNull KeyT key) {
- final KeyedFactoryEPBean[] epBeans = Extensions.getExtensions(myEpName);
- for (KeyedFactoryEPBean epBean : epBeans) {
- if (Comparing.strEqual(getKey(key), epBean.key)) {
- try {
- if (epBean.implementationClass != null) {
- return (T)epBean.instantiate(epBean.implementationClass, ApplicationManager.getApplication().getPicoContainer());
- }
- }
- catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- }
- return null;
- }
-
- private T getByKey(final KeyedFactoryEPBean[] epBeans, final String key, final Method method, final Object[] args) {
- Object result = null;
- for(KeyedFactoryEPBean epBean: epBeans) {
- if (Comparing.strEqual(epBean.key, key, true)) {
- try {
- if (epBean.implementationClass != null) {
- result = epBean.instantiate(epBean.implementationClass, ApplicationManager.getApplication().getPicoContainer());
- }
- else {
- Object factory = epBean.instantiate(epBean.factoryClass, ApplicationManager.getApplication().getPicoContainer());
- result = method.invoke(factory, args);
- }
- if (result != null) {
- break;
- }
- }
- catch (RuntimeException e) {
- throw e;
- }
- catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- }
- //noinspection ConstantConditions
- return (T)result;
- }
-
- public abstract String getKey(@NotNull KeyT key);
-}
-
diff --git a/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java b/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java
index 18f59ed..c5dcc9e 100644
--- a/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java
+++ b/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java
@@ -192,6 +192,10 @@
}
+ protected void nodeStateWillChange(CheckedTreeNode node) {
+
+ }
+
protected void adjustParentsAndChildren(final CheckedTreeNode node, final boolean checked) {
changeNodeState(node, checked);
if (!checked) {
@@ -230,6 +234,7 @@
private void changeNodeState(final CheckedTreeNode node, final boolean checked) {
if (node.isChecked() != checked) {
+ nodeStateWillChange(node);
node.setChecked(checked);
onNodeStateChanged(node);
}
diff --git a/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java b/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java
index 28c71db..168f4ee 100644
--- a/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java
+++ b/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java
@@ -44,6 +44,7 @@
protected JTree myTree;
private boolean myOpaque = true;
+ @Override
public final Component getTreeCellRendererComponent(
JTree tree,
Object value,
@@ -137,6 +138,7 @@
return myTree.hasFocus();
}
+ @Override
public void setOpaque(boolean isOpaque) {
myOpaque = isOpaque;
super.setOpaque(isOpaque);
@@ -157,6 +159,7 @@
* When the item is selected then we use default tree's selection foreground.
* It guaranties readability of selected text in any LAF.
*/
+ @Override
public void append(@NotNull @Nls String fragment, @NotNull SimpleTextAttributes attributes, boolean isMainText) {
if (mySelected && isFocused()) {
super.append(fragment, new SimpleTextAttributes(attributes.getStyle(), UIUtil.getTreeSelectionForeground()), isMainText);
diff --git a/platform/platform-api/src/com/intellij/ui/PrepareTreeRenderer.java b/platform/platform-api/src/com/intellij/ui/PrepareTreeRenderer.java
deleted file mode 100644
index ad4c0da..0000000
--- a/platform/platform-api/src/com/intellij/ui/PrepareTreeRenderer.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.ui;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 6/12/12
- * Time: 4:40 PM
- */
-public class PrepareTreeRenderer {
-/* public static void prepare(final JTree tree, final JComponent component, final boolean selected, final boolean hasFocus) {
- final boolean treeFocused = tree.hasFocus();
- // We paint background if and only if tree path is selected and tree has focus.
- // If path is selected and tree is not focused then we just paint focused border.
- if (UIUtil.isFullRowSelectionLAF()) {
- component.setBackground(selected ? UIUtil.getTreeSelectionBackground() : null);
- }
- else if (UIUtil.isUnderAquaLookAndFeel() && tree.getUI() instanceof MacTreeUI && ((MacTreeUI)tree.getUI()).isWideSelection()) {
- component.setPaintFocusBorder(false);
- //setBackground(selected ? UIUtil.getTreeSelectionBackground() : null);
- }
- else {
- if (selected) {
- component.setPaintFocusBorder(true);
- if (treeFocused) {
- component.setBackground(UIUtil.getTreeSelectionBackground());
- }
- else {
- component.setBackground(null);
- }
- }
- else {
- component.setBackground(null);
- }
- }
-
- component.setForeground(tree.getForeground());
- component.setIcon(null);
-
- if (UIUtil.isUnderGTKLookAndFeel()){
- component.setOpaque(false); // avoid nasty background
- component.setIconOpaque(false);
- }
- else if (UIUtil.isUnderNimbusLookAndFeel() && selected && hasFocus) {
- component.setOpaque(false); // avoid erasing Nimbus focus frame
- component.setIconOpaque(false);
- }
- else if (UIUtil.isUnderAquaLookAndFeel() && tree.getUI() instanceof MacTreeUI && ((MacTreeUI)tree.getUI()).isWideSelection()) {
- component.setOpaque(false); // avoid erasing Nimbus focus frame
- component.setIconOpaque(false);
- }
- else {
- component.setOpaque(myOpaque || selected && hasFocus || selected && treeFocused); // draw selection background even for non-opaque tree
- }
-
- if (tree.getUI() instanceof MacTreeUI) {
- component.setMyBorder(null);
- component.setIpad(new Insets(0, 2, 0, 2));
- }
-
- if (component.getFont() == null) {
- component.setFont(tree.getFont());
- }
- } */
-}
diff --git a/platform/platform-api/src/com/intellij/ui/TextComponentUndoProvider.java b/platform/platform-api/src/com/intellij/ui/TextComponentUndoProvider.java
index ce95057..0fe7e6e 100644
--- a/platform/platform-api/src/com/intellij/ui/TextComponentUndoProvider.java
+++ b/platform/platform-api/src/com/intellij/ui/TextComponentUndoProvider.java
@@ -37,6 +37,7 @@
myTextComponent = textComponent;
myUndoableEditListener = new UndoableEditListener() {
+ @Override
public void undoableEditHappened(UndoableEditEvent e) {
myUndoManager.addEdit(e.getEdit());
}
@@ -96,6 +97,7 @@
}
}
+ @Override
public void dispose() {
if (myUndoableEditListener != null) {
myTextComponent.getDocument().removeUndoableEditListener(myUndoableEditListener);
diff --git a/platform/platform-api/src/com/intellij/ui/table/TableView.java b/platform/platform-api/src/com/intellij/ui/table/TableView.java
index ad76c90..889c496 100644
--- a/platform/platform-api/src/com/intellij/ui/table/TableView.java
+++ b/platform/platform-api/src/com/intellij/ui/table/TableView.java
@@ -112,8 +112,12 @@
final ColumnInfo columnInfo = columns[i];
final TableColumn column = getColumnModel().getColumn(i);
- final Component headerComponent = defaultRenderer == null? null :
- defaultRenderer.getTableCellRendererComponent(this, column.getHeaderValue(), false, false, 0, 0);
+ TableCellRenderer columnHeaderRenderer = column.getHeaderRenderer();
+ if (columnHeaderRenderer == null) {
+ columnHeaderRenderer = defaultRenderer;
+ }
+ final Component headerComponent = columnHeaderRenderer == null? null :
+ columnHeaderRenderer.getTableCellRendererComponent(this, column.getHeaderValue(), false, false, 0, i);
if (headerComponent != null) {
headers[i] = headerComponent.getPreferredSize().width;
diff --git a/platform/platform-api/src/com/intellij/util/PlatformUtils.java b/platform/platform-api/src/com/intellij/util/PlatformUtils.java
index e71e70b..b4e9228 100644
--- a/platform/platform-api/src/com/intellij/util/PlatformUtils.java
+++ b/platform/platform-api/src/com/intellij/util/PlatformUtils.java
@@ -59,7 +59,8 @@
}
public static boolean isPyCharm() {
- return PYCHARM_PREFIX.equals(getPlatformPrefix());
+ String prefix = getPlatformPrefix();
+ return PYCHARM_PREFIX.equals(prefix) || (prefix != null && prefix.startsWith(PYCHARM_PREFIX2));
}
public static boolean isPhpStorm() {
diff --git a/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java b/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java
index a58aaa1..cf95958 100644
--- a/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java
+++ b/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java
@@ -24,7 +24,6 @@
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Conditions;
import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
@@ -34,7 +33,6 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.io.File;
import java.nio.charset.Charset;
/**
@@ -114,18 +112,7 @@
@Nullable VirtualFile scriptFile,
String[] parameters,
@Nullable Charset charset) throws ExecutionException {
- if (SystemInfo.isMac) {
- File exeFile = new File(exePath);
- if (!exeFile.isAbsolute() && !exePath.contains(File.separator)) {
- File originalResolvedExeFile = PathEnvironmentVariableUtil.findInOriginalPath(exePath);
- if (originalResolvedExeFile == null) {
- File resolvedExeFile = PathEnvironmentVariableUtil.findInPath(exePath);
- if (resolvedExeFile != null) {
- exePath = resolvedExeFile.getAbsolutePath();
- }
- }
- }
- }
+ exePath = PathEnvironmentVariableUtil.findAbsolutePathOnMac(exePath);
return doExecute(exePath, workingDirectory, scriptFile, parameters, charset);
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
index c84f7e2..5f259bf 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -211,7 +211,8 @@
"xdg-desktop-menu forceupdate --mode system\n" +
"exit $RV\n");
script.deleteOnExit();
- final int result = ExecUtil.sudoAndGetResult(script.getAbsolutePath(), ApplicationBundle.message("desktop.entry.sudo.prompt"));
+ final String prompt = ApplicationBundle.message("desktop.entry.sudo.prompt");
+ final int result = ExecUtil.sudoAndGetOutput(asList(script.getPath()), prompt, null).getExitCode();
if (result != 0) throw new RuntimeException("'" + script.getAbsolutePath() + "' : " + result);
}
else {
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java
index 8644cd5..315e3ad 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -112,8 +112,8 @@
// copy file and change ownership to root (UID 0 = root, GID 0 = root (wheel on Macs))
"install -g 0 -o 0 \"" + scriptFile.getCanonicalPath() + "\" \"" + pathName + "\"";
final File installationScript = ExecUtil.createTempExecutableScript("launcher_installer", ".sh", installationScriptSrc);
- ExecUtil.sudoAndGetResult(installationScript.getAbsolutePath(),
- ApplicationBundle.message("launcher.script.sudo.prompt", launcherScriptContainingDirPath));
+ final String prompt = ApplicationBundle.message("launcher.script.sudo.prompt", launcherScriptContainingDirPath);
+ ExecUtil.sudoAndGetOutput(asList(installationScript.getPath()), prompt, null);
}
}
catch (Exception e) {
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java
index 5dcf70e..7a15f84 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java
@@ -22,6 +22,7 @@
import com.intellij.ide.IdeBundle;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManager;
+import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
@@ -44,7 +45,6 @@
import java.util.jar.JarOutputStream;
public class ExportSettingsAction extends AnAction implements DumbAware {
-
public void actionPerformed(AnActionEvent e) {
Project project = getEventProject(e);
List<ExportableComponent> exportableComponents = new ArrayList<ExportableComponent>();
@@ -57,11 +57,12 @@
dialog.show();
if (!dialog.isOK()) return;
Set<ExportableComponent> markedComponents = dialog.getExportableComponents();
- if (markedComponents.size() == 0) return;
+ if (markedComponents.isEmpty()) {
+ return;
+ }
Set<File> exportFiles = new HashSet<File>();
for (final ExportableComponent markedComponent : markedComponents) {
- final File[] files = markedComponent.getExportFiles();
- ContainerUtil.addAll(exportFiles, files);
+ ContainerUtil.addAll(exportFiles, markedComponent.getExportFiles());
}
ApplicationManager.getApplication().saveSettings();
@@ -107,7 +108,7 @@
private static void exportInstalledPlugins(File saveFile, JarOutputStream output, HashSet<String> writtenItemRelativePaths) throws IOException {
final List<String> oldPlugins = new ArrayList<String>();
- for (IdeaPluginDescriptor descriptor : PluginManager.getPlugins()) {
+ for (IdeaPluginDescriptor descriptor : PluginManagerCore.getPlugins()) {
if (!descriptor.isBundled() && descriptor.isEnabled()) {
oldPlugins.add(descriptor.getPluginId().getIdString());
}
@@ -115,7 +116,7 @@
if (!oldPlugins.isEmpty()) {
final File tempFile = File.createTempFile("installed", "plugins");
tempFile.deleteOnExit();
- PluginManager.savePluginsList(oldPlugins, false, tempFile);
+ PluginManagerCore.savePluginsList(oldPlugins, false, tempFile);
ZipUtil.addDirToZipRecursively(output, saveFile, tempFile, "/" + PluginManager.INSTALLED_TXT, null, writtenItemRelativePaths);
}
}
@@ -129,8 +130,7 @@
for (ExportableComponent component : components) {
exportableComponents.add(component);
- final File[] exportFiles = component.getExportFiles();
- for (File exportFile : exportFiles) {
+ for (File exportFile : component.getExportFiles()) {
Set<ExportableComponent> componentsTied = fileToComponents.get(exportFile);
if (componentsTied == null) {
componentsTied = new HashSet<ExportableComponent>();
@@ -141,5 +141,4 @@
}
return fileToComponents;
}
-
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/MaintenanceAction.java b/platform/platform-impl/src/com/intellij/ide/actions/MaintenanceAction.java
index b42a9a1..df99af2 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/MaintenanceAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/MaintenanceAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,9 +19,10 @@
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.ui.popup.JBPopupFactory;
-public class MaintenanceAction extends AnAction {
+public class MaintenanceAction extends AnAction implements DumbAware {
public MaintenanceAction() {
super("Maintenance");
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/SendFeedbackAction.java b/platform/platform-impl/src/com/intellij/ide/actions/SendFeedbackAction.java
index c1e32c6..2ba9f1a 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/SendFeedbackAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/SendFeedbackAction.java
@@ -36,9 +36,10 @@
public static void launchBrowser() {
final ApplicationInfoEx appInfo = ApplicationInfoEx.getInstanceEx();
- String urlTemplate = appInfo.isEAP() ? appInfo.getEAPFeedbackUrl() : appInfo.getReleaseFeedbackUrl();
+ boolean eap = appInfo.isEAP();
+ String urlTemplate = eap ? appInfo.getEAPFeedbackUrl() : appInfo.getReleaseFeedbackUrl();
urlTemplate = urlTemplate
- .replace("$BUILD", appInfo.getBuild().asString())
+ .replace("$BUILD", eap ? appInfo.getBuild().asStringWithoutProductCode() : appInfo.getBuild().asString())
.replace("$TIMEZONE", System.getProperty("user.timezone"))
.replace("$EVAL", isEvaluationLicense() ? "true" : "false");
BrowserUtil.launchBrowser(urlTemplate);
diff --git a/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java b/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java
index b20c113..0c14e13 100644
--- a/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java
+++ b/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -71,6 +71,7 @@
myCommentAtLineStart.setEnabled(false);
}
+ @Override
public void resetEditorFrom(AbstractFileType fileType) {
myFileTypeName.setText(fileType.getName());
myFileTypeDescr.setText(fileType.getDescription());
@@ -106,6 +107,7 @@
}
}
+ @Override
public void applyEditorTo(AbstractFileType type) throws ConfigurationException {
if (myFileTypeName.getText().trim().length() == 0) {
throw new ConfigurationException(IdeBundle.message("error.name.cannot.be.empty"),
@@ -119,6 +121,7 @@
type.setSyntaxTable(getSyntaxTable());
}
+ @Override
@NotNull
public JComponent createEditor() {
JComponent panel = createCenterPanel();
diff --git a/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/ModifyKeywordDialog.java b/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/ModifyKeywordDialog.java
index 400c67a..bed9d53 100644
--- a/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/ModifyKeywordDialog.java
+++ b/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/ModifyKeywordDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +41,7 @@
myKeywordName.setText(initialValue);
}
+ @Override
protected JComponent createNorthPanel() {
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
@@ -64,10 +65,12 @@
return panel;
}
+ @Override
protected JComponent createCenterPanel() {
return null;
}
+ @Override
protected void doOKAction() {
final String keywordName = myKeywordName.getText().trim();
if (keywordName.length() == 0) {
@@ -83,6 +86,7 @@
super.doOKAction();
}
+ @Override
public JComponent getPreferredFocusedComponent() {
return myKeywordName;
}
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
index 95bbfdc..4037066 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
@@ -27,6 +27,7 @@
import com.intellij.openapi.components.ComponentConfig;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.PluginId;
+import com.intellij.openapi.extensions.impl.PicoPluginExtensionInitializationException;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.util.Comparing;
@@ -99,6 +100,9 @@
if (t instanceof StartupAbortedException) {
se = (StartupAbortedException)t;
}
+ else if (t.getCause() instanceof StartupAbortedException) {
+ se = (StartupAbortedException)t.getCause();
+ }
else if (!IdeaApplication.isLoaded()) {
se = new StartupAbortedException(t);
}
@@ -196,7 +200,18 @@
throw (StartupAbortedException)t;
}
- PluginId pluginId = config != null ? config.getPluginId() : getPluginByClassName(componentClassName);
+ PluginId pluginId = null;
+ if (config != null) {
+ pluginId = config.getPluginId();
+ }
+ if (pluginId == null || CORE_PLUGIN_ID.equals(pluginId.getIdString())) {
+ pluginId = getPluginByClassName(componentClassName);
+ }
+ if (pluginId == null || CORE_PLUGIN_ID.equals(pluginId.getIdString())) {
+ if (t instanceof PicoPluginExtensionInitializationException) {
+ pluginId = ((PicoPluginExtensionInitializationException)t).getPluginId();
+ }
+ }
if (pluginId != null && !CORE_PLUGIN_ID.equals(pluginId.getIdString())) {
getLogger().warn(t);
@@ -206,7 +221,7 @@
String message =
"Plugin '" + pluginId.getIdString() + "' failed to initialize and will be disabled\n" +
"(reason: " + t.getMessage() + ")\n\n" +
- ApplicationNamesInfo.getInstance().getFullProductName() + " will be restarted.";
+ "Please restart " + ApplicationNamesInfo.getInstance().getFullProductName() + ".";
Main.showMessage("Plugin Error", message, false);
throw new StartupAbortedException(t).exitCode(Main.PLUGIN_ERROR).logError(false);
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java
index 92027af..99d50c7 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java
@@ -148,6 +148,7 @@
// when we leave only system LaFs on other OSes, the order also should be determined as Default, Darcula
Arrays.sort(myLaFs, new Comparator<UIManager.LookAndFeelInfo>() {
+ @Override
public int compare(UIManager.LookAndFeelInfo obj1, UIManager.LookAndFeelInfo obj2) {
String name1 = obj1.getName();
String name2 = obj2.getName();
@@ -162,6 +163,7 @@
/**
* Adds specified listener
*/
+ @Override
public void addLafManagerListener(@NotNull final LafManagerListener l) {
myListenerList.add(LafManagerListener.class, l);
}
@@ -169,6 +171,7 @@
/**
* Removes specified listener
*/
+ @Override
public void removeLafManagerListener(@NotNull final LafManagerListener l) {
myListenerList.remove(LafManagerListener.class, l);
}
@@ -180,11 +183,13 @@
}
}
+ @Override
@NotNull
public String getComponentName() {
return "LafManager";
}
+ @Override
public void initComponent() {
if (myCurrentLaf != null) {
final UIManager.LookAndFeelInfo laf = findLaf(myCurrentLaf.getClassName());
@@ -213,6 +218,7 @@
}
}
+ @Override
public void disposeComponent() {
if (myThemeChangeListener != null) {
Toolkit.getDefaultToolkit().removePropertyChangeListener(GNOME_THEME_PROPERTY_NAME, myThemeChangeListener);
@@ -220,6 +226,7 @@
}
}
+ @Override
public void loadState(final Element element) {
String className = null;
for (final Object o : element.getChildren()) {
@@ -244,6 +251,7 @@
myCurrentLaf = laf;
}
+ @Override
public Element getState() {
Element element = new Element("state");
if (myCurrentLaf != null) {
@@ -257,10 +265,12 @@
return element;
}
+ @Override
public UIManager.LookAndFeelInfo[] getInstalledLookAndFeels(){
return myLaFs.clone();
}
+ @Override
public UIManager.LookAndFeelInfo getCurrentLookAndFeel(){
return myCurrentLaf;
}
@@ -322,6 +332,7 @@
/**
* Sets current LAF. The method doesn't update component hierarchy.
*/
+ @Override
public void setCurrentLookAndFeel(UIManager.LookAndFeelInfo lookAndFeelInfo) {
if (findLaf(lookAndFeelInfo.getClassName()) == null) {
LOG.error("unknown LookAndFeel : " + lookAndFeelInfo);
@@ -458,6 +469,7 @@
* Updates LAF of all windows. The method also updates font of components
* as it's configured in <code>UISettings</code>.
*/
+ @Override
public void updateUI() {
final UIDefaults uiDefaults = UIManager.getLookAndFeelDefaults();
@@ -671,6 +683,7 @@
/**
* Repaints all displayable window.
*/
+ @Override
public void repaintUI(){
Frame[] frames=Frame.getFrames();
for (Frame frame : frames) {
@@ -761,6 +774,7 @@
myDelegate = delegate;
}
+ @Override
public Popup getPopup(final Component owner, final Component contents, final int x, final int y) throws IllegalArgumentException {
final Point point = fixPopupLocation(contents, x, y);
diff --git a/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java b/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java
index 2057169..ba61547 100644
--- a/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java
+++ b/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java
@@ -93,6 +93,7 @@
init();
}
+ @NotNull
public List<T> showAndGetResult() {
show();
return getChosenElements();
diff --git a/platform/platform-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java b/platform/platform-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java
index cf6d25d..a743569 100644
--- a/platform/platform-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java
@@ -75,6 +75,16 @@
}
@Override
+ public void setValue(@NotNull String name, @NotNull String value, @NotNull String defaultValue) {
+ if (value.equals(defaultValue)) {
+ myMap.remove(name);
+ }
+ else {
+ myMap.put(name, value);
+ }
+ }
+
+ @Override
public void unsetValue(String name) {
myMap.remove(name);
}
diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
index 46ca05d..87f1b23 100644
--- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
+++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
@@ -15,6 +15,7 @@
*/
package com.intellij.idea;
+import com.intellij.ide.Bootstrap;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.ConfigImportHelper;
@@ -45,7 +46,7 @@
* @author yole
*/
public class StartupUtil {
- @NonNls public static final String NO_SPLASH = "nosplash";
+ @NonNls public static final String NO_SPLASH = Bootstrap.NO_SPLASH;
private static SocketLock ourLock;
private static String myDefaultLAF;
diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java
index 25882ae..273e580 100644
--- a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java
+++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java
@@ -35,6 +35,7 @@
@State(
name = "UsagesStatistic",
+ roamingType = RoamingType.DISABLED,
storages = {
@Storage(
file = StoragePathMacros.APP_CONFIG + "/usage.statistics.xml"
@@ -67,6 +68,7 @@
}
}
+ @Override
public void loadState(final Element element) {
List groupsList = element.getChildren(GROUP_TAG);
for (Object project : groupsList) {
@@ -92,14 +94,15 @@
}
final String isAllowedValue = element.getAttributeValue(IS_ALLOWED_ATTR);
- setAllowed(StringUtil.isEmptyOrSpaces(isAllowedValue) ? false : Boolean.parseBoolean(isAllowedValue));
+ setAllowed(!StringUtil.isEmptyOrSpaces(isAllowedValue) && Boolean.parseBoolean(isAllowedValue));
final String isShowNotificationValue = element.getAttributeValue(SHOW_NOTIFICATION_ATTR);
- setShowNotification(StringUtil.isEmptyOrSpaces(isShowNotificationValue) ? true : Boolean.parseBoolean(isShowNotificationValue));
+ setShowNotification(StringUtil.isEmptyOrSpaces(isShowNotificationValue) || Boolean.parseBoolean(isShowNotificationValue));
setPeriod(parsePeriod(element.getAttributeValue(PERIOD_ATTR)));
}
+ @Override
public Element getState() {
Element element = new Element("state");
@@ -162,6 +165,7 @@
return Double.parseDouble(priority);
}
+ @Override
@NonNls
@NotNull
public String getComponentName() {
@@ -172,6 +176,7 @@
public void initComponent() {
}
+ @Override
public void disposeComponent() {
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
index e48e2bf..0fd0ab3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
@@ -29,13 +29,14 @@
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.components.ComponentConfig;
-import com.intellij.openapi.components.RoamingType;
import com.intellij.openapi.components.StateStorageException;
import com.intellij.openapi.components.impl.ApplicationPathMacroManager;
import com.intellij.openapi.components.impl.ComponentManagerImpl;
-import com.intellij.openapi.components.impl.stores.*;
+import com.intellij.openapi.components.impl.stores.IApplicationStore;
+import com.intellij.openapi.components.impl.stores.IComponentStore;
+import com.intellij.openapi.components.impl.stores.StoreUtil;
+import com.intellij.openapi.components.impl.stores.StoresFactory;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -518,8 +519,6 @@
myIsFiringLoadingEvent = false;
}
- loadComponentRoamingTypes();
-
HeavyProcessLatch.INSTANCE.processStarted();
try {
getStateStore().load();
@@ -559,23 +558,6 @@
return super.getComponentFromContainer(interfaceClass);
}
- private static void loadComponentRoamingTypes() {
- ExtensionPoint<RoamingTypeExtensionPointBean> point = Extensions.getRootArea().getExtensionPoint("com.intellij.ComponentRoamingType");
- final RoamingTypeExtensionPointBean[] componentRoamingTypes = point.getExtensions();
-
- for (RoamingTypeExtensionPointBean object : componentRoamingTypes) {
-
- assert object.componentName != null;
- assert object.roamingType != null;
-
- final RoamingType type = RoamingType.valueOf(object.roamingType);
-
- assert type != null;
-
- ComponentRoamingManager.getInstance().setRoamingType(object.componentName, type);
- }
- }
-
private void fireBeforeApplicationLoaded() {
for (ApplicationLoadListener listener : ApplicationLoadListener.EP_NAME.getExtensions()) {
try {
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentRoamingManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentRoamingManager.java
index 3d60bca..e78fb56 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentRoamingManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentRoamingManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@
import com.intellij.openapi.components.RoamingType;
import com.intellij.util.ObjectUtils;
import gnu.trove.THashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.Map;
@@ -30,15 +32,13 @@
return OUR_INSTANCE;
}
- public RoamingType getRoamingType(String name) {
- return ObjectUtils.notNull(myRoamingTypeMap.get(name), RoamingType.PER_USER);
+ public RoamingType getRoamingType(@Nullable String name) {
+ return name == null ? RoamingType.PER_USER : ObjectUtils.notNull(myRoamingTypeMap.get(name), RoamingType.PER_USER);
}
- public void setRoamingType(final String name, final RoamingType roamingType) {
- myRoamingTypeMap.put(name, roamingType);
+ public void setRoamingType(@NotNull String name, @NotNull RoamingType roamingType) {
+ if (roamingType != RoamingType.PER_USER) {
+ myRoamingTypeMap.put(name, roamingType);
+ }
}
-
- public boolean typeSpecified(final String name) {
- return myRoamingTypeMap.containsKey(name);
- }
-}
+}
\ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
index 4a6c0ac..f7b548e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
@@ -17,7 +17,7 @@
import com.intellij.diagnostic.IdeErrorsDialog;
import com.intellij.diagnostic.PluginException;
-import com.intellij.ide.plugins.PluginManager;
+import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.components.*;
@@ -226,16 +226,8 @@
private static Element getJdomState(final Object component, final String componentName, @NotNull final StateStorage defaultsStorage)
throws StateStorageException {
ComponentRoamingManager roamingManager = ComponentRoamingManager.getInstance();
- if (!roamingManager.typeSpecified(componentName)) {
- if (component instanceof RoamingTypeDisabled) {
- roamingManager.setRoamingType(componentName, RoamingType.DISABLED);
- }
- else if (component instanceof RoamingTypePerPlatform) {
- roamingManager.setRoamingType(componentName, RoamingType.PER_PLATFORM);
- }
- /*else {
- roamingManager.setRoamingType(componentName, RoamingType.PER_USER);
- }*/
+ if (component instanceof RoamingTypeDisabled) {
+ roamingManager.setRoamingType(componentName, RoamingType.DISABLED);
}
return defaultsStorage.getState(component, componentName, Element.class, null);
}
@@ -261,13 +253,9 @@
}
private <T> String initPersistentComponent(@NotNull final PersistentStateComponent<T> component, final boolean reloadData) {
- final String name = getComponentName(component);
-
- RoamingType roamingTypeFromComponent = getRoamingType(component);
- ComponentRoamingManager roamingManager = ComponentRoamingManager.getInstance();
- if (!roamingManager.typeSpecified(name)) {
- roamingManager.setRoamingType(name, roamingTypeFromComponent);
- }
+ State spec = getStateSpec(component);
+ final String name = spec.name();
+ ComponentRoamingManager.getInstance().setRoamingType(name, spec.roamingType());
doAddComponent(name, component);
if (optimizeTestLoading()) return name;
@@ -283,7 +271,6 @@
}
Storage[] storageSpecs = getComponentStorageSpecs(component, StateStorageOperation.READ);
-
for (Storage storageSpec : storageSpecs) {
StateStorage stateStorage = getStateStorage(storageSpec);
if (stateStorage == null || !stateStorage.hasState(component, name, stateClass, reloadData)) continue;
@@ -299,21 +286,6 @@
return name;
}
- private static RoamingType getRoamingType(final PersistentStateComponent component) {
- if (component instanceof RoamingTypeDisabled) {
- return RoamingType.DISABLED;
- }
- else if (component instanceof RoamingTypePerPlatform) {
- return RoamingType.PER_PLATFORM;
- }
-
- final State stateSpec = getStateSpec(component);
- assert stateSpec != null;
-
- return stateSpec.roamingType();
-
- }
-
@NotNull
private static <T> Class<T> getComponentStateClass(@NotNull final PersistentStateComponent<T> persistentStateComponent) {
final Class persistentStateComponentClass = PersistentStateComponent.class;
@@ -339,18 +311,15 @@
}
public static String getComponentName(@NotNull final PersistentStateComponent<?> persistentStateComponent) {
- final State stateSpec = getStateSpec(persistentStateComponent);
- if (stateSpec == null) {
- LOG.error("Null state spec for " + persistentStateComponent);
- }
- return stateSpec.name();
+ return getStateSpec(persistentStateComponent).name();
}
+ @NotNull
private static <T> State getStateSpec(@NotNull final PersistentStateComponent<T> persistentStateComponent) {
final Class<? extends PersistentStateComponent> aClass = persistentStateComponent.getClass();
final State stateSpec = aClass.getAnnotation(State.class);
if (stateSpec == null) {
- final PluginId pluginId = PluginManager.getPluginByClassName(aClass.getName());
+ final PluginId pluginId = PluginManagerCore.getPluginByClassName(aClass.getName());
if (pluginId != null) {
throw new PluginException("No @State annotation found in " + aClass, pluginId);
}
@@ -359,7 +328,6 @@
return stateSpec;
}
-
@NotNull
protected <T> Storage[] getComponentStorageSpecs(@NotNull final PersistentStateComponent<T> persistentStateComponent,
final StateStorageOperation operation) throws StateStorageException {
@@ -517,12 +485,8 @@
public boolean isReloadPossible(@NotNull final Set<String> componentNames) {
for (String componentName : componentNames) {
final Object component = myComponents.get(componentName);
-
- if (component != null) {
- if (!(component instanceof PersistentStateComponent)) return false;
-
- final State stateSpec = getStateSpec((PersistentStateComponent<? extends Object>)component);
- if (stateSpec == null || !stateSpec.reloadable()) return false;
+ if (component != null && (!(component instanceof PersistentStateComponent) || !getStateSpec((PersistentStateComponent<?>)component).reloadable())) {
+ return false;
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentVersionListener.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentVersionListener.java
index f452d66..85b74fc 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentVersionListener.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentVersionListener.java
@@ -16,11 +16,5 @@
package com.intellij.openapi.components.impl.stores;
public interface ComponentVersionListener {
- ComponentVersionListener EMPTY = new ComponentVersionListener(){
- public void componentStateChanged(String componentName) {
-
- }
- } ;
-
void componentStateChanged(String componentName);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java
index 827896f..7ee3a54 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java
@@ -140,7 +140,7 @@
LOG.error(e);
}
}
- final ExternalizationSession session = new MyExternalizationSession(myPathMacroSubstitutor, myStorageData.clone());
+ final ExternalizationSession session = new MyExternalizationSession(myStorageData.clone());
mySession = session;
return session;
@@ -330,7 +330,7 @@
private class MyExternalizationSession implements ExternalizationSession {
private final DirectoryStorageData myStorageData;
- private MyExternalizationSession(final TrackingPathMacroSubstitutor pathMacroSubstitutor, final DirectoryStorageData storageData) {
+ private MyExternalizationSession(final DirectoryStorageData storageData) {
myStorageData = storageData;
}
@@ -344,16 +344,13 @@
private void setState(final String componentName, @NotNull Object state, final Storage storageSpec) throws StateStorageException {
try {
final Element element = DefaultStateSerializer.serializeState(state, storageSpec);
-
- final List<Pair<Element, String>> states = mySplitter.splitState(element);
- for (Pair<Element, String> pair : states) {
+ for (Pair<Element, String> pair : mySplitter.splitState(element)) {
Element e = pair.first;
String name = pair.second;
Element statePart = new Element(StorageData.COMPONENT);
statePart.setAttribute(StorageData.NAME, componentName);
- e.detach();
- statePart.addContent(e);
+ statePart.addContent(e.detach());
myStorageData.put(componentName, myDir.getChild(name), statePart, false);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java
index f8cf115..75b0999 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java
@@ -134,7 +134,9 @@
public void resetProviderCache() {
myProviderUpToDateHash = -1;
- myProviderVersions = null;
+ if (myRemoteVersionProvider != null) {
+ myRemoteVersionProvider.myProviderVersions = null;
+ }
}
private class FileSaveSession extends MySaveSession {
@@ -322,7 +324,7 @@
@Nullable
public File updateFileExternallyFromStreamProviders() throws IOException {
- StorageData loadedData = loadData(true, myListener);
+ StorageData loadedData = loadData(true);
Document document = getDocument(loadedData);
if (physicalContentNeedsSave(document)) {
File file = new File(myFile.getAbsolutePath());
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java
index 68efd2e..f9ac272 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java
@@ -338,10 +338,14 @@
@Override
public String getPresentableUrl() {
- if (myProject.isDefault()) return null;
+ if (myProject.isDefault()) {
+ return null;
+ }
if (myPresentableUrl == null) {
- final String url = myScheme == StorageScheme.DIRECTORY_BASED ? getProjectBasePath() : getProjectFilePath();
- myPresentableUrl = url != null ? FileUtil.toSystemDependentName(url) : url;
+ String url = myScheme == StorageScheme.DIRECTORY_BASED ? getProjectBasePath() : getProjectFilePath();
+ if (url != null) {
+ myPresentableUrl = FileUtil.toSystemDependentName(url);
+ }
}
return myPresentableUrl;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
index 93d3e9a..499eda6 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
@@ -37,7 +37,7 @@
TrackingPathMacroSubstitutor getMacroSubstitutor();
@Nullable
- StateStorage getStateStorage(@NotNull Storage storageSpec) throws StateStorageException;
+ StateStorage getStateStorage(@NotNull Storage storageSpec) throws StateStorageException;
@Nullable
StateStorage getFileStateStorage(String fileName);
@@ -59,7 +59,7 @@
String expandMacros(String file);
@Deprecated
- void registerStreamProvider(StreamProvider streamProvider, final RoamingType type);
+ void registerStreamProvider(@SuppressWarnings("deprecation") StreamProvider streamProvider, final RoamingType type);
void setStreamProvider(@Nullable com.intellij.openapi.components.impl.stores.StreamProvider streamProvider);
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
index 186ba20..25c940a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
@@ -144,6 +144,9 @@
public Collection<String> getStorageFileNames() {
myStorageLock.lock();
try {
+ if (myStorages.isEmpty()) {
+ return Collections.emptyList();
+ }
return Collections.unmodifiableCollection(myStorages.keySet());
}
finally {
@@ -488,7 +491,7 @@
}
@Override
- public void registerStreamProvider(com.intellij.openapi.options.StreamProvider streamProvider, final RoamingType type) {
+ public void registerStreamProvider(@SuppressWarnings("deprecation") com.intellij.openapi.options.StreamProvider streamProvider, final RoamingType type) {
synchronized (myOldStreamProvider) {
myOldStreamProvider.myStreamProviders.add(new OldStreamProviderAdapter(streamProvider, type));
}
@@ -547,6 +550,11 @@
private final List<OldStreamProviderAdapter> myStreamProviders = new SmartList<OldStreamProviderAdapter>();
@Override
+ public boolean isVersioningRequired() {
+ return true;
+ }
+
+ @Override
public boolean isEnabled() {
for (StreamProvider provider : myStreamProviders) {
if (provider.isEnabled()) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java
index bf03cfb..cf77ee3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java
@@ -15,6 +15,15 @@
public abstract boolean isEnabled();
/**
+ * If true, special version file per storage file will keep version of component.
+ * On load remote data will be ignored if local version of component is higher.
+ * If your storage is always in connected state (for example, git provides you local working copy), you don't need it.
+ */
+ public boolean isVersioningRequired() {
+ return false;
+ }
+
+ /**
* fileSpec Only main fileSpec, not version
*/
public boolean isApplicable(@NotNull String fileSpec, @NotNull RoamingType roamingType) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java
index 8c2c85b..650419f 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java
@@ -59,9 +59,7 @@
private final Map<String, Object> myStorageComponentStates = new THashMap<String, Object>(); // at loading we store Element, on setState Integer of hash// at loading we store Element, on setState Integer of hash
private final ComponentVersionProvider myLocalVersionProvider;
- private final ComponentVersionProvider myRemoteVersionProvider;
-
- protected TObjectLongHashMap<String> myProviderVersions;
+ protected final RemoteComponentVersionProvider myRemoteVersionProvider;
protected ComponentVersionListener myListener = new ComponentVersionListener(){
@Override
@@ -72,7 +70,7 @@
private boolean myDisposed;
- protected XmlElementStorage(@Nullable final TrackingPathMacroSubstitutor pathMacroSubstitutor,
+ protected XmlElementStorage(@Nullable TrackingPathMacroSubstitutor pathMacroSubstitutor,
@NotNull Disposable parentDisposable,
@NotNull String rootElementName,
@Nullable StreamProvider streamProvider,
@@ -86,24 +84,7 @@
Disposer.register(parentDisposable, this);
myLocalVersionProvider = localComponentVersionsProvider;
-
- myRemoteVersionProvider = new ComponentVersionProvider() {
- @Override
- public long getVersion(String name) {
- if (myProviderVersions == null) {
- loadProviderVersions();
- }
- return myProviderVersions.get(name);
- }
-
- @Override
- public void changeVersion(String name, long version) {
- if (myProviderVersions == null) {
- loadProviderVersions();
- }
- myProviderVersions.put(name, version);
- }
- };
+ myRemoteVersionProvider = streamProvider == null || !streamProvider.isVersioningRequired() ? null : new RemoteComponentVersionProvider();
}
protected boolean isDisposed() {
@@ -145,12 +126,12 @@
return myLoadedData;
}
- myLoadedData = loadData(true, myListener);
+ myLoadedData = loadData(true);
return myLoadedData;
}
@NotNull
- protected StorageData loadData(boolean useProvidersData, @SuppressWarnings("UnusedParameters") ComponentVersionListener listener) throws StateStorageException {
+ protected StorageData loadData(boolean useProvidersData) throws StateStorageException {
Document document = loadDocument();
StorageData result = createStorageData();
@@ -158,10 +139,19 @@
loadState(result, document.getRootElement());
}
- if (myStreamProvider != null && useProvidersData && myStreamProvider.isEnabled()) {
+ if (useProvidersData && myStreamProvider != null && myStreamProvider.isEnabled()) {
for (RoamingType roamingType : RoamingType.values()) {
if (roamingType != RoamingType.DISABLED && roamingType != RoamingType.GLOBAL) {
- loadProviderData(result, roamingType, myStreamProvider);
+ try {
+ Document sharedDocument = StorageUtil.loadDocument(myStreamProvider.loadContent(myFileSpec, roamingType));
+ if (sharedDocument != null) {
+ filterOutOfDate(sharedDocument.getRootElement());
+ loadState(result, sharedDocument.getRootElement());
+ }
+ }
+ catch (Exception e) {
+ LOG.warn(e);
+ }
}
}
}
@@ -169,19 +159,6 @@
return result;
}
- private void loadProviderData(StorageData result, RoamingType roamingType, StreamProvider streamProvider) {
- try {
- Document sharedDocument = StorageUtil.loadDocument(streamProvider.loadContent(myFileSpec, roamingType));
- if (sharedDocument != null) {
- filterOutOfDateAndDisabledForRoamingComponents(sharedDocument.getRootElement(), roamingType);
- loadState(result, sharedDocument.getRootElement());
- }
- }
- catch (Exception e) {
- LOG.warn(e);
- }
- }
-
protected void loadState(final StorageData result, final Element element) throws StateStorageException {
if (myPathMacroSubstitutor != null) {
myPathMacroSubstitutor.expandPaths(element);
@@ -433,59 +410,57 @@
}
private boolean saveForProvider(@NotNull StreamProvider streamProvider) {
- // it is not really correctly implemented - stream provider can save not the whole document, but only filtered (per roaming type)
- // but right now it is not our case, so, we should refine it later, but it not leads to bug now
- boolean result = false;
- for (final RoamingType roamingType : RoamingType.values()) {
- if (roamingType == RoamingType.DISABLED || !streamProvider.isApplicable(myFileSpec, roamingType)) {
- continue;
- }
+ if (!streamProvider.isApplicable(myFileSpec, RoamingType.PER_USER)) {
+ return false;
+ }
- Document document = getDocumentToSave();
- if (document.getRootElement().getChildren().isEmpty()) {
- continue;
- }
+ Document document = getDocumentToSave();
+ Element rootElement = document.getRootElement();
+ if (rootElement.getChildren().isEmpty()) {
+ return false;
+ }
- Document actualDocument;
- ElementFilter roamingFilter = new ElementFilter(StorageData.COMPONENT) {
- @Override
- public boolean matches(Object obj) {
- return super.matches(obj) && myComponentRoamingManager.getRoamingType(((Element)obj).getAttributeValue(StorageData.NAME)) != roamingType;
- }
- };
+ // skip the whole document if some component has disabled roaming type
+ // you must not store components with different roaming types in one document
+ // one exclusion: workspace file (you don't have choice in this case)
+ // for example, it is important for ICS ProjectId - we cannot keep project in another place,
+ // but this project id must not be shared
+ if (!myFileSpec.equals(StoragePathMacros.WORKSPACE_FILE) &&
+ rootElement.getContent(new RoamingElementFilter(RoamingType.DISABLED)).iterator().hasNext()) {
+ return false;
+ }
- if (document.getRootElement().getContent(roamingFilter).iterator().hasNext()) {
- actualDocument = document.clone();
- Iterator<Element> iterator = actualDocument.getRootElement().getContent(roamingFilter).iterator();
- while (iterator.hasNext()) {
- iterator.next();
- iterator.remove();
- }
+ RoamingElementFilter perPlatformFilter = new RoamingElementFilter(RoamingType.PER_PLATFORM);
+ if (rootElement.getContent(perPlatformFilter).iterator().hasNext()) {
+ return doSaveForProvider(rootElement, new RoamingElementFilter(RoamingType.PER_USER)) ||
+ doSaveForProvider(rootElement, perPlatformFilter);
+ }
+ else {
+ return doSaveForProvider(document, RoamingType.PER_USER, streamProvider);
+ }
+ }
- if (actualDocument.getRootElement().getChildren().isEmpty()) {
- continue;
- }
- }
- else {
- actualDocument = document;
- }
+ private boolean doSaveForProvider(Element element, RoamingElementFilter filter) {
+ Element copiedElement = JDOMUtil.cloneElement(element, filter);
+ return copiedElement != null && doSaveForProvider(new Document(copiedElement), filter.myRoamingType, myStreamProvider);
+ }
- try {
- if (StorageUtil.doSendContent(streamProvider, myFileSpec, actualDocument, roamingType, true)) {
- result = true;
- }
+ private boolean doSaveForProvider(Document actualDocument, RoamingType roamingType, StreamProvider streamProvider) {
+ try {
+ boolean result = StorageUtil.doSendContent(streamProvider, myFileSpec, actualDocument, roamingType, true);
+ if (streamProvider.isVersioningRequired()) {
TObjectLongHashMap<String> versions = loadVersions(actualDocument.getRootElement().getChildren(StorageData.COMPONENT));
if (!versions.isEmpty()) {
Document versionDoc = new Document(StateStorageManagerImpl.createComponentVersionsXml(versions));
StorageUtil.doSendContent(streamProvider, myFileSpec + VERSION_FILE_SUFFIX, versionDoc, roamingType, true);
}
}
- catch (IOException e) {
- LOG.warn(e);
- }
+ return result;
}
-
- return result;
+ catch (IOException e) {
+ LOG.warn(e);
+ return false;
+ }
}
private boolean isHashUpToDate(final Integer hash) {
@@ -527,6 +502,21 @@
return null;
}
+
+ private class RoamingElementFilter extends ElementFilter {
+ final RoamingType myRoamingType;
+
+ public RoamingElementFilter(RoamingType roamingType) {
+ super(StorageData.COMPONENT);
+
+ myRoamingType = roamingType;
+ }
+
+ @Override
+ public boolean matches(Object obj) {
+ return super.matches(obj) && myComponentRoamingManager.getRoamingType(((Element)obj).getAttributeValue(StorageData.NAME)) == myRoamingType;
+ }
+ }
}
private TObjectLongHashMap<String> loadVersions(List<Element> elements) {
@@ -554,7 +544,7 @@
@Override
public void reload(@NotNull final Set<String> changedComponents) throws StateStorageException {
- final StorageData storageData = loadData(false, myListener);
+ final StorageData storageData = loadData(false);
final StorageData oldLoadedData = myLoadedData;
@@ -578,12 +568,16 @@
myLoadedData = storageData;
}
- private void filterOutOfDateAndDisabledForRoamingComponents(Element element, RoamingType roamingType) {
+ private void filterOutOfDate(Element element) {
+ if (myRemoteVersionProvider == null) {
+ return;
+ }
+
Iterator<Element> iterator = element.getContent(new ElementFilter(StorageData.COMPONENT)).iterator();
while (iterator.hasNext()) {
String name = iterator.next().getAttributeValue(StorageData.NAME);
- long remoteVersion;
- if (myComponentRoamingManager.getRoamingType(name) != roamingType || (remoteVersion = myRemoteVersionProvider.getVersion(name)) <= myLocalVersionProvider.getVersion(name)) {
+ long remoteVersion = myRemoteVersionProvider.getVersion(name);
+ if (remoteVersion <= myLocalVersionProvider.getVersion(name)) {
iterator.remove();
}
else {
@@ -592,30 +586,50 @@
}
}
- private void loadProviderVersions() {
- if (myStreamProvider == null) {
- return;
+ @Nullable
+ Document logComponents() throws StateStorageException {
+ return mySession instanceof MySaveSession ? getDocument(((MySaveSession)mySession).myStorageData) : null;
+ }
+
+ protected class RemoteComponentVersionProvider implements ComponentVersionProvider {
+ protected TObjectLongHashMap<String> myProviderVersions;
+
+ @Override
+ public long getVersion(String name) {
+ if (myProviderVersions == null) {
+ loadProviderVersions();
+ }
+ return myProviderVersions == null ? -1 : myProviderVersions.get(name);
}
- myProviderVersions = new TObjectLongHashMap<String>();
- for (RoamingType type : RoamingType.values()) {
- Document doc = null;
- if (myStreamProvider.isEnabled()) {
+ @Override
+ public void changeVersion(String name, long version) {
+ if (myProviderVersions == null) {
+ loadProviderVersions();
+ }
+ if (myProviderVersions != null) {
+ myProviderVersions.put(name, version);
+ }
+ }
+
+ private void loadProviderVersions() {
+ assert myStreamProvider != null;
+ if (!myStreamProvider.isEnabled()) {
+ return;
+ }
+
+ myProviderVersions = new TObjectLongHashMap<String>();
+ for (RoamingType type : RoamingType.values()) {
try {
- doc = StorageUtil.loadDocument(myStreamProvider.loadContent(myFileSpec + VERSION_FILE_SUFFIX, type));
+ Document doc = StorageUtil.loadDocument(myStreamProvider.loadContent(myFileSpec + VERSION_FILE_SUFFIX, type));
+ if (doc != null) {
+ StateStorageManagerImpl.loadComponentVersions(myProviderVersions, doc);
+ }
}
catch (IOException e) {
LOG.debug(e);
}
}
- if (doc != null) {
- StateStorageManagerImpl.loadComponentVersions(myProviderVersions, doc);
- }
}
}
-
- @Nullable
- Document logComponents() throws StateStorageException {
- return mySession instanceof MySaveSession ? getDocument(((MySaveSession)mySession).myStorageData) : null;
- }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java
index 2fff109..dafe24d 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java
@@ -35,14 +35,16 @@
public class EditorHighlighterFactoryImpl extends EditorHighlighterFactory {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.highlighter.EditorHighlighterFactoryImpl");
+ @NotNull
@Override
- public EditorHighlighter createEditorHighlighter(SyntaxHighlighter highlighter, final EditorColorsScheme colors) {
+ public EditorHighlighter createEditorHighlighter(SyntaxHighlighter highlighter, @NotNull final EditorColorsScheme colors) {
if (highlighter == null) highlighter = new PlainSyntaxHighlighter();
return new LexerEditorHighlighter(highlighter, colors);
}
+ @NotNull
@Override
- public EditorHighlighter createEditorHighlighter(final FileType fileType, final EditorColorsScheme settings, final Project project) {
+ public EditorHighlighter createEditorHighlighter(@NotNull final FileType fileType, @NotNull final EditorColorsScheme settings, final Project project) {
if (fileType instanceof LanguageFileType) {
return FileTypeEditorHighlighterProviders.INSTANCE.forFileType(fileType).getEditorHighlighter(project, fileType, null, settings);
}
@@ -51,11 +53,13 @@
return createEditorHighlighter(highlighter, settings);
}
+ @NotNull
@Override
- public EditorHighlighter createEditorHighlighter(final Project project, final FileType fileType) {
+ public EditorHighlighter createEditorHighlighter(final Project project, @NotNull final FileType fileType) {
return createEditorHighlighter(fileType, EditorColorsManager.getInstance().getGlobalScheme(), project);
}
+ @NotNull
@Override
public EditorHighlighter createEditorHighlighter(@NotNull VirtualFile vFile, @NotNull EditorColorsScheme settings, @Nullable Project project) {
FileType fileType = vFile.getFileType();
@@ -105,18 +109,21 @@
return fileType;
}
+ @NotNull
@Override
- public EditorHighlighter createEditorHighlighter(final Project project, final VirtualFile file) {
+ public EditorHighlighter createEditorHighlighter(final Project project, @NotNull final VirtualFile file) {
return createEditorHighlighter(file, EditorColorsManager.getInstance().getGlobalScheme(), project);
}
+ @NotNull
@Override
- public EditorHighlighter createEditorHighlighter(final Project project, final String fileName) {
+ public EditorHighlighter createEditorHighlighter(final Project project, @NotNull final String fileName) {
return createEditorHighlighter(EditorColorsManager.getInstance().getGlobalScheme(), fileName, project);
}
+ @NotNull
@Override
- public EditorHighlighter createEditorHighlighter(final EditorColorsScheme settings, final String fileName, @Nullable final Project project) {
+ public EditorHighlighter createEditorHighlighter(@NotNull final EditorColorsScheme settings, @NotNull final String fileName, @Nullable final Project project) {
return createEditorHighlighter(new LightVirtualFile(fileName), settings, project);
}
}
\ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHeaderComponent.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHeaderComponent.java
index f149e0a..e849363 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHeaderComponent.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHeaderComponent.java
@@ -34,19 +34,23 @@
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
- Color GRADIENT_C1 = new JBColor(getBackground(), JBColor.background());
+ paintGradient(g, this);
+ }
+
+ public static void paintGradient(Graphics g, JComponent c) {
+ Color GRADIENT_C1 = new JBColor(c.getBackground(), JBColor.background());
Color GRADIENT_C2 = new JBColor(new Color(Math.max(0, GRADIENT_C1.getRed() - 0x18), Math.max(0, GRADIENT_C1.getGreen() - 0x18),
Math.max(0, GRADIENT_C1.getBlue() - 0x18)), Gray._75);
final Graphics2D g2d = (Graphics2D)g;
if (!UIUtil.isUnderGTKLookAndFeel()) {
- g2d.setPaint(UIUtil.getGradientPaint(0, 0, GRADIENT_C1, 0, getHeight(), GRADIENT_C2));
- g2d.fillRect(1, 1, getWidth(), getHeight() - 1);
+ g2d.setPaint(UIUtil.getGradientPaint(0, 0, GRADIENT_C1, 0, c.getHeight(), GRADIENT_C2));
+ g2d.fillRect(1, 1, c.getWidth(), c.getHeight() - 1);
g2d.setPaint(null);
}
g.setColor(UIUtil.getBorderColor());
- g.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1);
+ g.drawLine(0, c.getHeight() - 1, c.getWidth(), c.getHeight() - 1);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
index ea637b2..d233f37 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
@@ -94,7 +94,7 @@
EditorMarkupModelImpl(@NotNull EditorImpl editor) {
super(editor.getDocument());
myEditor = editor;
- myEditorFragmentRenderer = new EditorFragmentRenderer(0, Collections.<RangeHighlighterEx>emptyList(), 0);
+ myEditorFragmentRenderer = new EditorFragmentRenderer();
}
private int offsetToLine(int offset, Document document) {
@@ -184,7 +184,7 @@
collectRangeHighlighters(this, line, highlighters);
collectRangeHighlighters((MarkupModelEx)DocumentMarkupModel.forDocument(myEditor.getDocument(), getEditor().getProject(), true), line,
highlighters);
- myEditorFragmentRenderer.update(line, highlighters, 0);
+ myEditorFragmentRenderer.update(line, highlighters);
HintHint hint = new HintHint(me).setAwtTooltip(true).setPreferredPosition(Balloon.Position.atLeft).setShowImmediately(true)
.setAnimationEnabled(false);
myEditorFragmentRenderer.show(myEditor, me.getPoint(), true, ERROR_STRIPE_TOOLTIP_GROUP, hint);
@@ -267,9 +267,11 @@
private void doClick(final MouseEvent e) {
RangeHighlighter marker = getNearestRangeHighlighter(e);
int offset;
+ LogicalPosition logicalPositionToScroll = null;
if (marker == null) {
if (myEditorPreviewHint != null) {
- offset = myEditor.getDocument().getLineStartOffset(getLineByEvent(e)/*myEditorFragmentRenderer.myLine*/);
+ logicalPositionToScroll = myEditor.visualToLogicalPosition(new VisualPosition(myEditorFragmentRenderer.myStartLine, 0));
+ offset = myEditor.getDocument().getLineStartOffset(logicalPositionToScroll.line);
} else {
return;
}
@@ -281,7 +283,7 @@
if (doc.getLineCount() > 0 && myEditorPreviewHint == null) {
// Necessary to expand folded block even if navigating just before one
// Very useful when navigating to first unused import statement.
- int lineEnd = doc.getLineEndOffset(myEditorFragmentRenderer.myLine);
+ int lineEnd = doc.getLineEndOffset(doc.getLineNumber(offset));
myEditor.getCaretModel().moveToOffset(lineEnd);
}
@@ -289,8 +291,8 @@
myEditor.getSelectionModel().removeSelection();
ScrollingModel scrollingModel = myEditor.getScrollingModel();
scrollingModel.disableAnimation();
- if (myEditorPreviewHint != null) {
- int lineY = myEditor.logicalPositionToXY(new LogicalPosition(myEditorFragmentRenderer.myStartLine, 0)).y;
+ if (logicalPositionToScroll != null) {
+ int lineY = myEditor.logicalPositionToXY(logicalPositionToScroll).y;
int relativePopupOffset = myEditorFragmentRenderer.myRelativeY;
scrollingModel.scrollVertically(lineY - relativePopupOffset);
}
@@ -1014,20 +1016,18 @@
private class EditorFragmentRenderer implements TooltipRenderer {
private int myLine;
private Collection<RangeHighlighterEx> myHighlighters;
- private int myMouseX;
private BufferedImage myImage;
private int myStartLine;
private int myEndLine;
private int myRelativeY;
- private EditorFragmentRenderer(int currentLine, Collection<RangeHighlighterEx> rangeHighlighters, int mouseX) {
- update(currentLine, rangeHighlighters, mouseX);
+ private EditorFragmentRenderer() {
+ update(0, Collections.<RangeHighlighterEx>emptyList());
}
- public void update(int currentLine, Collection<RangeHighlighterEx> rangeHighlighters, int mouseX) {
+ public void update(int currentLine, Collection<RangeHighlighterEx> rangeHighlighters) {
myLine = currentLine;
myHighlighters = rangeHighlighters;
- myMouseX = mouseX;
myImage = null;
myStartLine = Math.max(0, myLine - myPreviewLines);
myEndLine = Math.min(myEditor.getDocument().getLineCount() - 1, myLine + myPreviewLines + 1);
@@ -1043,13 +1043,13 @@
if (myEditorPreviewHint == null) {
final JPanel editorFragmentPreviewPanel = new JPanel() {
private static final int R = 6;
-
+ private static final int LEFT_INDENT = BalloonImpl.ARC + 5;
@Override
public Dimension getPreferredSize() {
int width = myEditor.getGutterComponentEx().getWidth();
width += Math.min(myEditor.getScrollingModel().getVisibleArea().width, myEditor.getContentComponent().getWidth());
- return new Dimension(width - BalloonImpl.POINTER_WIDTH, myEditor.getLineHeight() * (myEndLine - myStartLine));
+ return new Dimension(width - BalloonImpl.POINTER_WIDTH - LEFT_INDENT, myEditor.getLineHeight() * (myEndLine - myStartLine));
}
@Override
@@ -1077,7 +1077,7 @@
exs.add(rangeHighlighter);
}
}
- AffineTransform translateInstance = AffineTransform.getTranslateInstance(myMouseX, lineShift);
+ AffineTransform translateInstance = AffineTransform.getTranslateInstance(-LEFT_INDENT, lineShift);
translateInstance.preConcatenate(transform);
g2d.setTransform(translateInstance);
EditorGutterComponentEx gutterComponentEx = myEditor.getGutterComponentEx();
@@ -1086,7 +1086,7 @@
gutterComponentEx.paint(g2d);
JComponent contentComponent = myEditor.getContentComponent();
g2d.setClip(width, 0, contentComponent.getWidth(), contentComponent.getHeight());
- translateInstance = AffineTransform.getTranslateInstance(width - myMouseX, lineShift);
+ translateInstance = AffineTransform.getTranslateInstance(width - LEFT_INDENT, lineShift);
translateInstance.preConcatenate(transform);
g2d.setTransform(translateInstance);
contentComponent.paint(g2d);
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/PlatformFileTypeFactory.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/PlatformFileTypeFactory.java
index ad5fd0f..7f550f9 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/PlatformFileTypeFactory.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/PlatformFileTypeFactory.java
@@ -25,7 +25,7 @@
public class PlatformFileTypeFactory extends FileTypeFactory {
public void createFileTypes(@NotNull final FileTypeConsumer consumer) {
consumer.consume(ArchiveFileType.INSTANCE, "zip;jar;war;ear;swc;ane;egg;apk");
- consumer.consume(PlainTextFileType.INSTANCE, "txt;sh;bat;cmd;policy;log;cgi;MF;jad;jam;htaccess");
+ consumer.consume(PlainTextFileType.INSTANCE, "txt;sh;bat;cmd;policy;log;cgi;MF;jad;jam;htaccess;rb");
consumer.consume(NativeFileType.INSTANCE, "doc;docx;xls;xlsx;ppt;pptx;mdb;vsd;pdf;hlp;chm;odt");
consumer.consume(UnknownFileType.INSTANCE);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java
index 4965ae0..f77ab13 100644
--- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java
@@ -18,7 +18,7 @@
import com.intellij.icons.AllIcons;
import com.intellij.ide.actionMacro.ActionMacro;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
-import com.intellij.ide.plugins.PluginManager;
+import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.ide.ui.search.SearchUtil;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
@@ -69,7 +69,7 @@
final KeymapManagerEx keymapManager = KeymapManagerEx.getInstanceEx();
ActionManagerEx managerEx = ActionManagerEx.getInstanceEx();
final List<IdeaPluginDescriptor> plugins = new ArrayList<IdeaPluginDescriptor>();
- Collections.addAll(plugins, PluginManager.getPlugins());
+ Collections.addAll(plugins, PluginManagerCore.getPlugins());
Collections.sort(plugins, new Comparator<IdeaPluginDescriptor>() {
public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) {
return o1.getName().compareTo(o2.getName());
@@ -150,7 +150,7 @@
return filter == null ? !actionBound : !actionBound && filter.value(action);
}
- return filter == null ? true : filter.value(action);
+ return filter == null || filter.value(action);
}
};
}
@@ -214,9 +214,11 @@
? ((DefaultActionGroup)actionGroup).getChildActionsOrStubs()
: actionGroup.getChildren(null);
- for (int i = 0; i < children.length; i++) {
- AnAction action = children[i];
- LOG.assertTrue(action != null, groupName + " contains null actions");
+ for (AnAction action : children) {
+ if (action == null) {
+ LOG.error(groupName + " contains null actions");
+ continue;
+ }
if (action instanceof ActionGroup) {
Group subGroup = createGroup((ActionGroup)action, getName(action), null, null, ignore, filtered, normalizeSeparators);
if (subGroup.getSize() > 0) {
@@ -234,7 +236,7 @@
else if (action instanceof Separator) {
group.addSeparator();
}
- else if (action != null) {
+ else {
String id = action instanceof ActionStub ? ((ActionStub)action).getId() : actionManager.getId(action);
if (id != null) {
if (id.startsWith(TOOL_ACTION_PREFIX)) continue;
@@ -490,7 +492,7 @@
.isComponentHighlighted(lowerText, insensitiveFilter, force, null)) {
return true;
}
- else if (lowerText.indexOf(insensitiveFilter) != -1) {
+ else if (lowerText.contains(insensitiveFilter)) {
return true;
}
}
@@ -501,7 +503,7 @@
.isComponentHighlighted(insensitiveDescription, insensitiveFilter, force, null)) {
return true;
}
- else if (insensitiveDescription.indexOf(insensitiveFilter) != -1) {
+ else if (insensitiveDescription.contains(insensitiveFilter)) {
return true;
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/SchemeImporterEP.java b/platform/platform-impl/src/com/intellij/openapi/options/SchemeImporterEP.java
new file mode 100644
index 0000000..4202ee4
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/options/SchemeImporterEP.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.options;
+
+import com.intellij.openapi.extensions.AbstractExtensionPointBean;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.util.LazyInstance;
+import com.intellij.util.xmlb.annotations.Attribute;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author Rustam Vishnyakov
+ */
+public class SchemeImporterEP <S extends Scheme> extends AbstractExtensionPointBean {
+
+ public static ExtensionPointName<SchemeImporterEP> EP_NAME = ExtensionPointName.create("com.intellij.schemeImporter");
+
+ @Attribute("name")
+ public String name;
+
+ @Attribute("schemeClass")
+ public String schemeClass;
+
+ @Attribute("implementationClass")
+ public String implementationClass;
+
+ private final LazyInstance<SchemeImporter<S>> myImporterInstance = new LazyInstance<SchemeImporter<S>>() {
+ @Override
+ protected Class<SchemeImporter<S>> getInstanceClass() throws ClassNotFoundException {
+ return findClass(implementationClass);
+ }
+ };
+
+ public SchemeImporter<S> getInstance() {
+ return myImporterInstance.getValue();
+ }
+
+ /**
+ * Finds extensions supporting the given <code>schemeClass</code>
+ * @param schemeClass The class of the scheme to search extensions for.
+ * @return A collection of importers capable of importing schemes of the given class. An empty collection is returned if there are
+ * no matching importers.
+ */
+ @NotNull
+ public static <S extends Scheme> Collection<SchemeImporterEP<S>> getExtensions(Class<S> schemeClass) {
+ List<SchemeImporterEP<S>> importers = new ArrayList<SchemeImporterEP<S>>();
+ for (SchemeImporterEP<?> importerEP : EP_NAME.getExtensions()) {
+ if (schemeClass.getName().equals(importerEP.schemeClass)) {
+ //noinspection unchecked
+ importers.add((SchemeImporterEP<S>)importerEP);
+ }
+ }
+ return importers;
+ }
+
+
+ /**
+ * Find an importer for the given name and scheme class. It is allowed for importers to have the same name but different scheme classes.
+ * @param name The importer name as defined in plug-in configuration.
+ * @param schemeClass The scheme class the importer has to support.
+ * @return The found importer or null if there are no importers for the given name and scheme class.
+ */
+ @Nullable
+ public static <S extends Scheme> SchemeImporter<S> getImporter(@NotNull String name, Class<S> schemeClass) {
+ for (SchemeImporterEP<S> importerEP : getExtensions(schemeClass)) {
+ if (name.equals(importerEP.name)) {
+ return importerEP.getInstance();
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java
index d2a5e85..376cfcf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java
@@ -572,7 +572,7 @@
schemeKey.getExternalInfo().setCurrentFileName(fileName);
}
- private static long computeHashValue(final Document document) throws IOException {
+ private static long computeHashValue(final Document document) {
return JDOMUtil.getTreeHash(document);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java
index 063cb2f..42495b5 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java
@@ -236,7 +236,7 @@
if (actualNames != null) {
String currentName = child.getName();
String actualName = actualNames.get(currentName);
- if (!currentName.equals(actualName)) {
+ if (actualName != null && !currentName.equals(actualName)) {
scheduleAttributeChange(child, VirtualFile.PROP_NAME, currentName, actualName);
}
}
diff --git a/platform/platform-impl/src/com/intellij/ui/CellRendererPanel.java b/platform/platform-impl/src/com/intellij/ui/CellRendererPanel.java
new file mode 100644
index 0000000..cf488e1
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ui/CellRendererPanel.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ui;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * Cell renderer CPU optimization.
+ * @see javax.swing.table.DefaultTableCellRenderer#invalidate()
+ *
+ * @author gregsh
+ */
+public class CellRendererPanel extends JPanel {
+ // BEGIN no validation methods --------------
+ @Override
+ public void doLayout() {
+ if (getComponentCount() != 1) return;
+ getComponent(0).setBounds(0, 0, getWidth(), getHeight());
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ if (getComponentCount() != 1) return super.getPreferredSize();
+ return getComponent(0).getPreferredSize();
+ }
+
+ public void invalidate() {
+ }
+
+ public void validate() {
+ doLayout();
+ }
+
+ public void revalidate() {
+ }
+
+ public void repaint(long tm, int x, int y, int width, int height) {
+ }
+
+ public void repaint(Rectangle r) {
+ }
+
+ public void repaint() {
+ }
+
+// END no validation methods --------------
+}
diff --git a/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java b/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java
index fe649b3..5a07cbd 100644
--- a/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java
+++ b/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java
@@ -31,7 +31,7 @@
/**
* @author gregsh
*/
-public abstract class EditorTextFieldCellRenderer extends JPanel implements TableCellRenderer, Disposable {
+public abstract class EditorTextFieldCellRenderer extends CellRendererPanel implements TableCellRenderer, Disposable {
private EditorEx myEditor;
@@ -112,40 +112,6 @@
((EditorImpl)editor).resetSizes();
}
- // BEGIN no validation methods --------------
- @Override
- public void doLayout() {
- if (getComponentCount() != 1) return;
- getComponent(0).setBounds(0, 0, getWidth(), getHeight());
- }
-
- @Override
- public Dimension getPreferredSize() {
- if (getComponentCount() != 1) return super.getPreferredSize();
- return getComponent(0).getPreferredSize();
- }
-
- public void invalidate() {
- }
-
- public void validate() {
- doLayout();
- }
-
- public void revalidate() {
- }
-
- public void repaint(long tm, int x, int y, int width, int height) {
- }
-
- public void repaint(Rectangle r) {
- }
-
- public void repaint() {
- }
-
-// END no validation methods --------------
-
private static class MyDocument extends UserDataHolderBase implements DocumentEx {
RangeMarkerTree<RangeMarkerEx> myRangeMarkers = new RangeMarkerTree<RangeMarkerEx>(this) {};
diff --git a/platform/platform-impl/src/com/intellij/ui/GotItMessage.java b/platform/platform-impl/src/com/intellij/ui/GotItMessage.java
index 6580d0c..d44318b 100644
--- a/platform/platform-impl/src/com/intellij/ui/GotItMessage.java
+++ b/platform/platform-impl/src/com/intellij/ui/GotItMessage.java
@@ -41,11 +41,13 @@
@NotNull String message ) {
myTitle = title;
final String[] lines = message.split("\n");
- if (lines.length > 1) {
- myMessage = "<html><div align='center'>" + message.replace("\n", "<br>") + "</div></html>";
- } else {
- myMessage = message;
- }
+
+ StringBuffer buf = new StringBuffer("<html><body><div align='center' style=\"font-family: ")
+ .append(UIUtil.getLabelFont().getFontName()).append("; ")
+ .append("font-size: 12pt;\">")
+ .append(lines.length > 1 ? message.replace("\n", "<br>") : message)
+ .append("</div></body></html>");
+ myMessage = buf.toString();
}
public static GotItMessage createMessage(@NotNull String title,
@@ -86,6 +88,7 @@
.setHideOnFrameResize(false)
.setHideOnKeyOutside(false)
.setShowCallout(myShowCallout)
+ .setBlockClicksThroughBalloon(true)
.createBalloon();
panel.myButton.addMouseListener(new MouseAdapter() {
@Override
diff --git a/platform/platform-impl/src/com/intellij/ui/GotItPanel.form b/platform/platform-impl/src/com/intellij/ui/GotItPanel.form
index 0fda696..2c6f5d7 100644
--- a/platform/platform-impl/src/com/intellij/ui/GotItPanel.form
+++ b/platform/platform-impl/src/com/intellij/ui/GotItPanel.form
@@ -24,13 +24,15 @@
<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"/>
</constraints>
</vspacer>
- <component id="1102e" class="javax.swing.JLabel" binding="myMessage">
+ <component id="10cce" class="javax.swing.JEditorPane" binding="myMessage" custom-create="true">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
+ <contentType value="text/html"/>
<font size="12"/>
- <text value="Text text text text"/>
+ <opaque value="false"/>
+ <text value="<html> <head> </head> <body> <p style="margin-top: 0"> Test test test </p> </body> </html> "/>
</properties>
</component>
<grid id="fd7bc" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
diff --git a/platform/platform-impl/src/com/intellij/ui/GotItPanel.java b/platform/platform-impl/src/com/intellij/ui/GotItPanel.java
index 20c43fa..a2bb792 100644
--- a/platform/platform-impl/src/com/intellij/ui/GotItPanel.java
+++ b/platform/platform-impl/src/com/intellij/ui/GotItPanel.java
@@ -16,6 +16,7 @@
package com.intellij.ui;
import com.intellij.util.ui.GraphicsUtil;
+import com.intellij.util.ui.UIUtil;
import javax.swing.*;
import java.awt.*;
@@ -27,7 +28,8 @@
JPanel myButton;
JPanel myRoot;
JLabel myTitle;
- JLabel myMessage;
+ JEditorPane myMessage;
+
private void createUIComponents() {
myButton = new JPanel(new BorderLayout()) {
@@ -45,5 +47,10 @@
g.drawRoundRect(0,0,getWidth()-1, getHeight()-1, 5,5);
}
};
+ myMessage = new JEditorPane("text/html", "<html></html>");
+ myMessage.setEditorKit(UIUtil.getHTMLEditorKit());
+ myMessage.setEditable(false);
+ myMessage.addHyperlinkListener(new BrowserHyperlinkListener());
+ myMessage.setFont(UIUtil.getLabelFont().deriveFont(UIUtil.getLabelFont().getSize() + 2f));
}
}
diff --git a/platform/platform-impl/src/com/intellij/ui/TreeSpeedSearch.java b/platform/platform-impl/src/com/intellij/ui/TreeSpeedSearch.java
index 2594f91..c44488b 100644
--- a/platform/platform-impl/src/com/intellij/ui/TreeSpeedSearch.java
+++ b/platform/platform-impl/src/com/intellij/ui/TreeSpeedSearch.java
@@ -16,9 +16,9 @@
package com.intellij.ui;
import com.intellij.ide.util.treeView.NodeDescriptor;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.containers.Convertor;
import com.intellij.ui.treeStructure.Tree;
+import com.intellij.util.ArrayUtilRt;
+import com.intellij.util.containers.Convertor;
import com.intellij.util.ui.tree.TreeUtil;
import javax.swing.*;
@@ -86,7 +86,7 @@
@Override
protected int getSelectedIndex() {
if (myCanExpand) {
- return ArrayUtil.find(getAllElements(), myComponent.getSelectionPath());
+ return ArrayUtilRt.find(getAllElements(), myComponent.getSelectionPath());
}
int[] selectionRows = myComponent.getSelectionRows();
return selectionRows == null || selectionRows.length == 0 ? -1 : selectionRows[0];
diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties
index 520aeaa..ecf9703 100644
--- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties
+++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties
@@ -460,6 +460,14 @@
button.edit.global.settings=Edit Global Settings...
label.edit.per.project.or.global.code.style=<html><body>Check option above on for per-project code style configuration<br>or use global code style. Global code style settings can be configured<br>in IDE Settings/Global Code Style</body></html>
title.project.code.style=Project\nCode Style
+title.code.style.settings.import=Settings Import
+title.import.scheme.from=Import From
+import.scheme.shared=Shared Scheme
+message.code.style.scheme.already.exists=Scheme {0} already exists. Overwrite settings?
+code.style.scheme.import.unnamed=Unnamed
+message.code.style.scheme.import.success={0} settings were imported to {1} scheme.
+message.code.style.scheme.import.failure={0} import failed with error message: {1}
+
label.name=Name:
error.scheme.must.have.a.name=Scheme must have a name
error.illegal.scheme.name=Illegal scheme name
diff --git a/platform/platform-resources-en/src/messages/OptionsBundle.properties b/platform/platform-resources-en/src/messages/OptionsBundle.properties
index 920fd45..f92eab5 100644
--- a/platform/platform-resources-en/src/messages/OptionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/OptionsBundle.properties
@@ -228,6 +228,8 @@
# Console settings
color.settings.console.name=Console Colors
color.settings.console.output=IRB Output
+
+color.settings.console.black=ANSI Black
color.settings.console.red=ANSI Red
color.settings.console.green=ANSI Green
color.settings.console.yellow=ANSI Yellow
@@ -235,4 +237,14 @@
color.settings.console.magenta=ANSI Magenta
color.settings.console.cyan=ANSI Cyan
color.settings.console.gray=ANSI Gray
+
+color.settings.console.darkGray=ANSI Dark Gray
+color.settings.console.redBright=ANSI Bright Red
+color.settings.console.greenBright=ANSI Bright Green
+color.settings.console.yellowBright=ANSI Bright Yellow
+color.settings.console.blueBright=ANSI Bright Blue
+color.settings.console.magentaBright=ANSI Bright Magenta
+color.settings.console.cyanBright=ANSI Bright Cyan
+color.settings.console.white=ANSI White
+
options.general.attribute.descriptor.live.template=Live Template
\ No newline at end of file
diff --git a/platform/platform-resources-en/src/messages/RefactoringBundle.properties b/platform/platform-resources-en/src/messages/RefactoringBundle.properties
index 7f9d09d..4571f97 100644
--- a/platform/platform-resources-en/src/messages/RefactoringBundle.properties
+++ b/platform/platform-resources-en/src/messages/RefactoringBundle.properties
@@ -2,42 +2,42 @@
progress.text=Looking for Usages
usageView.tabText=Refactoring Preview
usageView.usagesText=usages
-usageView.need.reRun=Cannot perform the refactoring operation.\nThere were changes in code after the usages have been found.\nPlease, perform the usage search again.
+usageView.need.reRun=Cannot perform refactoring operation.\nThere were changes in code after usages have been found.\nPlease perform usage search again.
usageView.doAction=&Do Refactor
statusBar.refactoring.result={0, choice, 1#1 occurrence|2#{0,number} occurrences} changed
statusBar.noUsages=No occurrences found
anonymousToInner.refactoring.name=Convert Anonymous to Inner
anonymousToInner.no.inner.class.name=Class name should be specified
-inner.class.exists=Inner class named ''{0}'' is already defined\nin the class ''{1}''
+inner.class.exists=Inner class named ''{0}'' is already defined\nin class ''{1}''
anonymousToInner.class.name.label.text=Class name:
anonymousToInner.make.class.static.checkbox.text=Make class &static
anonymousToInner.parameters.panel.border.title=Constructor Parameters
-error.wrong.caret.position.method=The caret should be positioned inside the method to be refactored.
-error.wrong.caret.position.constructor=The caret should be positioned inside the constructor to be refactored.
-error.wrong.caret.position.method.or.class.name=The caret should be positioned at the name of the method or class to be refactored.
-error.wrong.caret.position.method.or.variable.name=The caret should be positioned at the name of the method or variable to be refactored.
-error.wrong.caret.position.anonymous=The caret should be positioned inside the anonymous class to be refactored.
-error.wrong.caret.position.class=The caret should be positioned inside the class to be refactored.
-error.wrong.caret.position.method.or.local.name=The caret should be positioned at the name of the element to be refactored.
-error.wrong.caret.position.local.name=The caret should be positioned at the name of the local variable to be refactored.
-error.wrong.caret.position.local.or.expression.name=The caret should be positioned at the name of the local variable or expression to be refactored.
-error.wrong.caret.position.symbol.to.rename=The caret should be positioned at the symbol to be renamed.
-error.wrong.caret.position.symbol.to.refactor=The caret should be positioned at the symbol to be refactored.
-error.out.of.project.element=Selected {0} is not located inside the project.
-error.in.injected.lang.prefix.suffix=Selected {0} is located in the readonly part of the injected language document.
-error.cannot.be.renamed=This element cannot be renamed.
+error.wrong.caret.position.method=Caret should be positioned inside method to be refactored
+error.wrong.caret.position.constructor=Caret should be positioned inside constructor to be refactored
+error.wrong.caret.position.method.or.class.name=Caret should be positioned at the name of method or class to be refactored
+error.wrong.caret.position.method.or.variable.name=Caret should be positioned at the name of method or variable to be refactored
+error.wrong.caret.position.anonymous=Caret should be positioned inside anonymous class to be refactored
+error.wrong.caret.position.class=Caret should be positioned inside class to be refactored
+error.wrong.caret.position.method.or.local.name=Caret should be positioned at the name of element to be refactored
+error.wrong.caret.position.local.name=Caret should be positioned at the name of local variable to be refactored
+error.wrong.caret.position.local.or.expression.name=Caret should be positioned at the name of local variable or expression to be refactored
+error.wrong.caret.position.symbol.to.rename=Caret should be positioned at symbol to be renamed
+error.wrong.caret.position.symbol.to.refactor=Caret should be positioned at symbol to be refactored
+error.out.of.project.element=Selected {0} is not located inside project.
+error.in.injected.lang.prefix.suffix=Selected {0} is located in the read-only part of injected language document
+error.cannot.be.renamed=This element cannot be renamed
to.refactor=to refactor
error.cannot.resolve=Cannot resolve {0}
error.incorrect.data=Incorrect Data
error.wrong.name.input=Wrong name: {0}
error.not.supported.for.jsp={0} refactoring is not supported for JSP
changeClassSignature.refactoring.name=Change Class Signature
-changeClassSignature.no.type.parameters=The class cannot have type parameters.
+changeClassSignature.no.type.parameters=Class cannot have type parameters
changeClassSignature.parameters.panel.border.title=Parameters
changeClassSignature.bad.default.value=Wrong default value: ''{0}'' for parameter ''{1}''
changeClassSignature.class.label.text=Change signature of {0}
-changeSignature.no.type.for.parameter=Specify a type for parameter ''{0}''
-changeSignature.no.type.for.exception=Specify a type for exception
+changeSignature.no.type.for.parameter=Specify type for parameter ''{0}''
+changeSignature.no.type.for.exception=Specify type for exception
changeSignature.refactoring.name=Change Signature
column.name.name=Name:
changeSignature.default.value.column=Default Value
@@ -59,7 +59,7 @@
changeSignature.wrong.type.for.parameter=Wrong type: ''{0}'' for parameter ''{1}''
changeSignature.wrong.type.for.exception=Wrong type: ''{0}'' for exception
changeSignature.vararg.not.last=Vararg parameter should be the last in method signature
-changeSignature.no.default.value=New parameter ''{0}'' has been added.\nSpecify a default value to be used in all existing calls of this method.
+changeSignature.no.default.value=New parameter ''{0}'' has been added.\nSpecify default value to be used in all existing calls of this method.
changeSignature.not.throwable.type=Wrong type ''{0}'' for exception, should extend java.lang.Throwable
changeSignature.cannot.resolve.parameter.type=Type ''{0}'' for parameter ''{1}'' cannot be resolved.\nContinue?
search.in.comments.and.strings=Search in &comments and strings
@@ -128,9 +128,9 @@
do.not.replace=Do ¬ replace
replace.fields.inaccessible.in.usage.context=Replace fields &inaccessible in usage context
replace.all.fields=&Replace all fields
-class.does.not.exist.in.the.project=Class does not exist in the project. Do you want to create it?
+class.does.not.exist.in.the.project=Class does not exist in project. Do you want to create it?
no.field.name.specified=No field name specified
-field.exists=The field with the name {0}\nalready exists in class ''{1}''.\nContinue?
+field.exists=Field with name {0}\nalready exists in class ''{1}''.\nContinue?
choose.destination.class=Choose Destination Class
replace.write.access.occurrences=Rep&lace write access occurrences
@@ -146,49 +146,49 @@
variable.of.type=Variable of &type:
convert.to.instance.method.title=Convert To Instance Method
-convertToInstanceMethod.method.is.not.static=Cannot perform the refactoring\nMethod {0} is not static.
-convertToInstanceMethod.no.parameters.with.reference.type=There are no parameters that have a reference type
-convertToInstanceMethod.all.reference.type.parametres.have.unknown.types=All reference type parametres have unknown types
+convertToInstanceMethod.method.is.not.static=Cannot perform the refactoring\nMethod {0} is not static
+convertToInstanceMethod.no.parameters.with.reference.type=There are no parameters that have reference type
+convertToInstanceMethod.all.reference.type.parametres.have.unknown.types=All reference type parameters have unknown types
convertToInstanceMethod.all.reference.type.parameters.are.not.in.project=All reference type parameters have types that are not in project
cannot.perform.refactoring=Cannot perform refactoring.
move.instance.method.title=Move Instance Method
move.method.is.not.supported.for.constructors=Move method is not supported for constructors
move.method.is.not.supported.for.generic.classes=Move method is not supported for generic classes
move.method.is.not.supported.when.method.is.part.of.inheritance.hierarchy=Move method is not supported when method is a part of inheritance hierarchy
-synthetic.jsp.class.is.referenced.in.the.method=Synthetic jsp class is referenced in the method
-there.are.no.variables.that.have.reference.type=There are no variables that have a reference type
+synthetic.jsp.class.is.referenced.in.the.method=Synthetic jsp class is referenced in method
+there.are.no.variables.that.have.reference.type=There are no variables that have reference type
all.candidate.variables.have.unknown.types=All candidate variables have unknown types
all.candidate.variables.have.types.not.in.project=All candidate variables have types that are not in project
use.interface.where.possible.title=Use Interface Where Possible
-interface.does.not.have.base.interfaces=Interface {0} does not have base interfaces.
-the.field.should.be.declared.in.a.class=The field should be declared in a class.
+interface.does.not.have.base.interfaces=Interface {0} does not have base interfaces
+the.field.should.be.declared.in.a.class=The field should be declared in a class
encapsulate.fields.title=Encapsulate Fields
-fields.to.be.refactored.should.belong.to.the.same.class=Fields to be refactored should belong to the same class.
+fields.to.be.refactored.should.belong.to.the.same.class=Fields to be refactored should belong to the same class
encapsulate.fields.refactoring.cannot.be.applied.to.interface=Encapsulate fields refactoring cannot be applied to interface
extract.interface.title=Extract Interface
extract.interface.command.name=Extracting interface {0} from {1}
extract.method.title=Extract Method
-selected.block.contains.invocation.of.another.class.constructor=Selected block contains invocation of another class constructor.
+selected.block.contains.invocation.of.another.class.constructor=Selected block contains invocation of another class constructor
selected.block.should.represent.a.set.of.statements.or.an.expression=Selected block should represent a set of statements or an expression
press.escape.to.remove.the.highlighting=Press Escape to remove the highlighting
extract.superclass.title=Extract Superclass
extract.superclass.command.name=Extracting superclass {0} from {1}
-superclass.cannot.be.extracted.from.an.interface=Superclass cannot be extracted from an interface.
-superclass.cannot.be.extracted.from.an.enum=Superclass cannot be extracted from an enum.
+superclass.cannot.be.extracted.from.an.interface=Superclass cannot be extracted from interface
+superclass.cannot.be.extracted.from.an.enum=Superclass cannot be extracted from enum
replace.inheritance.with.delegation.title=Replace Inheritance With Delegation
class.is.interface={0} is an interface.
-class.does.not.have.base.classes.or.interfaces=Class {0} does not have base classes or interfaces.
+class.does.not.have.base.classes.or.interfaces=Class {0} does not have base classes or interfaces
inline.title=Inline
introduce.constant.title=Extract Constant
introduce.selection.error=Cannot perform refactoring using selected element(s)
-selected.expression.cannot.be.a.constant.initializer=Selected expression cannot be a constant initializer.
+selected.expression.cannot.be.a.constant.initializer=Selected expression cannot be a constant initializer
variable.does.not.have.an.initializer=Variable {0} does not have an initializer.
-initializer.for.variable.cannot.be.a.constant.initializer=Initializer for variable {0} cannot be a constant initializer.
-cannot.introduce.field.in.interface=Cannot extract field in interface
+initializer.for.variable.cannot.be.a.constant.initializer=Initializer for variable {0} cannot be a constant initializer
+cannot.introduce.field.in.interface=Cannot extract field in the interface
introduce.field.title=Extract Field
-selected.block.should.represent.an.expression=Selected block should represent an expression.
-is.not.supported.in.the.current.context={0} is not supported in current context.
-type.of.the.selected.expression.cannot.be.determined=Type of the selected expression cannot be determined.
+selected.block.should.represent.an.expression=Selected block should represent an expression
+is.not.supported.in.the.current.context={0} is not supported in current context
+type.of.the.selected.expression.cannot.be.determined=Type of selected expression cannot be determined.
selected.expression.has.void.type=Selected expression has void type.
to.rename=to rename
to.delete.with.usage.search=to delete (with usage search)
@@ -196,30 +196,30 @@
invalid.expression.context=Invalid expression context.
refactoring.is.not.supported.in.the.current.context={0} refactoring is not supported in the current context
cannot.introduce.variable.in.super.constructor.call=Cannot extract variable in super constructor call
-is.modified.in.loop.body={0} is modified in loop body.
-introducing.variable.may.break.code.logic=Introducing variable may break code logic.
+is.modified.in.loop.body={0} is modified in loop body
+introducing.variable.may.break.code.logic=Introducing variable may break code logic
no.selection=No selection.
-selection.does.not.form.a.fragment.for.extraction=Selection does not form a fragment for extraction.
-cannot.extract.selected.elements.into.include.file=Cannot extract selected elements into include file.
+selection.does.not.form.a.fragment.for.extraction=Selection does not form a fragment for extraction
+cannot.extract.selected.elements.into.include.file=Cannot extract selected elements into include file
the.language.for.selected.elements.has.no.associated.file.type=The language for selected elements has no associated file type
extract.include.file.title=Extract include file
replace.fragment=Replace Fragment
idea.has.found.fragments.that.can.be.replaced.with.include.directive={0} has found fragments that can be replaced with include directive\nDo you want to review them?
remove.duplicates.command=Remove Duplicates
make.method.static.title=Make Method Static
-constructor.cannot.be.made.static=Constructor cannot be made static.
-this.member.does.not.seem.to.belong.to.any.class=This member does not seem to belong to any class.
-member.is.already.static=Member is already static.
-cannot.make.abstract.method.static=Cannot make abstract method static.
-inner.classes.cannot.have.static.members=Inner classes cannot have static members.
+constructor.cannot.be.made.static=Constructor cannot be made static
+this.member.does.not.seem.to.belong.to.any.class=This member does not seem to belong to any class
+member.is.already.static=Member is already static
+cannot.make.abstract.method.static=Cannot make abstract method static
+inner.classes.cannot.have.static.members=Inner classes cannot have static members
pull.members.up.title=Pull Members Up
-the.caret.should.be.positioned.inside.a.class.to.pull.members.from=The caret should be positioned inside a class to pull members from.
-class.does.not.have.base.classes.interfaces.in.current.project={0} does not have base classes/interfaces in current project.
+the.caret.should.be.positioned.inside.a.class.to.pull.members.from=Caret should be positioned inside a class to pull members from
+class.does.not.have.base.classes.interfaces.in.current.project={0} does not have base classes/interfaces in current project
pullUp.command=Pulling members up from {0}
push.members.down.title=Push Members Down
-the.caret.should.be.positioned.inside.a.class.to.push.members.from=The caret should be positioned inside a class to push members from
+the.caret.should.be.positioned.inside.a.class.to.push.members.from=Caret should be positioned inside a class to push members from
move.title=Move
-the.caret.should.be.positioned.at.the.class.method.or.field.to.be.refactored=The caret should be positioned at the class, method or field to be refactored.
+the.caret.should.be.positioned.at.the.class.method.or.field.to.be.refactored=Caret should be positioned at the class, method or field to be refactored
select.refactoring.title=Select Refactoring
what.would.you.like.to.do=What would you like to do?
move.packages.to.another.package=Move {0} &packages to another package
@@ -228,11 +228,11 @@
move.directory.to.another.source.root=Move directory {0} to &another source root
move.inner.class.to.upper.level=Move &inner class {0} to upper level
move.inner.class.to.another.class=&Move inner class {0} to another class
-move.nonstatic.class.from.jsp.not.supported = Moving non-static classes from JSP page is not supported.
+move.nonstatic.class.from.jsp.not.supported = Moving non-static classes from JSP page is not supported
package.occurs.in.package.prefixes.of.the.following.source.folders.n=Package {0} occurs in package prefixes of the following source folders:\n
these.package.prefixes.will.be.changed=These package prefixes will be changed.
rename.title=Rename
-rename.not.supported=Operation is not supported.
+rename.not.supported=Operation is not supported
multiple.directories.correspond.to.package=Multiple directories correspond to package\n
directories.and.all.references.to.package.will.be.renamed=\n\nDo you want to rename the whole package or directory \n{0} only?
rename.package.button.text=Rename &package
@@ -243,26 +243,26 @@
move.directories= Move &all
warning.title=Warning
replace.constructor.with.factory.method.title=Replace Constructor With Factory Method
-class.does.not.have.implicit.default.constructor=Class {0} does not have implicit default constructor.
+class.does.not.have.implicit.default.constructor=Class {0} does not have implicit default constructor
would.you.like.to.replace.default.constructor.of.0.with.factory.method=Would you like to replace default constructor of {0} with factory method?
-refactoring.is.not.supported.for.local.and.jsp.classes=Refactoring is not supported for local and JSP classes.
-refactoring.is.not.supported.for.jsp.classes=Refactoring is not supported for JSP classes.
+refactoring.is.not.supported.for.local.and.jsp.classes=Refactoring is not supported for local and JSP classes
+refactoring.is.not.supported.for.jsp.classes=Refactoring is not supported for JSP classes
class.is.abstract={0} is abstract.
-method.is.not.a.constructor=Method is not a constructor.
+method.is.not.a.constructor=Method is not a constructor
safe.delete.title=Safe Delete
replace.temp.with.query.title=Replace Temp with Query
-cannot.replace.temp.with.query.in.interface=Cannot replace temp with query in interface.
-variable.has.no.initializer=Variable {0} has no initializer.
-variable.has.no.dominating.definition=Cannot find a single definition to inline.
+cannot.replace.temp.with.query.in.interface=Cannot replace temp with query in interface
+variable.has.no.initializer=Variable {0} has no initializer
+variable.has.no.dominating.definition=Cannot find a single definition to inline
variable.is.never.used=Variable {0} is never used
-variable.is.accessed.for.writing=Variable ''{0}'' is accessed for writing.
-variable.is.accessed.for.writing.and.used.with.inlined=Another variable ''{0}'' definition is used together with inlined one.
+variable.is.accessed.for.writing=Variable ''{0}'' is accessed for writing
+variable.is.accessed.for.writing.and.used.with.inlined=Another variable ''{0}'' definition is used together with inlined one
only.fields.variables.of.methods.of.valid.type.can.be.considered=Only fields, variables, method parameters\u00A0or methods of valid type can be considered.
unable.to.start.type.migration=Unable to start type migration
replace.method.code.duplicates.title=Replace Code Duplicates
-locate.caret.inside.a.method=Locate caret inside a member.
+locate.caret.inside.a.method=Locate caret inside a member
replace.with.method.call.does.not.work.for.constructors=Replace With Method Call does not work for constructors
-method.does.not.have.a.body=Method {0} does not have a body.
+method.does.not.have.a.body=Method {0} does not have a body
method.has.an.empty.body=Method {0} has an empty body.
idea.has.not.found.any.code.that.can.be.replaced.with.method.call={0} has not found any duplicates
method.duplicates.found.message={0, choice, 1#1 code fragment|2#{0,number} code fragments} found
@@ -288,20 +288,20 @@
javadoc.move=&Move
replace.instance.qualifiers.with.class.references=Replace instance qualifiers with class references
make.0.static=Make {0} Static
-0.already.has.parameter.named.1.use.this.name.anyway={0} already has parameter named ''{1}''.\nUse this name anyway?
+0.already.has.parameter.named.1.use.this.name.anyway={0} already has a parameter named ''{1}''.\nUse this name anyway?
this.method=This method
add.object.as.a.parameter.with.name=Add &object as a parameter with name:
add.object.as.a.parameter.to.constructors.with.name=Add &object as a parameter to constructors with name:
add.parameters.for.fields=Add parameters for &fields:
add.parameters.for.fields.to.constructors=Add parameters for &fields to constructors:
-0.already.contains.field.1={0} already contains field {1}.
+0.already.contains.field.1={0} already contains field {1}
0.is.already.overridden.in.1={0} is already overridden in {1}. Method will not be pushed down to that class.
-0.already.contains.inner.class.named.1={0} already contains inner class named {1}.
+0.already.contains.inner.class.named.1={0} already contains inner class named {1}
0.uses.1.which.is.pushed.down={0} uses {1}, which is pushed down
refactoring.cannot.be.performed=Refactoring cannot be performed
there.is.already.a.0.it.will.conflict.with.an.introduced.parameter=There is already a {0}. It will conflict with an introduced parameter
introduce.parameter.command=Extracting parameter to {0}
-parameter.initializer.contains.0.but.not.all.calls.to.method.are.in.its.class=Parameter initializer contains {0}, but not all calls to method are in its class.
+parameter.initializer.contains.0.but.not.all.calls.to.method.are.in.its.class=Parameter initializer contains {0}, but not all calls to method are in its class
0.is.not.accessible.from.1.value.for.introduced.parameter.in.that.method.call.will.be.incorrect={0} is not accessible from {1}. Value for introduced parameter in that method call will be incorrect.
use.interface.superclass.in.instanceof=Use interface/superclass in instanceof
introduce.parameter.to.method=Extract parameter to method:
@@ -325,7 +325,7 @@
copy.files.copy.specified.directories.label=Copy specified directories
copy.files.copy.specified.mixed.label=Copy specified files and directories
copy.files.to.directory.label=To &directory:
-the.file.will.be.copied.to.this.directory=The file will be copied to this directory
+the.file.will.be.copied.to.this.directory=File will be copied to this directory
copy.files.clone.title=Clone
copy.files.copy.title=Copy
copy.files.clone.file.0=Clone file {0}
@@ -352,8 +352,8 @@
encapsulate.fields.setter.column.name=Setter
encapsulate.fields.no.fields.selected=No fields selected
encapsulate.fields.command.name=Encapsulating fields in {0}
-encapsulate.fields.getter.exists=There already is a method {0} which differs from getter {1} by return type only.
-encapsulate.fields.setter.exists=There already is a method {0} which differs from setter {1} by return type only.
+encapsulate.fields.getter.exists=There is already method {0} which differs from getter {1} by return type only
+encapsulate.fields.setter.exists=There is already method {0} which differs from setter {1} by return type only
encapsulate.fields.fields.to.be.encapsulated=Fields to be encapsulated
invocations.to.be.inlined=Invocations to be inlined {0}
classes.to.push.down.members.to=Classes to push down members to {0}
@@ -374,8 +374,8 @@
make.static.description.label=Make {0} {1} static
there.is.already.a.0.in.1=There is already a {0} in {1}
0.uses.non.static.1.which.is.not.passed.as.a.parameter={0} uses non-static {1}, which is not passed as a parameter
-0.uses.1.which.needs.class.instance={0} uses {1}, which needs class instance.
-method.0.is.overridden.by.1=Method {0} is overridden by {1}.
+0.uses.1.which.needs.class.instance={0} uses {1}, which needs class instance
+method.0.is.overridden.by.1=Method {0} is overridden by {1}
make.static.command=Making {0} static
introduce.parameter.elements.header=Adding parameter to a method
annotate.field.as.nonnls.checkbox=Annotate &field as @NonNls
@@ -398,7 +398,7 @@
declare.varargs.checkbox=Declare v&arargs
declare.folded.parameters=&Fold parameters
extract.method.method.panel.border=Method
-there.are.multiple.exit.points.in.the.selected.code.fragment=There are multiple exit points in the selected code fragment.
+there.are.multiple.exit.points.in.the.selected.code.fragment=There are multiple exit points in the selected code fragment
move.members.elements.header=Members to be moved
move.members.move.members.from.label=Move members from:
move.members.to.fully.qualified.name.label=To (fully qualified name):
@@ -407,10 +407,10 @@
0.is.not.a.legal.fq.name=''{0}'' is not a legal FQ-name
create.class.command=Create class {0}
source.and.destination.classes.should.be.different=Source and destination classes should be different
-cannot.move.inner.class.0.into.itself=Cannot move inner class {0} into itself.
+cannot.move.inner.class.0.into.itself=Cannot move inner class {0} into itself
class.0.does.not.exist=Class {0} does not exist.\nDo you want to create it?
move.members.title=Move Members
-members.to.be.moved.should.belong.to.the.same.class=Members to be moved should belong to the same class.
+members.to.be.moved.should.belong.to.the.same.class=Members to be moved should belong to the same class
field.0.is.not.static=Field {0} is not static.\n{1} refactoring is supported for static members only.
0.refactoring.cannot.be.applied.to.constructors={0} refactoring cannot be applied to constructors
method.0.is.not.static=Method {0} is not static.\n{1} refactoring is supported for static members only.
@@ -455,16 +455,16 @@
inline.field.elements.header=Field to inline
inline.class.elements.header=Class to inline
inline.vars.elements.header=Variable to inline
-interface.has.been.successfully.created=Interface {0} has been successfully created.
-class.has.been.successfully.created=Class {0} has been successfully created.
+interface.has.been.successfully.created=Interface {0} has been successfully created
+class.has.been.successfully.created=Class {0} has been successfully created
use.super.references.prompt=At this stage {0} can analyze usages of {1} \nand replace them with usages of {2} where possible.\nDo you want to proceed?
analyze.and.replace.usages=Analyze and Replace Usages
there.are.multiple.output.values.for.the.selected.code.fragment=There are multiple output values for the selected code fragment:
expression.result=expression result
boolean.method.result=boolean method result
instances.of.0.upcasted.to.1.were.found=Instances of {0} upcasted to {1} were found. If you continue, they will be shown in a separate Find tab.
-0.uses.1.of.an.instance.of.a.2={0} uses {1} of an instance of a {2}.
-0.upcasts.an.instance.of.1.to.2={0} upcasts an instance of {1} to {2}.
+0.uses.1.of.an.instance.of.a.2={0} uses {1} of an instance of a {2}
+0.upcasts.an.instance.of.1.to.2={0} upcasts an instance of {1} to {2}
0.will.no.longer.override.1={0} will no longer override {1}
replacing.inheritance.with.delegation=Replacing inheritance with delegation
instances.casted.to.java.lang.object=Instances casted to java.lang.Object
@@ -474,7 +474,7 @@
replace.inheritance.with.delegation.elements.header=Replace inheritance with delegation
# Inline included file
inline.included.file.title=Inline included file
-the.caret.should.be.positioned.on.the.included.file.to.inline=The caret should be positioned on the included file reference to inline
+the.caret.should.be.positioned.on.the.included.file.to.inline=Caret should be positioned on the included file reference to inline
inline.the.contents.include.prompt=Inline the contents of ''{0}''?
remove.include.prompt=Included file is no longer used. Remove it?
@@ -492,8 +492,8 @@
keep.abstract.column.header=Keep abstract
push.down.javadoc.panel.title=JavaDoc for abstracts
push.down.members.elements.header=Push down members from
-interface.0.does.not.have.inheritors=Interface {0} does not have inheritors.
-class.0.does.not.have.inheritors=Class {0} does not have inheritors.
+interface.0.does.not.have.inheritors=Interface {0} does not have inheritors
+class.0.does.not.have.inheritors=Class {0} does not have inheritors
push.down.will.delete.members=Pushing members down will result in them being deleted. Would you like to create a new subclass?
edit.migration.map.title=Edit Migration Map
migration.map.name.prompt=Map name:
@@ -529,30 +529,30 @@
package.does.not.exist=Package {0} does not exist.\nDo you want to create it?
move.package.refactoring.cannot.be.applied.to.default.package=Move Package refactoring cannot be applied to default package
move.class.refactoring.cannot.be.applied.to.anonymous.classes=Move Class refactoring cannot be applied to anonymous classes
-moving.local.classes.is.not.supported=Moving local classes is not supported.
-there.are.going.to.be.multiple.destination.files.with.the.same.name=There are going to be multiple destination files with the same name.
+moving.local.classes.is.not.supported=Moving local classes is not supported
+there.are.going.to.be.multiple.destination.files.with.the.same.name=There are going to be multiple destination files with the same name
do.you.wish.to.continue=Do you wish to continue?
all.these.directories.will.be.moved.and.all.references.to.0.will.be.changed=All these directories will be moved, and all references to {0} \nwill be changed.
select.source.root.chooser.title=Select Source Root
moving.directories.command=Moving directories
-0.uses.a.package.local.1={0} uses a package-local {1}.
-a.package.local.class.0.will.no.longer.be.accessible.from.1=A package-local class {0} will no longer be accessible from {1}
+0.uses.a.package.local.1={0} uses package-local {1}
+a.package.local.class.0.will.no.longer.be.accessible.from.1=Package-local class {0} will no longer be accessible from {1}
element.will.no.longer.be.accessible={0} will no longer be accessible from {1}
move.instance.method.command=Move Instance method
move.instance.method.elements.header=Move instance method
move.method.this.parameter.label=Select a name for ''{0}.this'' parameter
move.method.enter.a.valid.name.for.parameter=Please Enter a Valid name for Parameter
-0.is.an.interface.that.has.no.implementing.classes={0} is an interface. \nthat has no implementing classes.
+0.is.an.interface.that.has.no.implementing.classes={0} is an interface that has no implementing classes
0.is.an.interface.method.implementation.will.be.added.to.all.directly.implementing.classes={0} is an interface. \nMethod implementation will be added to all directly implementing classes.\n Proceed?
move.inner.to.upper.level.title=Move Inner to Upper Level
move.inner.class.command=Moving inner class {0}
-0.will.become.inaccessible.from.1={0} will become inaccessible from {1}.
+0.will.become.inaccessible.from.1={0} will become inaccessible from {1}
move.specified.files=Move specified files
move.specified.directories=Move specified directories
move.file.0=Move file {0}
move.directory.0=Move directory {0}
move.files.to.directory.label=To directory:
-the.file.will.be.moved.to.this.directory=The file will be moved to this directory
+the.file.will.be.moved.to.this.directory=File will be moved to this directory
searching.for.variables=Searching for variables
no.usages.can.be.replaced=No usages of {0} \ncan be replaced with usages of {1}
turn.refs.to.super.command=Replacing usages of {0} with {1}
@@ -560,8 +560,8 @@
factory.method.name.label=Factory method name:
replace.constructor.with.factory.target.fq.name=In (fully qualified name):
class.0.not.found=Class {0} not found.
-class.0.is.not.accessible.from.target.1=Class {0} is not accessible from target {1}.
-target.0.is.not.accessible.from.1=Target {0} is not accessible from {1}.
+class.0.is.not.accessible.from.target.1=Class {0} is not accessible from target {1}
+target.0.is.not.accessible.from.1=Target {0} is not accessible from {1}
constructor.being.refactored.is.used.in.initializer.of.0=Constructor being refactored is used in initializer of {0}. Non-static factory of inner class{1} cannot be used in this context. Resulting code will not compile.
replace.constructor.0.with.a.factory.method=Replace constructor {0} with a factory method
replace.default.constructor.of.0.with.a.factory.method=Replace default constructor of {0} with a factory method
@@ -606,8 +606,8 @@
entity.name.inheritor=Inheritor
entity.name.test=Test
unused.overriding.methods.title=Unused Overriding Methods
-there.are.unused.methods.that.override.methods.you.delete=There are unused methods that override methods you delete.
-choose.the.ones.you.want.to.be.deleted=Choose the ones you want to be deleted.
+there.are.unused.methods.that.override.methods.you.delete=There are unused methods that override methods you delete
+choose.the.ones.you.want.to.be.deleted=Choose the ones you want to be deleted
method.column=Method
0.implements.1={0} implements {1}.
attempting.to.delete.targets.node.text=Attempting to delete
@@ -668,19 +668,19 @@
0.is.located.in.a.jar.file={0} is located in a jar file.\n
0.is.read.only={0} is read-only.\n
0.is.not.a.legal.java.identifier=''{0}'' is not a legal java identifier
-method.0.is.already.defined.in.the.1=Method {0} is already defined in the {1}.
-method.0.will.hide.method.of.the.base.class=Method {0} will hide \nthe method of the base class {1}.
-method.0.will.implement.method.of.the.base.class=Method {0} will implement \na method of the base class {1}.
-method.0.will.override.a.method.of.the.base.class=Method {0} will override \na method of the base class {1}.
+method.0.is.already.defined.in.the.1=Method {0} is already defined in the {1}
+method.0.will.hide.method.of.the.base.class=Method {0} will hide \nthe method of the base class {1}
+method.0.will.implement.method.of.the.base.class=Method {0} will implement \na method of the base class {1}
+method.0.will.override.a.method.of.the.base.class=Method {0} will override \na method of the base class {1}
current.class=current class
-field.0.is.already.defined.in.the.1=Field {0} is already defined in the {1}.
-field.0.will.hide.field.1.of.the.base.class=Field {0} will hide \na field {1} of the base class {2}.
+field.0.is.already.defined.in.the.1=Field {0} is already defined in the {1}
+field.0.will.hide.field.1.of.the.base.class=Field {0} will hide \na field {1} of the base class {2}
directory.0.already.contains.1.named.2=Directory {0} \nalready contains {1} named ''{2}''
directory.0.already.contains.a.file.named.1=Directory {0} \nalready contains a file named ''{1}''
getter.and.setter.methods.found.for.the.field.0=Getter and setter methods found for the field {0}. \n{1} them as well?
getter.method.found.for.the.field.0=Getter method found for the field {0}. \n{1} the getter as well?
setter.method.found.for.the.field.0=Setter method found for the field {0}. \n{1} the setter as well?
-0.has.1.usages.in.comments.and.strings={0} has {1,choice,1#1 usage|2#{1,number} usages} in strings, comments, or non-code files.
+0.has.1.usages.in.comments.and.strings={0} has {1,choice,1#1 usage|2#{1,number} usages} in strings, comments, or non-code files
0.has.1.usages.that.are.not.safe.to.delete.of.those.2={0} has {1,choice,1#1 usage that is|2#{1,number} usages that are} not safe to delete.\nOf those {2,choice,0#0 usages are|1#1 usage is|2#{2,number} usages are} in strings, comments, or non-code files.
type.cook.drop.obsolete.casts=&Drop obsolete casts
type.cook.preserve.raw.arrays=Preserve raw &arrays
@@ -693,7 +693,7 @@
type.cook.report=Items generified: {0}, casts removed: {1}
type.cook.ratio.generified={0,choice,-1#not calculated|0#{0,number} of {1}}
extract.method.control.flow.analysis.failed=Code contains syntax errors. Cannot perform necessary analysis.
-pushed.members.will.not.be.visible.from.certain.call.sites=Pushed members will not be visible from certain call sites.
+pushed.members.will.not.be.visible.from.certain.call.sites=Pushed members will not be visible from certain call sites
invert.boolean.title=Invert Boolean
invert.boolean.wrong.type=Return type of the method or type of the variable to be refactored should be boolean
invert.boolean.refs.to.invert=References to be inverted {0}
diff --git a/platform/platform-resources-en/src/messages/StatisticsBundle.properties b/platform/platform-resources-en/src/messages/StatisticsBundle.properties
index 5ed23cd..e7705d7 100644
--- a/platform/platform-resources-en/src/messages/StatisticsBundle.properties
+++ b/platform/platform-resources-en/src/messages/StatisticsBundle.properties
@@ -1,4 +1,4 @@
stats.title=Help improve {0} by sending anonymous usage statistics to {1}
-stats.config.allow.send.stats.text=Allow to send usages statistics to {0}
-stats.config.details=<html>We're asking your permission to send information about your plugins configuration (what is enabled <br>and what is not) and feature usage statistics (e.g. how frequently you're using code completion).<br> This data is anonymous, does not contain any personal information, collected for use only by {0}<br> and will never be transmitted to any third party.</html>
\ No newline at end of file
+stats.config.allow.send.stats.text=Allow sending usage statistics to {0}
+stats.config.details=<html>We are asking your permission to send information about your plugins configuration (what is enabled <br>and what is not) and feature usage statistics (e.g. how frequently you are using code completion).<br> This data is anonymous, does not contain any personal information, collected for use only by {0}<br> and will never be transmitted to any third party.</html>
\ No newline at end of file
diff --git a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties
index 8b5133d..8e0d36d 100644
--- a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties
+++ b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties
@@ -25,11 +25,13 @@
xbreakpoints.dialog.button.remove=&Remove
xbreakpoints.dialog.button.add=&Add...
xbreakpoints.conditions.group.title=Conditions
-xbreakpoints.suspend.group.title=Suspend policy
-xbreakpoints.suspend.checkbox=&Suspend
-xbreakpoints.suspend.all.radio=All
-xbreakpoints.suspend.thread.radio=Thread
-xbreakpoints.suspend.none.radio=None
+
+suspend.policy.panel.title=Suspend policy
+suspend.policy.panel.suspend=&Suspend
+suspend.policy.panel.all=All
+suspend.policy.panel.thread=Thread
+suspend.policy.panel.makeDefault=Make De&fault
+
xbreakpoints.properties.actions.group.title=Actions
xbreakpoints.log.message.checkbox=Log &message to console
xbreakpoints.log.expression.checkbox=Log evaluated &expression
diff --git a/platform/platform-resources/src/DefaultColorSchemesManager.xml b/platform/platform-resources/src/DefaultColorSchemesManager.xml
index 8e08ee1..7bac479 100644
--- a/platform/platform-resources/src/DefaultColorSchemesManager.xml
+++ b/platform/platform-resources/src/DefaultColorSchemesManager.xml
@@ -858,7 +858,7 @@
</option>
<option name="LOG_WARNING_OUTPUT">
<value>
- <option name="FOREGROUND" value="80A000"/>
+ <option name="FOREGROUND" value="ffa500"/>
</value>
</option>
<option name="LOG_ERROR_OUTPUT">
@@ -892,9 +892,29 @@
<option name="ERROR_STRIPE_COLOR" value="ff" />
</value>
</option>
+ <option name="CONSOLE_BLACK_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="000000" />
+ <option name="BACKGROUND" />
+ <option name="FONT_TYPE" value="0" />
+ <option name="EFFECT_COLOR" />
+ <option name="EFFECT_TYPE" value="0" />
+ <option name="ERROR_STRIPE_COLOR" />
+ </value>
+ </option>
<option name="CONSOLE_BLUE_OUTPUT">
<value>
- <option name="FOREGROUND" value="ff" />
+ <option name="FOREGROUND" value="0000ee" />
+ <option name="BACKGROUND" />
+ <option name="FONT_TYPE" value="0" />
+ <option name="EFFECT_COLOR" />
+ <option name="EFFECT_TYPE" value="0" />
+ <option name="ERROR_STRIPE_COLOR" />
+ </value>
+ </option>
+ <option name="CONSOLE_BLUE_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="5c5cff" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
@@ -904,7 +924,27 @@
</option>
<option name="CONSOLE_CYAN_OUTPUT">
<value>
- <option name="FOREGROUND" value="b2b2" />
+ <option name="FOREGROUND" value="00cccc" />
+ <option name="BACKGROUND" />
+ <option name="FONT_TYPE" value="0" />
+ <option name="EFFECT_COLOR" />
+ <option name="EFFECT_TYPE" value="0" />
+ <option name="ERROR_STRIPE_COLOR" />
+ </value>
+ </option>
+ <option name="CONSOLE_CYAN_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="00ffff" />
+ <option name="BACKGROUND" />
+ <option name="FONT_TYPE" value="0" />
+ <option name="EFFECT_COLOR" />
+ <option name="EFFECT_TYPE" value="0" />
+ <option name="ERROR_STRIPE_COLOR" />
+ </value>
+ </option>
+ <option name="CONSOLE_DARKGRAY_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="555555" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
@@ -914,7 +954,7 @@
</option>
<option name="CONSOLE_GRAY_OUTPUT">
<value>
- <option name="FOREGROUND" value="595959" />
+ <option name="FOREGROUND" value="aaaaaa" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
@@ -924,7 +964,17 @@
</option>
<option name="CONSOLE_GREEN_OUTPUT">
<value>
- <option name="FOREGROUND" value="8000" />
+ <option name="FOREGROUND" value="00cd00" />
+ <option name="BACKGROUND" />
+ <option name="FONT_TYPE" value="0" />
+ <option name="EFFECT_COLOR" />
+ <option name="EFFECT_TYPE" value="0" />
+ <option name="ERROR_STRIPE_COLOR" />
+ </value>
+ </option>
+ <option name="CONSOLE_GREEN_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="00ff00" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
@@ -934,6 +984,16 @@
</option>
<option name="CONSOLE_MAGENTA_OUTPUT">
<value>
+ <option name="FOREGROUND" value="cd00cd" />
+ <option name="BACKGROUND" />
+ <option name="FONT_TYPE" value="0" />
+ <option name="EFFECT_COLOR" />
+ <option name="EFFECT_TYPE" value="0" />
+ <option name="ERROR_STRIPE_COLOR" />
+ </value>
+ </option>
+ <option name="CONSOLE_MAGENTA_BRIGHT_OUTPUT">
+ <value>
<option name="FOREGROUND" value="ff00ff" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
@@ -944,6 +1004,16 @@
</option>
<option name="CONSOLE_RED_OUTPUT">
<value>
+ <option name="FOREGROUND" value="cd0000" />
+ <option name="BACKGROUND" />
+ <option name="FONT_TYPE" value="0" />
+ <option name="EFFECT_COLOR" />
+ <option name="EFFECT_TYPE" value="0" />
+ <option name="ERROR_STRIPE_COLOR" />
+ </value>
+ </option>
+ <option name="CONSOLE_RED_BRIGHT_OUTPUT">
+ <value>
<option name="FOREGROUND" value="ff0000" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
@@ -954,7 +1024,27 @@
</option>
<option name="CONSOLE_YELLOW_OUTPUT">
<value>
- <option name="FOREGROUND" value="ffcc00" />
+ <option name="FOREGROUND" value="cdcd00" />
+ <option name="BACKGROUND" />
+ <option name="FONT_TYPE" value="0" />
+ <option name="EFFECT_COLOR" />
+ <option name="EFFECT_TYPE" value="0" />
+ <option name="ERROR_STRIPE_COLOR" />
+ </value>
+ </option>
+ <option name="CONSOLE_YELLOW_BRIGHT_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="eaea00" />
+ <option name="BACKGROUND" />
+ <option name="FONT_TYPE" value="0" />
+ <option name="EFFECT_COLOR" />
+ <option name="EFFECT_TYPE" value="0" />
+ <option name="ERROR_STRIPE_COLOR" />
+ </value>
+ </option>
+ <option name="CONSOLE_WHITE_OUTPUT">
+ <value>
+ <option name="FOREGROUND" value="ffffff" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml
index bd4f689..15b1e43 100644
--- a/platform/platform-resources/src/META-INF/LangExtensions.xml
+++ b/platform/platform-resources/src/META-INF/LangExtensions.xml
@@ -565,6 +565,8 @@
id="PlatformProjectConfigurator"/>
<directoryProjectConfigurator implementation="com.intellij.platform.PlatformProjectViewOpener"/>
+ <fileIconProvider implementation="com.intellij.ide.FileIconPatcherImpl"/>
+ <iconProvider implementation="com.intellij.ide.NativeIconProvider"/>
<iconProvider implementation="com.intellij.psi.impl.file.DirectoryIconProvider" id="directory" order="last"/>
<statementUpDownMover implementation="com.intellij.codeInsight.editorActions.moveUpDown.LineMover" id="line" order="last"/>
@@ -756,8 +758,6 @@
<!--<projectViewPane implementation="com.intellij.ide.favoritesTreeView.FavoritesProjectViewPane"/>-->
<projectViewPane implementation="com.intellij.ide.scopeView.ScopeViewPane"/>
- <fileIconProvider implementation="com.intellij.openapi.fileTypes.impl.NativeFileIconProvider"/>
- <fileIconProvider implementation="com.intellij.ide.FileIconPatcherImpl"/>
<renameHandler implementation="com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler"/>
<renameHandler implementation="com.intellij.refactoring.rename.inplace.MemberInplaceRenameHandler"/>
<completion.contributor language="any"
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
index 337bfaf..a689fbc 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
@@ -97,7 +97,6 @@
interface="com.intellij.platform.ProjectTemplatesFactory"/>
<extensionPoint name="ApplicationLoadListener" interface="com.intellij.ide.ApplicationLoadListener"/>
- <extensionPoint name="ComponentRoamingType" beanClass="com.intellij.openapi.components.impl.stores.RoamingTypeExtensionPointBean"/>
<extensionPoint name="editorTabTitleProvider" interface="com.intellij.openapi.fileEditor.impl.EditorTabTitleProvider"/>
<extensionPoint name="editorTabColorProvider" interface="com.intellij.openapi.fileEditor.impl.EditorTabColorProvider"/>
@@ -197,5 +196,10 @@
<extensionPoint name="colorPickerListenerFactory" interface="com.intellij.ui.ColorPickerListenerFactory"/>
<extensionPoint name="search.topHitProvider" interface="com.intellij.ide.SearchTopHitProvider"/>
+
+ <extensionPoint name="schemeImporter" beanClass="com.intellij.openapi.options.SchemeImporterEP">
+ <with attribute="schemeClass" implements="com.intellij.openapi.options.Scheme"/>
+ <with attribute="implementationClass" implements="com.intellij.openapi.options.SchemeImporter"/>
+ </extensionPoint>
</extensionPoints>
</idea-plugin>
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
index 45c340a..c948106 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
@@ -239,8 +239,6 @@
<fileEditorProvider implementation="com.intellij.openapi.fileEditor.impl.http.HttpFileEditorProvider"/>
<componentConfigurationMerger implementation="com.intellij.openapi.vcs.changes.shelf.ShelfManagerConfigurationMerger"/>
<editorActionHandler action="EditorEscape" implementationClass="com.intellij.codeInsight.hint.EscapeHandler" id="hide-hints"/>
- <ComponentRoamingType component="ChangeListManager" type="DISABLED"/>
- <ComponentRoamingType component="RestoreUpdateTree" type="DISABLED"/>
<projectConfigurable instance="com.intellij.javaee.ExternalResourceConfigurable" key="display.name.edit.external.resource"
bundle="messages.XmlBundle" id="preferences.externalResources">
diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml
index 1eb54ac..73839f0 100644
--- a/platform/platform-resources/src/META-INF/XmlPlugin.xml
+++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml
@@ -297,7 +297,7 @@
<extendWordSelectionHandler implementation="com.intellij.codeInsight.editorActions.XmlCDATAContentSelectioner"/>
<extendWordSelectionHandler implementation="com.intellij.codeInsight.editorActions.DtdSelectioner"/>
<extendWordSelectionHandler implementation="com.intellij.codeInsight.editorActions.XmlElementSelectioner"/>
- <extendWordSelectionHandler implementation="com.intellij.codeInsight.editorActions.XmlTokenSelectioner"/>
+ <extendWordSelectionHandler id="xmlTokenSelectioner" implementation="com.intellij.codeInsight.editorActions.XmlTokenSelectioner"/>
<extendWordSelectionHandler implementation="com.intellij.codeInsight.editorActions.XmlLineSelectioner"/>
diff --git a/platform/platform-tests/testSrc/com/intellij/lang/PsiBuilderQuickTest.java b/platform/platform-tests/testSrc/com/intellij/lang/PsiBuilderQuickTest.java
index 343b58f2..5a47fdf 100644
--- a/platform/platform-tests/testSrc/com/intellij/lang/PsiBuilderQuickTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/lang/PsiBuilderQuickTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,9 +33,6 @@
import com.intellij.util.diff.DiffTreeChangeBuilder;
import com.intellij.util.diff.FlyweightCapableTreeStructure;
import com.intellij.util.diff.ShallowNodeComparator;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -674,7 +671,7 @@
private int myBufferEnd = 1;
@Override
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
myBuffer = buffer.subSequence(startOffset, endOffset);
myIndex = 0;
myBufferEnd = myBuffer.length();
@@ -710,6 +707,7 @@
if (myIndex < myBufferEnd) myIndex++;
}
+ @NotNull
@Override
public CharSequence getBufferSequence() {
return myBuffer;
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java
index c3a8641..8d8a924 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java
@@ -288,7 +288,7 @@
LocalFileSystem local = LocalFileSystem.getInstance();
VirtualFile virtualDir = local.findFileByIoFile(testDir);
- assert virtualDir != null : virtualDir;
+ assert virtualDir != null : testDir;
virtualDir.getChildren();
virtualDir.refresh(false, true);
checkChildCount(virtualDir, 1);
diff --git a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.groovy b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.groovy
index 0b451d3..677e42b 100644
--- a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.groovy
+++ b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.groovy
@@ -516,6 +516,12 @@
assertPreference("*e", "fileIndex", "file", NameUtil.MatchingCaseSensitivity.NONE);
}
+ public void "test first letter case match is important"() {
+ assertPreference("*pim", "PNGImageDecoder", "posIdMap", NameUtil.MatchingCaseSensitivity.NONE)
+ assertPreference("*pim", "PImageDecoder", "posIdMap", NameUtil.MatchingCaseSensitivity.NONE)
+ assertPreference("*er", "Error", "exchangeRequest", NameUtil.MatchingCaseSensitivity.NONE)
+ }
+
public void testPreferences() {
assertPreference(" fb", "FooBar", "_fooBar", NameUtil.MatchingCaseSensitivity.NONE);
assertPreference("*foo", "barFoo", "foobar");
diff --git a/platform/platform-tests/testSrc/com/intellij/run/PathMacrosCollectorTest.java b/platform/platform-tests/testSrc/com/intellij/run/PathMacrosCollectorTest.java
index cff8a1c..5f961b7 100644
--- a/platform/platform-tests/testSrc/com/intellij/run/PathMacrosCollectorTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/run/PathMacrosCollectorTest.java
@@ -18,6 +18,7 @@
import com.intellij.application.options.PathMacrosCollector;
import com.intellij.application.options.PathMacrosImpl;
import com.intellij.openapi.application.PathMacroFilter;
+import com.intellij.testFramework.UsefulTestCase;
import junit.framework.TestCase;
import org.jdom.Attribute;
import org.jdom.Element;
@@ -41,21 +42,17 @@
root.addContent(new Text("$$$ "));
root.addContent(new Text("$c:\\a\\b\\c$ "));
root.addContent(new Text("$Revision 1.23$"));
+ root.addContent(new Text("file://$root$/some/path/just$file$name.txt"));
final Set<String> macros = PathMacrosCollector.getMacroNames(root, null, new PathMacrosImpl());
-
- assertEquals(5, macros.size());
- assertTrue(macros.contains("MACro1"));
- assertTrue(macros.contains("macro4"));
- assertTrue(macros.contains("mac_ro6"));
- assertTrue(macros.contains("macr.o7"));
- assertTrue(macros.contains("mac-ro8"));
+ UsefulTestCase.assertSameElements(macros, "MACro1", "macro4", "mac_ro6", "macr.o7", "mac-ro8", "root");
}
public void testWithRecursiveFilter() throws Exception {
Element root = new Element("root");
final Element configuration = new Element("configuration");
configuration.setAttribute("value", "some text$macro5$fdsjfhdskjfsd$MACRO$");
+ configuration.setAttribute("value2", "file://$root$/some/path/just$file$name.txt");
root.addContent(configuration);
final Set<String> macros = PathMacrosCollector.getMacroNames(root, new PathMacroFilter() {
@@ -64,10 +61,7 @@
return "value".equals(attribute.getName());
}
}, new PathMacrosImpl());
-
- assertEquals(2, macros.size());
- assertTrue(macros.contains("macro5"));
- assertTrue(macros.contains("MACRO"));
+ UsefulTestCase.assertSameElements(macros, "macro5", "MACRO", "root");
}
public void testWithFilter() throws Exception {
diff --git a/platform/projectModel-api/src/com/intellij/ide/highlighter/ModuleFileType.java b/platform/projectModel-api/src/com/intellij/ide/highlighter/ModuleFileType.java
index 4a8fde4..9d06028 100644
--- a/platform/projectModel-api/src/com/intellij/ide/highlighter/ModuleFileType.java
+++ b/platform/projectModel-api/src/com/intellij/ide/highlighter/ModuleFileType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,33 +29,40 @@
@NonNls public static final String DEFAULT_EXTENSION = "iml";
@NonNls public static final String DOT_DEFAULT_EXTENSION = ".iml";
+ @Override
@NotNull
public String getName() {
return "IDEA_MODULE";
}
+ @Override
@NotNull
public String getDescription() {
return IdeBundle.message("filetype.description.idea.module");
}
+ @Override
@NotNull
public String getDefaultExtension() {
return DEFAULT_EXTENSION;
}
+ @Override
public Icon getIcon() {
return AllIcons.Nodes.IdeaModule;
}
+ @Override
public boolean isBinary() {
return false;
}
+ @Override
public boolean isReadOnly() {
return true;
}
+ @Override
public String getCharset(@NotNull VirtualFile file, final byte[] content) {
return CharsetToolkit.UTF8;
}
diff --git a/platform/projectModel-api/src/com/intellij/ide/highlighter/ProjectFileType.java b/platform/projectModel-api/src/com/intellij/ide/highlighter/ProjectFileType.java
index 43f5958..20f7a62 100644
--- a/platform/projectModel-api/src/com/intellij/ide/highlighter/ProjectFileType.java
+++ b/platform/projectModel-api/src/com/intellij/ide/highlighter/ProjectFileType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,33 +29,40 @@
@NonNls public static final String DEFAULT_EXTENSION = "ipr";
@NonNls public static final String DOT_DEFAULT_EXTENSION = ".ipr";
+ @Override
@NotNull
public String getName() {
return "IDEA_PROJECT";
}
+ @Override
@NotNull
public String getDescription() {
return IdeBundle.message("filetype.description.idea.project");
}
+ @Override
@NotNull
public String getDefaultExtension() {
return DEFAULT_EXTENSION;
}
+ @Override
public Icon getIcon() {
return AllIcons.Nodes.IdeaModule;
}
+ @Override
public boolean isBinary() {
return false;
}
+ @Override
public boolean isReadOnly() {
return true;
}
+ @Override
public String getCharset(@NotNull VirtualFile file, final byte[] content) {
return CharsetToolkit.UTF8;
}
diff --git a/platform/projectModel-api/src/com/intellij/openapi/components/State.java b/platform/projectModel-api/src/com/intellij/openapi/components/State.java
index 8278b2d..ec6b970 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/components/State.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/components/State.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,8 +22,15 @@
@Retention(RetentionPolicy.RUNTIME)
public @interface State {
String name();
+
+ /**
+ * {@link RoamingType#GLOBAL} will be ignored, use only {@link RoamingType#DISABLED} or {@link RoamingType#PER_PLATFORM}
+ */
RoamingType roamingType() default RoamingType.PER_USER;
+
Storage[] storages();
+
Class<? extends StateStorageChooser> storageChooser() default StorageAnnotationsDefaultValues.NullStateStorageChooser.class;
+
boolean reloadable() default true;
-}
+}
\ No newline at end of file
diff --git a/platform/projectModel-api/src/com/intellij/openapi/components/StorageAnnotationsDefaultValues.java b/platform/projectModel-api/src/com/intellij/openapi/components/StorageAnnotationsDefaultValues.java
index d9d3c92..5105105 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/components/StorageAnnotationsDefaultValues.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/components/StorageAnnotationsDefaultValues.java
@@ -26,42 +26,40 @@
public interface StorageAnnotationsDefaultValues {
class NullStateStorage implements StateStorage {
+ @Override
@Nullable
public <T> T getState(final Object component, final String componentName, Class<T> stateClass, @Nullable T mergeInto)
throws StateStorageException {
throw new UnsupportedOperationException("Method getState is not supported in " + getClass());
}
+ @Override
public boolean hasState(final Object component, final String componentName, final Class<?> aClass, final boolean reloadData) throws StateStorageException {
throw new UnsupportedOperationException("Method hasState not implemented in " + getClass());
}
- public boolean needsSave() throws StateStorageException {
- throw new UnsupportedOperationException("Method needsSave is not supported in " + getClass());
- }
-
public void save() throws StateStorageException {
throw new UnsupportedOperationException("Method save is not supported in " + getClass());
}
- public Set<String> getUsedMacros() {
- throw new UnsupportedOperationException("Method getUsedMacros not implemented in " + getClass());
- }
-
+ @Override
@NotNull
public ExternalizationSession startExternalization() {
throw new UnsupportedOperationException("Method startExternalization not implemented in " + getClass());
}
+ @Override
@NotNull
public SaveSession startSave(@NotNull ExternalizationSession externalizationSession) {
throw new UnsupportedOperationException("Method startSave not implemented in " + getClass());
}
+ @Override
public void finishSave(@NotNull SaveSession saveSession) {
throw new UnsupportedOperationException("Method finishSave not implemented in " + getClass());
}
+ @Override
public void reload(@NotNull final Set<String> changedComponents) throws StateStorageException {
throw new UnsupportedOperationException("Method reload not implemented in " + getClass());
}
@@ -69,16 +67,19 @@
}
class NullStateStorageChooser implements StateStorageChooser {
+ @Override
public Storage[] selectStorages(Storage[] storages, Object component, final StateStorageOperation operation) {
throw new UnsupportedOperationException("Method selectStorages is not supported in " + getClass());
}
}
class NullStateSplitter implements StateSplitter {
+ @Override
public List<Pair<Element, String>> splitState(Element e) {
throw new UnsupportedOperationException("Method splitState not implemented in " + getClass());
}
+ @Override
public void mergeStatesInto(final Element target, final Element[] elements) {
throw new UnsupportedOperationException("Method mergeStatesInto not implemented in " + getClass());
}
diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/ContentEntry.java b/platform/projectModel-api/src/com/intellij/openapi/roots/ContentEntry.java
index 360de66..d6e983c 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/roots/ContentEntry.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ContentEntry.java
@@ -135,6 +135,10 @@
@NotNull
SourceFolder addSourceFolder(@NotNull String url, boolean isTestSource);
+ @NotNull
+ <P extends JpsElement>
+ SourceFolder addSourceFolder(@NotNull String url, @NotNull JpsModuleSourceRootType<P> type);
+
/**
* Removes a source or test source root from this content root.
*
diff --git a/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosCollector.java b/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosCollector.java
index 05d8533..b4ed15f 100644
--- a/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosCollector.java
+++ b/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosCollector.java
@@ -21,12 +21,13 @@
import com.intellij.openapi.components.PathMacroMap;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtilRt;
+import gnu.trove.THashSet;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
@@ -43,9 +44,6 @@
private final Matcher myMatcher;
private final Map<String, String> myMacroMap = ContainerUtilRt.newLinkedHashMap();
- private static final String FILE_PROTOCOL = "file:";
- private static final String JAR_PROTOCOL = "jar:";
-
private PathMacrosCollector() {
myMatcher = MACRO_PATTERN.matcher("");
}
@@ -59,7 +57,7 @@
public static Set<String> getMacroNames(Element root, @Nullable PathMacroFilter filter, @NotNull final PathMacros pathMacros) {
final PathMacrosCollector collector = new PathMacrosCollector();
collector.substitute(root, true, false, filter);
- final HashSet<String> result = new HashSet<String>(collector.myMacroMap.keySet());
+ final Set<String> result = new THashSet<String>(collector.myMacroMap.keySet());
result.removeAll(pathMacros.getSystemMacroNames());
result.removeAll(pathMacros.getLegacyMacroNames());
result.removeAll(PathMacrosImpl.getToolMacroNames());
@@ -69,12 +67,13 @@
@Override
public String substituteRecursively(String text, boolean caseSensitive) {
- if (text == null || text.isEmpty()) return text;
+ if (StringUtil.isEmpty(text)) {
+ return text;
+ }
myMatcher.reset(text);
while (myMatcher.find()) {
- final String macroName = myMatcher.group(1);
- myMacroMap.put(macroName, null);
+ myMacroMap.put(myMatcher.group(1), null);
}
return text;
@@ -82,23 +81,30 @@
@Override
public String substitute(String text, boolean caseSensitive) {
- if (text == null || text.isEmpty()) return text;
-
- String protocol = null;
- if (text.length() > 7 && text.charAt(0) == 'f') {
- protocol = FILE_PROTOCOL;
- } else if (text.length() > 6 && text.charAt(0) == 'j') {
- protocol = JAR_PROTOCOL;
- } else if ('$' != text.charAt(0)) {
+ if (StringUtil.isEmpty(text)) {
return text;
}
- if (protocol != null && !text.startsWith(protocol)) return text;
+ int startPos = -1;
+ if (text.charAt(0) == '$') {
+ startPos = 0;
+ }
+ else {
+ for (String protocol : ReplacePathToMacroMap.PROTOCOLS) {
+ if (text.length() > protocol.length() + 4 && text.startsWith(protocol) && text.charAt(protocol.length()) == ':') {
+ startPos = protocol.length() + 1;
+ if (text.charAt(startPos) == '/') startPos++;
+ if (text.charAt(startPos) == '/') startPos++;
+ }
+ }
+ }
+ if (startPos < 0) {
+ return text;
+ }
- myMatcher.reset(text);
- if (myMatcher.find()) {
- final String macroName = myMatcher.group(1);
- myMacroMap.put(macroName, null);
+ myMatcher.reset(text).region(startPos, text.length());
+ if (myMatcher.lookingAt()) {
+ myMacroMap.put(myMatcher.group(1), null);
}
return text;
diff --git a/platform/projectModel-impl/src/com/intellij/application/options/ReplacePathToMacroMap.java b/platform/projectModel-impl/src/com/intellij/application/options/ReplacePathToMacroMap.java
index ffb0096..10acdbe 100644
--- a/platform/projectModel-impl/src/com/intellij/application/options/ReplacePathToMacroMap.java
+++ b/platform/projectModel-impl/src/com/intellij/application/options/ReplacePathToMacroMap.java
@@ -43,7 +43,7 @@
private List<String> myPathsIndex = null;
private final Map<String, String> myMacroMap = ContainerUtilRt.newLinkedHashMap();
- @NonNls private static final String[] PROTOCOLS;
+ @NonNls public static final String[] PROTOCOLS;
static {
List<String> protocols = new ArrayList<String>();
protocols.add("file");
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java
index 33fac00..82dece3 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java
@@ -25,6 +25,7 @@
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.util.ArrayUtil;
import gnu.trove.THashMap;
+import gnu.trove.THashSet;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -54,37 +55,32 @@
}
public void load(@NotNull Element rootElement) throws IOException {
- final Element[] elements = JDOMUtil.getElements(rootElement);
- for (Element element : elements) {
- if (element.getName().equals(COMPONENT)) {
- final String name = element.getAttributeValue(NAME);
+ for (Iterator<Element> iterator = rootElement.getChildren(COMPONENT).iterator(); iterator.hasNext(); ) {
+ Element element = iterator.next();
+ String name = element.getAttributeValue(NAME);
+ if (name == null) {
+ LOG.info("Broken content in file : " + this);
+ continue;
+ }
- if (name == null) {
- LOG.info("Broken content in file : " + this);
- continue;
+ iterator.remove();
+
+ if (element.getAttributes().size() > 1 || !element.getChildren().isEmpty()) {
+ assert element.getAttributeValue(NAME) != null : "No name attribute for component: " + name + " in " + this;
+
+ Element existingElement = myComponentStates.get(name);
+ if (existingElement != null) {
+ element = mergeElements(name, element, existingElement);
}
- element.detach();
-
- if (element.getAttributes().size() > 1 || !element.getChildren().isEmpty()) {
- assert element.getAttributeValue(NAME) != null : "No name attribute for component: " + name + " in " + this;
-
- Element existingElement = myComponentStates.get(name);
-
- if (existingElement != null) {
- element = mergeElements(name, element, existingElement);
- }
-
- myComponentStates.put(name, element);
- }
+ myComponentStates.put(name, element);
}
}
}
private static Element mergeElements(final String name, final Element element1, final Element element2) {
ExtensionPoint<XmlConfigurationMerger> point = Extensions.getRootArea().getExtensionPoint("com.intellij.componentConfigurationMerger");
- XmlConfigurationMerger[] mergers = point.getExtensions();
- for (XmlConfigurationMerger merger : mergers) {
+ for (XmlConfigurationMerger merger : point.getExtensions()) {
if (merger.getComponentName().equals(name)) {
return merger.merge(element1, element2);
}
@@ -111,14 +107,12 @@
@Nullable
public Element getState(final String name) {
- final Element e = myComponentStates.get(name);
-
- if (e != null) {
- assert e.getAttributeValue(NAME) != null : "No name attribute for component: " + name + " in " + this;
- e.removeAttribute(NAME);
+ final Element element = myComponentStates.get(name);
+ if (element != null) {
+ assert element.getAttributeValue(NAME) != null : "No name attribute for component: " + name + " in " + this;
+ element.removeAttribute(NAME);
}
-
- return e;
+ return element;
}
void removeState(final String componentName) {
@@ -174,10 +168,10 @@
}
public Set<String> getDifference(final StorageData storageData, PathMacroSubstitutor substitutor) {
- Set<String> bothStates = new HashSet<String>(myComponentStates.keySet());
+ Set<String> bothStates = new THashSet<String>(myComponentStates.keySet());
bothStates.retainAll(storageData.myComponentStates.keySet());
- Set<String> diffs = new HashSet<String>();
+ Set<String> diffs = new THashSet<String>();
diffs.addAll(storageData.myComponentStates.keySet());
diffs.addAll(myComponentStates.keySet());
diffs.removeAll(bothStates);
@@ -196,7 +190,6 @@
}
}
-
return diffs;
}
@@ -209,7 +202,9 @@
}
public void checkUnknownMacros(TrackingPathMacroSubstitutor pathMacroSubstitutor) {
- if (pathMacroSubstitutor == null) return;
+ if (pathMacroSubstitutor == null) {
+ return;
+ }
for (String componentName : myComponentStates.keySet()) {
final Set<String> unknownMacros = PathMacrosCollector.getMacroNames(myComponentStates.get(componentName));
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java
index 1dea810..980123e 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java
@@ -21,6 +21,7 @@
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.util.Consumer;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
@@ -118,7 +119,7 @@
});
}
- private static void updateModel(Module module, Consumer<ModifiableRootModel> task) {
+ public static void updateModel(@NotNull Module module, @NotNull Consumer<ModifiableRootModel> task) {
final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
try {
task.consume(model);
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java
index 0197e1d..085abe6 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java
@@ -42,6 +42,7 @@
import org.jetbrains.jps.model.JpsSimpleElement;
import org.jetbrains.jps.model.java.JavaSourceRootProperties;
import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer;
@@ -209,10 +210,15 @@
@NotNull
@Override
public SourceFolder addSourceFolder(@NotNull String url, boolean isTestSource) {
+ return addSourceFolder(url, isTestSource ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE);
+ }
+
+ @NotNull
+ @Override
+ public <P extends JpsElement> SourceFolder addSourceFolder(@NotNull String url, @NotNull JpsModuleSourceRootType<P> type) {
assertFolderUnderMe(url);
- JavaSourceRootType type = isTestSource ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE;
- JpsSimpleElement<JavaSourceRootProperties> properties = JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties(""));
- return addSourceFolder(new SourceFolderImpl(JpsElementFactory.getInstance().createModuleSourceRoot(url, type, properties), this));
+ JpsModuleSourceRoot sourceRoot = JpsElementFactory.getInstance().createModuleSourceRoot(url, type, type.createDefaultProperties());
+ return addSourceFolder(new SourceFolderImpl(sourceRoot, this));
}
@NotNull
diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java
index 44e5ee5..49a391d 100644
--- a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java
+++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java
@@ -185,10 +185,7 @@
private SourceFolder addSourceFolder(final String url, boolean isTestSource, String packagePrefix) {
final JavaSourceRootType rootType = isTestSource ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE;
JpsSimpleElement<JavaSourceRootProperties> properties = JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties(packagePrefix));
- final JpsModuleSourceRoot sourceRoot = myModule.addSourceRoot(url, rootType, properties);
- final JpsSourceFolder sourceFolder = new JpsSourceFolder(sourceRoot, this);
- mySourceFolders.add(sourceFolder);
- return sourceFolder;
+ return addSourceFolder(url, rootType, properties);
}
@NotNull
@@ -197,6 +194,19 @@
return addSourceFolder(url, isTestSource, "");
}
+ @NotNull
+ @Override
+ public <P extends JpsElement> SourceFolder addSourceFolder(@NotNull String url, @NotNull JpsModuleSourceRootType<P> type) {
+ return addSourceFolder(url, type, type.createDefaultProperties());
+ }
+
+ private <P extends JpsElement> SourceFolder addSourceFolder(final String url, JpsModuleSourceRootType<P> type, P properties) {
+ final JpsModuleSourceRoot sourceRoot = myModule.addSourceRoot(url, type, properties);
+ final JpsSourceFolder sourceFolder = new JpsSourceFolder(sourceRoot, this);
+ mySourceFolders.add(sourceFolder);
+ return sourceFolder;
+ }
+
@Override
public void removeSourceFolder(@NotNull SourceFolder sourceFolder) {
final JpsSourceFolder folder = (JpsSourceFolder)sourceFolder;
diff --git a/platform/projectModel-impl/src/messages/ProjectBundle.properties b/platform/projectModel-impl/src/messages/ProjectBundle.properties
index 0c0d6f9..d44173b 100644
--- a/platform/projectModel-impl/src/messages/ProjectBundle.properties
+++ b/platform/projectModel-impl/src/messages/ProjectBundle.properties
@@ -167,6 +167,7 @@
module.classpath.button.move.up=Move Up
module.classpath.button.move.down=Move Down
module.remove.confirmation.prompt=Remove {1, choice, 1#Module|2#Modules} {0} from the project?\nNo files will be deleted.
+project.remove.confirmation.prompt=Would you like to detach the {1, choice, 1#project|2#projects} {0}?
module.remove.command=Detach module from project
module.new.action=New Module
module.new.action.description=Add new module to the project
@@ -346,7 +347,6 @@
error.message.unknown.facet.type.0=Unknown facet type: ''{0}''
error.message.cannot.load.facet.condiguration.0=Cannot load facet condiguration: {0}
error.message.facet.type.isn.t.specified=Facet type isn''t specified
-error.message.cannot.find.underlying.facet.type.for.0=Cannot find underlying facet type for ''{0}''
error.message.0.facet.must.be.placed.under.1.facet={0} facet must be placed under {1} facet
error.message.0.cannot.be.placed.under.1={0} cannot be placed under {1}
error.message.0.facets.are.not.allowed.in.1={0} facets are not allowed in {1}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgent.java b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgent.java
new file mode 100644
index 0000000..4eb2bf1
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgent.java
@@ -0,0 +1,8 @@
+package com.intellij.remoteServer.agent;
+
+/**
+ * @author michael.golubev
+ */
+public interface RemoteAgent {
+
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgentManager.java b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgentManager.java
new file mode 100644
index 0000000..10c81de
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgentManager.java
@@ -0,0 +1,27 @@
+package com.intellij.remoteServer.agent;
+
+import com.intellij.openapi.components.ServiceManager;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * @author michael.golubev
+ */
+public abstract class RemoteAgentManager {
+
+ public static RemoteAgentManager getInstance() {
+ return ServiceManager.getService(RemoteAgentManager.class);
+ }
+
+ public abstract <T extends RemoteAgent> T createAgent(RemoteAgentProxyFactory agentProxyFactory,
+ List<File> instanceLibraries,
+ List<Class<?>> commonJarClasses,
+ String specificsRuntimeModuleName,
+ String specificsBuildJarPath,
+ Class<T> agentInterface,
+ String agentClassName,
+ Class<?> pluginClass) throws Exception;
+
+ public abstract RemoteAgentProxyFactory createReflectiveThreadProxyFactory(ClassLoader callerClassLoader);
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgentProxyFactory.java b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgentProxyFactory.java
new file mode 100644
index 0000000..1cf9c73
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/RemoteAgentProxyFactory.java
@@ -0,0 +1,12 @@
+package com.intellij.remoteServer.agent;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * @author michael.golubev
+ */
+public interface RemoteAgentProxyFactory {
+
+ <T> T createProxy(List<File> libraries, Class<T> agentInterface, String agentClassName) throws Exception;
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/AsyncCall.java b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/AsyncCall.java
new file mode 100644
index 0000000..e310564
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/AsyncCall.java
@@ -0,0 +1,16 @@
+package com.intellij.remoteServer.agent.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: michael.golubev
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface AsyncCall {
+
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/ChildCall.java b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/ChildCall.java
new file mode 100644
index 0000000..c3fc17b
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/ChildCall.java
@@ -0,0 +1,15 @@
+package com.intellij.remoteServer.agent.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author michael.golubev
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface ChildCall {
+
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/FinalCall.java b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/FinalCall.java
new file mode 100644
index 0000000..5b77d54
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/FinalCall.java
@@ -0,0 +1,16 @@
+package com.intellij.remoteServer.agent.annotation;
+
+/**
+ * @author michael.golubev
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface FinalCall {
+
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/ImmediateCall.java b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/ImmediateCall.java
new file mode 100644
index 0000000..33767d7
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/agent/annotation/ImmediateCall.java
@@ -0,0 +1,15 @@
+package com.intellij.remoteServer.agent.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author michael.golubev
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface ImmediateCall {
+
+}
diff --git a/platform/remote-servers/impl/src/META-INF/RemoteServers.xml b/platform/remote-servers/impl/src/META-INF/RemoteServers.xml
index d8b3bdf..a539fbe 100644
--- a/platform/remote-servers/impl/src/META-INF/RemoteServers.xml
+++ b/platform/remote-servers/impl/src/META-INF/RemoteServers.xml
@@ -9,6 +9,8 @@
serviceImplementation="com.intellij.remoteServer.impl.configuration.RemoteServersManagerImpl"/>
<applicationService serviceInterface="com.intellij.remoteServer.runtime.ServerConnectionManager"
serviceImplementation="com.intellij.remoteServer.impl.runtime.ServerConnectionManagerImpl"/>
+ <applicationService serviceInterface="com.intellij.remoteServer.agent.RemoteAgentManager"
+ serviceImplementation="com.intellij.remoteServer.agent.impl.RemoteAgentManagerImpl"/>
<applicationConfigurable instance="com.intellij.remoteServer.impl.configuration.RemoteServerListConfigurable"/>
<programRunner implementation="com.intellij.remoteServer.impl.runtime.DeployToServerRunner"/>
<projectService serviceInterface="com.intellij.remoteServer.runtime.ui.RemoteServersView"
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/CallerClassLoaderProvider.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/CallerClassLoaderProvider.java
new file mode 100644
index 0000000..e6910db
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/CallerClassLoaderProvider.java
@@ -0,0 +1,19 @@
+package com.intellij.remoteServer.agent.impl;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author michael.golubev
+ */
+public class CallerClassLoaderProvider {
+
+ private ClassLoader myCallerClassLoader;
+
+ public CallerClassLoaderProvider(@Nullable ClassLoader callerClassLoader) {
+ myCallerClassLoader = callerClassLoader;
+ }
+
+ public ClassLoader getCallerClassLoader(Class<?> classOfDefaultLoader) {
+ return myCallerClassLoader == null ? classOfDefaultLoader.getClassLoader() : myCallerClassLoader;
+ }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ChildWrapperCreator.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ChildWrapperCreator.java
new file mode 100644
index 0000000..d8be065
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ChildWrapperCreator.java
@@ -0,0 +1,11 @@
+package com.intellij.remoteServer.agent.impl;
+
+import java.lang.reflect.InvocationHandler;
+
+/**
+ * @author michael.golubev
+ */
+public interface ChildWrapperCreator {
+
+ InvocationHandler createWrapperInvocationHandler(Object child);
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentClassLoaderCache.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentClassLoaderCache.java
new file mode 100644
index 0000000..5b9311a
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentClassLoaderCache.java
@@ -0,0 +1,24 @@
+package com.intellij.remoteServer.agent.impl;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author michael.golubev
+ */
+public class RemoteAgentClassLoaderCache {
+
+ private final Map<Set<URL>, URLClassLoader> myUrls2ClassLoader = new HashMap<Set<URL>, URLClassLoader>();
+
+ public URLClassLoader getOrCreateClassLoader(Set<URL> libraryUrls) {
+ URLClassLoader result = myUrls2ClassLoader.get(libraryUrls);
+ if (result == null) {
+ result = new URLClassLoader(libraryUrls.toArray(new URL[libraryUrls.size()]), null);
+ myUrls2ClassLoader.put(libraryUrls, result);
+ }
+ return result;
+ }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentManagerImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentManagerImpl.java
new file mode 100644
index 0000000..6f3bc30
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentManagerImpl.java
@@ -0,0 +1,61 @@
+package com.intellij.remoteServer.agent.impl;
+
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.remoteServer.agent.RemoteAgent;
+import com.intellij.remoteServer.agent.RemoteAgentManager;
+import com.intellij.remoteServer.agent.RemoteAgentProxyFactory;
+import com.intellij.util.PathUtil;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author michael.golubev
+ */
+public class RemoteAgentManagerImpl extends RemoteAgentManager {
+
+ private final RemoteAgentClassLoaderCache myClassLoaderCache = new RemoteAgentClassLoaderCache();
+
+ @Override
+ public <T extends RemoteAgent> T createAgent(RemoteAgentProxyFactory agentProxyFactory,
+ List<File> instanceLibraries,
+ List<Class<?>> commonJarClasses,
+ String specificsRuntimeModuleName,
+ String specificsBuildJarPath,
+ Class<T> agentInterface,
+ String agentClassName,
+ Class<?> pluginClass) throws Exception {
+
+ List<Class<?>> allCommonJarClasses = new ArrayList<Class<?>>();
+ allCommonJarClasses.addAll(commonJarClasses);
+ allCommonJarClasses.add(RemoteAgent.class);
+ allCommonJarClasses.add(agentInterface);
+
+ List<File> libraries = new ArrayList<File>();
+ libraries.addAll(instanceLibraries);
+
+ for (Class<?> clazz : allCommonJarClasses) {
+ libraries.add(new File(PathUtil.getJarPathForClass(clazz)));
+ }
+
+ File plugin = new File(PathUtil.getJarPathForClass(pluginClass));
+ String allPluginsDir = plugin.getParent();
+ if (plugin.isDirectory()) {
+ // runtime behavior
+ File specificsModule = new File(allPluginsDir, specificsRuntimeModuleName);
+ libraries.add(specificsModule);
+ }
+ else {
+ // build behavior
+ File specificsDir = new File(allPluginsDir, FileUtil.toSystemDependentName(specificsBuildJarPath));
+ libraries.add(specificsDir);
+ }
+
+ return agentProxyFactory.createProxy(libraries, agentInterface, agentClassName);
+ }
+
+ public RemoteAgentProxyFactory createReflectiveThreadProxyFactory(ClassLoader callerClassLoader) {
+ return new RemoteAgentReflectiveThreadProxyFactory(myClassLoaderCache, callerClassLoader);
+ }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentProxyFactoryBase.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentProxyFactoryBase.java
new file mode 100644
index 0000000..688869a
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentProxyFactoryBase.java
@@ -0,0 +1,42 @@
+package com.intellij.remoteServer.agent.impl;
+
+import com.intellij.remoteServer.agent.RemoteAgentProxyFactory;
+import com.intellij.remoteServer.agent.impl.util.UrlCollector;
+
+import java.io.File;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.net.URL;
+import java.util.List;
+
+/**
+ * @author michael.golubev
+ */
+public abstract class RemoteAgentProxyFactoryBase implements RemoteAgentProxyFactory {
+
+ private final CallerClassLoaderProvider myCallerClassLoaderProvider;
+
+ public RemoteAgentProxyFactoryBase(CallerClassLoaderProvider callerClassLoaderProvider) {
+ myCallerClassLoaderProvider = callerClassLoaderProvider;
+ }
+
+ @Override
+ public <T> T createProxy(List<File> libraries, Class<T> agentInterface, String agentClassName) throws Exception {
+ ClassLoader callerClassLoader = myCallerClassLoaderProvider.getCallerClassLoader(agentInterface);
+ ClassLoader agentClassLoader = createAgentClassLoader(libraries);
+ Object agentImpl = agentClassLoader.loadClass(agentClassName).getDeclaredConstructor().newInstance();
+ return agentInterface.cast(Proxy.newProxyInstance(agentInterface.getClassLoader(),
+ new Class[]{agentInterface},
+ createInvocationHandler(agentImpl, agentClassLoader, callerClassLoader)));
+ }
+
+ protected ClassLoader createAgentClassLoader(List<File> libraries) throws Exception {
+ return createAgentClassLoader(new UrlCollector().collect(libraries));
+ }
+
+ protected abstract ClassLoader createAgentClassLoader(URL[] agentLibraryUrls) throws Exception;
+
+ protected abstract InvocationHandler createInvocationHandler(Object agentImpl,
+ ClassLoader agentClassLoader,
+ ClassLoader callerClassLoader);
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentReflectiveProxyFactory.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentReflectiveProxyFactory.java
new file mode 100644
index 0000000..c2bf104
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentReflectiveProxyFactory.java
@@ -0,0 +1,140 @@
+package com.intellij.remoteServer.agent.impl;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.containers.hash.HashSet;
+import org.jetbrains.annotations.Nullable;
+
+import java.lang.reflect.*;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.Set;
+
+/**
+ * @author michael.golubev
+ */
+public class RemoteAgentReflectiveProxyFactory extends RemoteAgentProxyFactoryBase {
+
+ private static final Logger LOG = Logger.getInstance("#" + RemoteAgentReflectiveProxyFactory.class.getName());
+
+ private final RemoteAgentClassLoaderCache myClassLoaderCache;
+
+ public RemoteAgentReflectiveProxyFactory(@Nullable RemoteAgentClassLoaderCache classLoaderCache,
+ CallerClassLoaderProvider callerClassLoaderProvider) {
+ super(callerClassLoaderProvider);
+ myClassLoaderCache = classLoaderCache;
+ }
+
+ @Override
+ protected ClassLoader createAgentClassLoader(URL[] agentLibraryUrls) throws Exception {
+ Set<URL> urls = new HashSet<URL>();
+ urls.addAll(Arrays.asList(agentLibraryUrls));
+ return myClassLoaderCache == null
+ ? new URLClassLoader(urls.toArray(new URL[urls.size()]), null)
+ : myClassLoaderCache.getOrCreateClassLoader(urls);
+ }
+
+ @Override
+ protected InvocationHandler createInvocationHandler(Object agentImpl, ClassLoader agentClassLoader, ClassLoader callerClassLoader) {
+ return new ReflectiveInvocationHandler(agentImpl, agentClassLoader, callerClassLoader);
+ }
+
+ private static class ReflectiveInvocationHandler implements InvocationHandler {
+
+ private final Object myTarget;
+ private final ClassLoader myTargetClassLoader;
+ private final ClassLoader mySourceClassLoader;
+
+ public ReflectiveInvocationHandler(Object target, ClassLoader targetClassLoader, ClassLoader sourceClassLoader) {
+ myTarget = target;
+ myTargetClassLoader = targetClassLoader;
+ mySourceClassLoader = sourceClassLoader;
+ }
+
+ @Nullable
+ @Override
+ public Object invoke(Object proxy, final Method method, final Object[] args) {
+ ClassLoader initialClassLoader = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(myTargetClassLoader);
+
+ Class<?>[] parameterTypes = method.getParameterTypes();
+ Class<?>[] delegateParameterTypes = new Class<?>[parameterTypes.length];
+
+ Object[] delegateArgs = new Object[parameterTypes.length];
+ for (int i = 0; i < parameterTypes.length; i++) {
+ Mirror parameterMirror = new Mirror(parameterTypes[i], args[i], mySourceClassLoader, myTargetClassLoader);
+ delegateParameterTypes[i] = parameterMirror.getMirrorType();
+ delegateArgs[i] = parameterMirror.getMirrorValue();
+ }
+
+ Method delegateMethod = myTarget.getClass().getMethod(method.getName(), delegateParameterTypes);
+ delegateMethod.setAccessible(true);
+
+ Object result = delegateMethod.invoke(myTarget, delegateArgs);
+ Mirror resultMirror = new Mirror(delegateMethod.getReturnType(), result, myTargetClassLoader, mySourceClassLoader);
+ return resultMirror.getMirrorValue();
+ }
+ catch (IllegalAccessException e) {
+ LOG.error(e);
+ return null;
+ }
+ catch (InvocationTargetException e) {
+ LOG.error(e);
+ return null;
+ }
+ catch (NoSuchMethodException e) {
+ LOG.error(e);
+ return null;
+ }
+ catch (ClassNotFoundException e) {
+ LOG.error(e);
+ return null;
+ }
+ finally {
+ Thread.currentThread().setContextClassLoader(initialClassLoader);
+ }
+ }
+ }
+
+ private static class Mirror {
+
+ private final Class<?> myMirrorType;
+
+ private final Object myMirrorValue;
+
+ public Mirror(Class<?> type, Object value, ClassLoader classLoader, ClassLoader mirrorClassLoader) throws ClassNotFoundException {
+ if (type.isArray()) {
+ Class<?> componentType = type.getComponentType();
+ Mirror componentMirror = new Mirror(componentType, null, classLoader, mirrorClassLoader);
+ int length = value == null ? 0 : Array.getLength(value);
+ Object mirrorValue = Array.newInstance(componentMirror.getMirrorType(), length);
+ for (int i = 0; i < length; i++) {
+ Mirror itemMirror = new Mirror(componentType, Array.get(value, i), classLoader, mirrorClassLoader);
+ Array.set(mirrorValue, i, itemMirror.getMirrorValue());
+ }
+ myMirrorType = mirrorValue.getClass();
+ myMirrorValue = value == null ? null : mirrorValue;
+ }
+ else if (type.isInterface()) {
+ myMirrorType = mirrorClassLoader.loadClass(type.getName());
+ myMirrorValue = value == null ? null
+ : Proxy.newProxyInstance(mirrorClassLoader,
+ new Class[]{myMirrorType},
+ new ReflectiveInvocationHandler(value, classLoader, mirrorClassLoader));
+ }
+ else {
+ myMirrorType = type;
+ myMirrorValue = value;
+ }
+ }
+
+ public Class<?> getMirrorType() {
+ return myMirrorType;
+ }
+
+ public Object getMirrorValue() {
+ return myMirrorValue;
+ }
+ }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentReflectiveThreadProxyFactory.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentReflectiveThreadProxyFactory.java
new file mode 100644
index 0000000..2669670
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentReflectiveThreadProxyFactory.java
@@ -0,0 +1,22 @@
+package com.intellij.remoteServer.agent.impl;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author michael.golubev
+ */
+public class RemoteAgentReflectiveThreadProxyFactory extends RemoteAgentThreadProxyFactory {
+
+ public RemoteAgentReflectiveThreadProxyFactory() {
+ this(null, (ClassLoader)null);
+ }
+
+ public RemoteAgentReflectiveThreadProxyFactory(RemoteAgentClassLoaderCache classLoaderCache, @Nullable ClassLoader callerClassLoader) {
+ this(classLoaderCache, new CallerClassLoaderProvider(callerClassLoader));
+ }
+
+ private RemoteAgentReflectiveThreadProxyFactory(RemoteAgentClassLoaderCache classLoaderCache,
+ CallerClassLoaderProvider callerClassLoaderProvider) {
+ super(callerClassLoaderProvider, new RemoteAgentReflectiveProxyFactory(classLoaderCache, callerClassLoaderProvider), null);
+ }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentThreadProxyCreator.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentThreadProxyCreator.java
new file mode 100644
index 0000000..c5be2b2
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentThreadProxyCreator.java
@@ -0,0 +1,32 @@
+package com.intellij.remoteServer.agent.impl;
+
+import com.intellij.remoteServer.agent.impl.util.SequentialTaskExecutor;
+import org.jetbrains.annotations.Nullable;
+
+import java.lang.reflect.Proxy;
+
+/**
+ * @author michael.golubev
+ */
+public class RemoteAgentThreadProxyCreator {
+
+ private final CallerClassLoaderProvider myCallerClassLoaderProvider;
+ private final ChildWrapperCreator myPreWrapperCreator;
+
+ public RemoteAgentThreadProxyCreator(CallerClassLoaderProvider callerClassLoaderProvider,
+ @Nullable ChildWrapperCreator preWrapperCreator) {
+ myPreWrapperCreator = preWrapperCreator;
+ myCallerClassLoaderProvider = callerClassLoaderProvider;
+ }
+
+ public <T> T createProxy(Class<T> agentInterface, T agentInstance) {
+ final SequentialTaskExecutor taskExecutor = new SequentialTaskExecutor();
+
+ ClassLoader callerClassLoader = myCallerClassLoaderProvider.getCallerClassLoader(agentInterface);
+
+ return agentInterface.cast(Proxy.newProxyInstance(callerClassLoader,
+ new Class[]{agentInterface},
+ new ThreadInvocationHandler(taskExecutor, callerClassLoader, agentInstance,
+ myPreWrapperCreator)));
+ }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentThreadProxyFactory.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentThreadProxyFactory.java
new file mode 100644
index 0000000..651e2ae
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/RemoteAgentThreadProxyFactory.java
@@ -0,0 +1,29 @@
+package com.intellij.remoteServer.agent.impl;
+
+import com.intellij.remoteServer.agent.RemoteAgentProxyFactory;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * @author michael.golubev
+ */
+public class RemoteAgentThreadProxyFactory implements RemoteAgentProxyFactory {
+
+ private final RemoteAgentThreadProxyCreator myCreator;
+ private final RemoteAgentProxyFactory myDelegate;
+
+ public RemoteAgentThreadProxyFactory(CallerClassLoaderProvider callerClassLoaderProvider, @NotNull RemoteAgentProxyFactory delegate,
+ @Nullable ChildWrapperCreator preWrapperCreator) {
+ myCreator = new RemoteAgentThreadProxyCreator(callerClassLoaderProvider, preWrapperCreator);
+ myDelegate = delegate;
+ }
+
+ @Override
+ public <T> T createProxy(List<File> libraries, Class<T> agentInterface, String agentClassName) throws Exception {
+ T agentDelegate = myDelegate.createProxy(libraries, agentInterface, agentClassName);
+ return myCreator.createProxy(agentInterface, agentDelegate);
+ }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ThreadInvocationHandler.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ThreadInvocationHandler.java
new file mode 100644
index 0000000..3e26022
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ThreadInvocationHandler.java
@@ -0,0 +1,153 @@
+package com.intellij.remoteServer.agent.impl;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.remoteServer.agent.annotation.AsyncCall;
+import com.intellij.remoteServer.agent.annotation.ChildCall;
+import com.intellij.remoteServer.agent.annotation.FinalCall;
+import com.intellij.remoteServer.agent.annotation.ImmediateCall;
+import com.intellij.remoteServer.agent.impl.util.FinalTask;
+import com.intellij.remoteServer.agent.impl.util.SequentialTaskExecutor;
+import com.intellij.util.containers.HashMap;
+import org.jetbrains.annotations.Nullable;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+/**
+ * @author michael.golubev
+ */
+public class ThreadInvocationHandler implements InvocationHandler {
+
+ private static final Logger LOG = Logger.getInstance("#" + ThreadInvocationHandler.class.getName());
+
+ private final SequentialTaskExecutor myTaskExecutor;
+ private final ClassLoader myCallerClassLoader;
+ private final Object myTarget;
+ private final ChildWrapperCreator myPreWrapperFactory;
+
+ private Map<Object, Object> myChild2Wrapped;
+
+ public ThreadInvocationHandler(SequentialTaskExecutor taskExecutor, ClassLoader callerClassLoader, Object target) {
+ this(taskExecutor, callerClassLoader, target, null);
+ }
+
+ public ThreadInvocationHandler(SequentialTaskExecutor taskExecutor, ClassLoader callerClassLoader, Object target,
+ @Nullable ChildWrapperCreator preWrapperCreator) {
+ myTaskExecutor = taskExecutor;
+ myCallerClassLoader = callerClassLoader;
+ myTarget = target;
+ myPreWrapperFactory = preWrapperCreator;
+ myChild2Wrapped = new HashMap<Object, Object>();
+ }
+
+ @Override
+ public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
+ final Callable<Object> taskCallable = new Callable<Object>() {
+
+ @Override
+ public Object call() {
+ try {
+ return method.invoke(myTarget, args);
+ }
+ catch (IllegalAccessException e) {
+ LOG.error(e);
+ return null;
+ }
+ catch (InvocationTargetException e) {
+ LOG.error(e);
+ return null;
+ }
+ }
+ };
+
+ try {
+ boolean immediateCall = method.getAnnotation(ImmediateCall.class) != null;
+
+ boolean childCall = method.getAnnotation(ChildCall.class) != null;
+ if (childCall) {
+ Object child = immediateCall ? taskCallable.call() : myTaskExecutor.queueAndWaitTask(taskCallable);
+ if (child == null) {
+ return null;
+ }
+
+ Object cached = myChild2Wrapped.get(child);
+ if (cached != null) {
+ return cached;
+ }
+
+ Class<?> childClass = child.getClass();
+ Class<?>[] childInterfaces = childClass.getInterfaces();
+ LOG.assertTrue(childInterfaces.length == 1, "Child class is expected to implement single child interface");
+ Class<?> childInterface = childInterfaces[0];
+
+ Class<?> callerChildInterface;
+ try {
+ callerChildInterface = myCallerClassLoader.loadClass(childInterface.getName());
+ }
+ catch (ClassNotFoundException e) {
+ LOG.error(e);
+ return null;
+ }
+
+ Object preWrappedChild;
+ if (myPreWrapperFactory == null) {
+ preWrappedChild = child;
+ }
+ else {
+ preWrappedChild = Proxy.newProxyInstance(myCallerClassLoader,
+ new Class[]{callerChildInterface},
+ myPreWrapperFactory.createWrapperInvocationHandler(child));
+ }
+
+ Object result = Proxy.newProxyInstance(myCallerClassLoader,
+ new Class[]{callerChildInterface},
+ new ThreadInvocationHandler(myTaskExecutor, myCallerClassLoader, preWrappedChild,
+ myPreWrapperFactory));
+
+ myChild2Wrapped.put(child, result);
+ return result;
+ }
+
+ if (immediateCall) {
+ return taskCallable.call();
+ }
+
+ boolean asyncCall = method.getAnnotation(AsyncCall.class) != null;
+
+ if (asyncCall) {
+ myTaskExecutor.queueTask(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ taskCallable.call();
+ }
+ catch (Exception e) {
+ LOG.error(e); // should never happen
+ }
+ }
+ });
+ return null;
+ }
+ else {
+ return myTaskExecutor.queueAndWaitTask(taskCallable);
+ }
+ }
+ finally {
+ boolean finalCall = method.getAnnotation(FinalCall.class) != null;
+ if (finalCall) {
+ myTaskExecutor.queueTask(new FinalTask() {
+
+ @Override
+ public void run() {
+
+ }
+ });
+ }
+ }
+ }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/FinalTask.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/FinalTask.java
new file mode 100644
index 0000000..7d3ce82
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/FinalTask.java
@@ -0,0 +1,9 @@
+package com.intellij.remoteServer.agent.impl.util;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: michael.golubev
+ */
+public interface FinalTask extends Runnable {
+
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/SequentialTaskExecutor.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/SequentialTaskExecutor.java
new file mode 100644
index 0000000..fa9c320
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/SequentialTaskExecutor.java
@@ -0,0 +1,81 @@
+package com.intellij.remoteServer.agent.impl.util;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Ref;
+import com.intellij.util.concurrency.Semaphore;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: michael.golubev
+ */
+public class SequentialTaskExecutor {
+
+ private static final Logger LOG = Logger.getInstance("#" + SequentialTaskExecutor.class.getName());
+
+ private BlockingQueue<Runnable> myTasks;
+
+ public SequentialTaskExecutor() {
+ myTasks = new LinkedBlockingQueue<Runnable>();
+
+ ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ while (true) {
+ Runnable task = myTasks.take();
+ task.run();
+ if (task instanceof FinalTask) {
+ break;
+ }
+ }
+ }
+ catch (InterruptedException e) {
+ LOG.debug(e);
+ }
+ }
+ });
+ }
+
+ public void queueTask(Runnable task) {
+ myTasks.offer(task);
+ }
+
+ public <V> V queueAndWaitTask(final Callable<V> task) throws Throwable {
+ final Ref<V> resultRef = new Ref<V>();
+ final Ref<Throwable> throwableRef = new Ref<Throwable>();
+
+ final Semaphore taskSemaphore = new Semaphore();
+ taskSemaphore.down();
+
+ queueTask(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ resultRef.set(task.call());
+ }
+ catch (Throwable e) {
+ throwableRef.set(e);
+ LOG.error(e);
+ }
+ finally {
+ taskSemaphore.up();
+ }
+ }
+ });
+
+ taskSemaphore.waitFor();
+
+ if (!throwableRef.isNull()) {
+ throw throwableRef.get();
+ }
+
+ return resultRef.get();
+ }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/UrlCollector.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/UrlCollector.java
new file mode 100644
index 0000000..21e9f8c
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/util/UrlCollector.java
@@ -0,0 +1,64 @@
+package com.intellij.remoteServer.agent.impl.util;
+
+import com.intellij.openapi.diagnostic.Logger;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: michael.golubev
+ */
+public class UrlCollector {
+
+ private static final Logger LOG = Logger.getInstance("#" + UrlCollector.class.getName());
+
+ private List<File> myFiles;
+
+ public URL[] collect(Collection<File> libraries) {
+ List<File> files = collectFiles(libraries);
+ URL[] result = new URL[files.size()];
+ for (int i = 0; i < files.size(); i++) {
+ try {
+ result[i] = files.get(i).toURI().toURL();
+ }
+ catch (MalformedURLException e) {
+ LOG.error(e); // should never happen
+ }
+ }
+ return result;
+ }
+
+ public List<File> collectFiles(Collection<File> libraries) {
+ myFiles = new ArrayList<File>();
+ for (File library : libraries) {
+ if (library.exists()) {
+ addFile(library);
+ if (library.isDirectory()) {
+ addLibraries(library);
+ }
+ }
+ }
+ return myFiles;
+ }
+
+ private void addLibraries(File dir) {
+ for (File file : dir.listFiles()) {
+ if (file.isDirectory()) {
+ addLibraries(file);
+ }
+ else if (file.getName().endsWith(".jar")) {
+ addFile(file);
+ }
+ }
+ }
+
+ private void addFile(File file) {
+ LOG.debug("addFile: " + file.getAbsolutePath());
+ myFiles.add(file);
+ }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentInformation.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentInformation.java
deleted file mode 100644
index 97117e4..0000000
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentInformation.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.intellij.remoteServer.impl.runtime.deployment;
-
-import com.intellij.remoteServer.runtime.deployment.DeploymentStatus;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * @author nik
- */
-public class DeploymentInformation {
- private final DeploymentStatus myStatus;
- private final String myStatusText;
-
- public DeploymentInformation(@NotNull DeploymentStatus status) {
- myStatus = status;
- myStatusText = status.name();
- }
-
- public DeploymentInformation(@NotNull DeploymentStatus status, @NotNull String statusText) {
- myStatus = status;
- myStatusText = statusText;
- }
-
- public DeploymentStatus getStatus() {
- return myStatus;
- }
-
- public String getStatusText() {
- return myStatusText;
- }
-}
diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
index bd407c9..6e1d901 100644
--- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
@@ -74,6 +74,7 @@
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.encoding.EncodingManager;
import com.intellij.openapi.vfs.encoding.EncodingManagerImpl;
+import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
import com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFSImpl;
@@ -89,6 +90,7 @@
import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl;
import com.intellij.psi.templateLanguages.TemplateDataLanguageMappings;
+import com.intellij.util.Consumer;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.LocalTimeCounter;
import com.intellij.util.containers.ContainerUtil;
@@ -109,11 +111,16 @@
import java.io.PrintStream;
import java.util.*;
+import static com.intellij.openapi.roots.ModuleRootModificationUtil.updateModel;
+
/**
* @author yole
*/
public abstract class LightPlatformTestCase extends UsefulTestCase implements DataProvider {
- public static final String PROFILE = "Configurable";
+ @NonNls public static final String PROFILE = "Configurable";
+
+ @NonNls private static final String LIGHT_PROJECT_MARK = "Light project: ";
+
private static IdeaTestApplication ourApplication;
protected static Project ourProject;
private static Module ourModule;
@@ -123,9 +130,9 @@
private static TestCase ourTestCase = null;
public static Thread ourTestThread;
private static LightProjectDescriptor ourProjectDescriptor;
- @NonNls private static final String LIGHT_PROJECT_MARK = "Light project: ";
- private final Map<String, InspectionToolWrapper> myAvailableInspectionTools = new THashMap<String, InspectionToolWrapper>();
private static boolean ourHaveShutdownHook;
+
+ private final Map<String, InspectionToolWrapper> myAvailableInspectionTools = new THashMap<String, InspectionToolWrapper>();
private ThreadTracker myThreadTracker;
/**
@@ -202,9 +209,11 @@
private static void initProject(@NotNull final LightProjectDescriptor descriptor) throws Exception {
ourProjectDescriptor = descriptor;
+
final File projectFile = FileUtil.createTempFile("light_temp_", ProjectFileType.DOT_DEFAULT_EXTENSION);
new WriteCommandAction.Simple(null) {
+ @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod")
@Override
protected void run() throws Throwable {
if (ourProject != null) {
@@ -220,6 +229,7 @@
new Throwable(projectFile.getPath()).printStackTrace(new PrintStream(buffer));
ourProject = PlatformTestCase.createProject(projectFile, LIGHT_PROJECT_MARK + buffer.toString());
+ ourPathToKeep = projectFile.getPath();
if (!ourHaveShutdownHook) {
ourHaveShutdownHook = true;
registerShutdownHook();
@@ -227,14 +237,13 @@
ourPsiManager = null;
ourModule = createMainModule(descriptor.getModuleType());
-
- //ourSourceRoot = DummyFileSystem.getInstance().createRoot("src");
-
- final VirtualFile dummyRoot = VirtualFileManager.getInstance().findFileByUrl("temp:///");
+ VirtualFile dummyRoot = VirtualFileManager.getInstance().findFileByUrl("temp:///");
+ assert dummyRoot != null;
dummyRoot.refresh(false, false);
try {
ourSourceRoot = dummyRoot.createChildDirectory(this, "src");
+ cleanSourceRoot();
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -255,39 +264,35 @@
@Override
public boolean visitFile(@NotNull VirtualFile file) {
iterator.processFile(file);
-
return true;
}
});
}
}, null);
- final ModuleRootManager rootManager = ModuleRootManager.getInstance(ourModule);
-
- final ModifiableRootModel rootModel = rootManager.getModifiableModel();
-
-
- if (descriptor.getSdk() != null) {
- rootModel.setSdk(descriptor.getSdk());
- }
-
- final ContentEntry contentEntry = rootModel.addContentEntry(ourSourceRoot);
- contentEntry.addSourceFolder(ourSourceRoot, false);
-
- descriptor.configureModule(ourModule, rootModel, contentEntry);
-
- rootModel.commit();
-
- final MessageBusConnection connection = ourProject.getMessageBus().connect();
- connection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
+ updateModel(ourModule, new Consumer<ModifiableRootModel>() {
@Override
- public void beforeRootsChange(ModuleRootEvent event) {
- if (!event.isCausedByFileTypesChange()) {
- //TODO: uncomment fail("Root modification in LightIdeaTestCase is not allowed.");
+ public void consume(ModifiableRootModel model) {
+ if (descriptor.getSdk() != null) {
+ model.setSdk(descriptor.getSdk());
}
+
+ ContentEntry contentEntry = model.addContentEntry(ourSourceRoot);
+ contentEntry.addSourceFolder(ourSourceRoot, false);
+
+ descriptor.configureModule(ourModule, model, contentEntry);
}
});
+ MessageBusConnection connection = ourProject.getMessageBus().connect();
+ connection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
+ @Override
+ public void beforeRootsChange(ModuleRootEvent event) {
+ /*if (!event.isCausedByFileTypesChange()) {
+ fail("Root modification in LightIdeaTestCase is not allowed.");
+ }*/
+ }
+ });
connection.subscribe(ProjectTopics.MODULES, new ModuleAdapter() {
@Override
public void moduleAdded(Project project, Module module) {
@@ -295,12 +300,22 @@
}
});
-
- final StartupManagerImpl startupManager = (StartupManagerImpl)StartupManager.getInstance(ourProject);
+ StartupManagerImpl startupManager = (StartupManagerImpl)StartupManager.getInstance(ourProject);
startupManager.runStartupActivities();
startupManager.startCacheUpdate();
}
+
+ private void cleanSourceRoot() throws IOException {
+ TempFileSystem tempFs = (TempFileSystem)ourSourceRoot.getFileSystem();
+ for (VirtualFile child : ourSourceRoot.getChildren()) {
+ if (!tempFs.exists(child)) {
+ tempFs.createChildFile(this, ourSourceRoot, child.getName());
+ }
+ child.delete(this);
+ }
+ }
}.execute().throwException();
+
// project creation may make a lot of pointers, do not regard them as leak
((VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance()).storePointers();
}
@@ -339,12 +354,11 @@
public static void doSetup(@NotNull LightProjectDescriptor descriptor,
@NotNull LocalInspectionTool[] localInspectionTools,
- @NotNull final Map<String, InspectionToolWrapper> availableInspectionTools)
- throws Exception {
+ @NotNull final Map<String, InspectionToolWrapper> availableInspectionTools) throws Exception {
assertNull("Previous test " + ourTestCase + " hasn't called tearDown(). Probably overridden without super call.", ourTestCase);
IdeaLogger.ourErrorsOccurred = null;
- if (ourProject == null || !ourProjectDescriptor.equals(descriptor)) {
+ if (ourProject == null || ourProjectDescriptor == null || !ourProjectDescriptor.equals(descriptor)) {
initProject(descriptor);
}
((ProjectImpl)ourProject).setTemporarilyDisposed(false);
@@ -762,26 +776,32 @@
return PsiDocumentManager.getInstance(getProject()).getDocument(file);
}
+ @SuppressWarnings("NonPrivateFieldAccessedInSynchronizedContext")
public static synchronized void closeAndDeleteProject() {
if (ourProject != null) {
ApplicationManager.getApplication().assertWriteAccessAllowed();
+
((ProjectImpl)ourProject).setTemporarilyDisposed(false);
- final VirtualFile projFile = ((ProjectEx)ourProject).getStateStore().getProjectFile();
- final File projectFile = projFile == null ? null : VfsUtilCore.virtualToIoFile(projFile);
+ VirtualFile projectFile = ((ProjectEx)ourProject).getStateStore().getProjectFile();
+ File ioFile = projectFile == null ? null : VfsUtilCore.virtualToIoFile(projectFile);
if (!ourProject.isDisposed()) Disposer.dispose(ourProject);
- if (projectFile != null) {
- FileUtil.delete(projectFile);
+ if (ioFile != null) {
+ File dir = ioFile.getParentFile();
+ if (dir.getName().startsWith(UsefulTestCase.TEMP_DIR_MARKER)) {
+ FileUtil.delete(dir);
+ }
+ else {
+ FileUtil.delete(ioFile);
+ }
}
+
+ ProjectManagerEx.getInstanceEx().closeTestProject(ourProject);
ourProject = null;
+ ourPathToKeep = null;
}
}
-
- static {
- System.setProperty("jbdt.test.fixture", "com.intellij.designer.dt.IJTestFixture");
- }
-
private static void registerShutdownHook() {
ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
@Override
diff --git a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java
index 9005752..7d35679 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java
@@ -54,6 +54,8 @@
import java.util.Collection;
import java.util.List;
+import static com.intellij.openapi.roots.ModuleRootModificationUtil.updateModel;
+
@NonNls
public class PsiTestUtil {
public static VirtualFile createTestProjectStructure(Project project,
@@ -400,28 +402,4 @@
}
});
}
-
- private static void updateModel(Module module, Consumer<ModifiableRootModel> task) {
- updateModel(ModuleRootManager.getInstance(module).getModifiableModel(), task);
- }
-
- private static void updateModel(ModifiableRootModel model, Consumer<ModifiableRootModel> task) {
- try {
- task.consume(model);
- commitModel(model);
- }
- catch (Throwable t) {
- model.dispose();
- throw new RuntimeException(t);
- }
- }
-
- private static void commitModel(final ModifiableRootModel model) {
- new WriteCommandAction.Simple(model.getProject()) {
- @Override
- protected void run() throws Throwable {
- model.commit();
- }
- }.execute().throwException();
- }
}
\ No newline at end of file
diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
index 404eff3..02cd178 100644
--- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -69,17 +69,18 @@
* @author peter
*/
public abstract class UsefulTestCase extends TestCase {
+ public static final String IDEA_MARKER_CLASS = "com.intellij.openapi.components.impl.stores.IdeaProjectStoreImpl";
+ public static final String TEMP_DIR_MARKER = "unitTest_";
+
protected static boolean OVERWRITE_TESTDATA = false;
private static final String DEFAULT_SETTINGS_EXTERNALIZED;
- private static final Random PRNG = new SecureRandom();
+ private static final Random RNG = new SecureRandom();
private static final String ORIGINAL_TEMP_DIR = FileUtil.getTempDirectory();
- public static final String IDEA_MARKER_CLASS = "com.intellij.openapi.components.impl.stores.IdeaProjectStoreImpl";
protected final Disposable myTestRootDisposable = new Disposable() {
@Override
- public void dispose() {
- }
+ public void dispose() { }
@Override
public String toString() {
@@ -87,6 +88,9 @@
return UsefulTestCase.this.getClass() + (StringUtil.isEmpty(testName) ? "" : ".test" + testName);
}
};
+
+ protected static String ourPathToKeep = null;
+
private CodeStyleSettings myOldCodeStyleSettings;
private String myTempDir;
@@ -119,9 +123,10 @@
String testName = getTestName(true);
if (StringUtil.isEmptyOrSpaces(testName)) testName = "";
testName = new File(testName).getName(); // in case the test name contains file separators
- myTempDir = ORIGINAL_TEMP_DIR + "/unitTest_" + testName + "_"+ PRNG.nextInt(1000);
+ myTempDir = FileUtil.toSystemDependentName(ORIGINAL_TEMP_DIR + "/" + TEMP_DIR_MARKER + testName + "_"+ RNG.nextInt(1000));
FileUtil.resetCanonicalTempPathCache(myTempDir);
}
+ //noinspection AssignmentToStaticFieldFromInstanceMethod
DocumentImpl.CHECK_DOCUMENT_CONSISTENCY = !isPerformanceTest();
}
@@ -134,7 +139,19 @@
finally {
if (shouldContainTempFiles()) {
FileUtil.resetCanonicalTempPathCache(ORIGINAL_TEMP_DIR);
- FileUtil.delete(new File(myTempDir));
+ if (ourPathToKeep != null && FileUtil.isAncestor(myTempDir, ourPathToKeep, false)) {
+ File[] files = new File(myTempDir).listFiles();
+ if (files != null) {
+ for (File file : files) {
+ if (!FileUtil.pathsEqual(file.getPath(), ourPathToKeep)) {
+ FileUtil.delete(file);
+ }
+ }
+ }
+ }
+ else {
+ FileUtil.delete(new File(myTempDir));
+ }
}
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java
index 84848f0..5259fa0 100644
--- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java
+++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,6 +39,7 @@
/**
* @author mike
*/
+@SuppressWarnings("TestOnlyProblems")
public class LightIdeaTestFixtureImpl extends BaseFixture implements LightIdeaTestFixture {
private final LightProjectDescriptor myProjectDescriptor;
private CodeStyleSettings myOldCodeStyleSettings;
@@ -73,10 +74,9 @@
super.tearDown();
InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project);
PersistentFS.getInstance().clearIdCache();
- ((DirectoryIndexImpl)DirectoryIndex.getInstance(project)).assertAncestorConsistent();
+ ((DirectoryIndexImpl)DirectoryIndex.getInstance(project)).assertAncestorConsistent();
}
-
@Override
public Project getProject() {
return LightPlatformTestCase.getProject();
diff --git a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java
index cf7b95d..dc9068e 100644
--- a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java
+++ b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java
@@ -298,13 +298,9 @@
return attrs;
}
- private void appendPrefix(List<TextChunk> result, int lineNumber, int columnNumber) {
- StringBuilder buffer = new StringBuilder("(");
- buffer.append(lineNumber + 1);
- buffer.append(": ");
- buffer.append(columnNumber + 1);
- buffer.append(") ");
- TextChunk prefixChunk = new TextChunk(myColorsScheme.getAttributes(UsageTreeColors.USAGE_LOCATION), buffer.toString());
+ private void appendPrefix(@NotNull List<TextChunk> result, int lineNumber, int columnNumber) {
+ String prefix = "(" + (lineNumber + 1) + ": " + (columnNumber + 1) + ") ";
+ TextChunk prefixChunk = new TextChunk(myColorsScheme.getAttributes(UsageTreeColors.USAGE_LOCATION), prefix);
result.add(prefixChunk);
}
}
diff --git a/platform/util-rt/src/com/intellij/openapi/util/UnorderedPair.java b/platform/util-rt/src/com/intellij/openapi/util/UnorderedPair.java
new file mode 100644
index 0000000..83a4859
--- /dev/null
+++ b/platform/util-rt/src/com/intellij/openapi/util/UnorderedPair.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.util;
+
+public class UnorderedPair<T> {
+ public final T first;
+ public final T second;
+
+ public UnorderedPair(T first, T second) {
+ this.first = first;
+ this.second = second;
+ }
+
+ @Override
+ public int hashCode() {
+ int hc1 = first == null ? 0 : first.hashCode();
+ int hc2 = second == null ? 0 : second.hashCode();
+ return hc1 * hc1 + hc2 * hc2;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) return false;
+ if (obj.getClass() != getClass()) return false;
+
+ final UnorderedPair other = (UnorderedPair)obj;
+ if (Comparing.equal(other.first, first) && Comparing.equal(other.second, second)) return true;
+ if (Comparing.equal(other.first, second) && Comparing.equal(other.second, first)) return true;
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "<" + first + ", " + second + '>';
+ }
+}
diff --git a/platform/util/src/com/intellij/openapi/util/JDOMUtil.java b/platform/util/src/com/intellij/openapi/util/JDOMUtil.java
index e143ef8..665776f 100644
--- a/platform/util/src/com/intellij/openapi/util/JDOMUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/JDOMUtil.java
@@ -17,6 +17,7 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.StringInterner;
import com.intellij.util.io.URLUtil;
@@ -25,6 +26,7 @@
import com.intellij.util.text.CharSequenceReader;
import com.intellij.util.text.StringFactory;
import org.jdom.*;
+import org.jdom.filter.ElementFilter;
import org.jdom.filter.Filter;
import org.jdom.input.DOMBuilder;
import org.jdom.input.SAXBuilder;
@@ -56,12 +58,11 @@
@NotNull
public static List<Element> getChildren(@Nullable Element parent) {
- if (parent != null) {
- @SuppressWarnings({"UnnecessaryLocalVariable", "unchecked"}) final List<Element> children = parent.getChildren();
- return children;
+ if (parent == null) {
+ return Collections.emptyList();
}
else {
- return Collections.emptyList();
+ return parent.getChildren();
}
}
@@ -82,8 +83,6 @@
return LoggerHolder.ourLogger;
}
- private static final String ENCODING = "UTF-8";
-
public static boolean areElementsEqual(Element e1, Element e2) {
if (e1 == null && e2 == null) return true;
if (e1 == null || e2 == null) return false;
@@ -106,16 +105,12 @@
private static int addToHash(int i, @NotNull final Element element) {
i = addToHash(i, element.getName());
- final List<Attribute> list = element.getAttributes();
- //noinspection ForLoopReplaceableByForEach
- for (int j = 0; j < list.size(); j++) {
- i = addToHash(i, list.get(j));
+ for (Attribute aList : element.getAttributes()) {
+ i = addToHash(i, aList);
}
List<Content> content = element.getContent();
- //noinspection ForLoopReplaceableByForEach
- for (int j = 0; j < content.size(); j++) {
- Content child = content.get(j);
+ for (Content child : content) {
if (child instanceof Element) {
i = addToHash(i, (Element)child);
}
@@ -137,7 +132,6 @@
return i * 31 + s.hashCode();
}
- @SuppressWarnings({"unchecked"})
@NotNull
public static Object[] getChildNodesWithAttrs(@NotNull Element e) {
ArrayList<Object> result = new ArrayList<Object>();
@@ -146,18 +140,16 @@
return ArrayUtil.toObjectArray(result);
}
- @SuppressWarnings({"unchecked"})
@NotNull
- public static Content[] getContent(@NotNull final Element m) {
- final List list = m.getContent();
- return (Content[])list.toArray(new Content[list.size()]);
+ public static Content[] getContent(@NotNull Element m) {
+ List<Content> list = m.getContent();
+ return list.toArray(new Content[list.size()]);
}
- @SuppressWarnings({"unchecked"})
@NotNull
- public static Element[] getElements(@NotNull final Element m) {
- final List list = m.getChildren();
- return (Element[])list.toArray(new Element[list.size()]);
+ public static Element[] getElements(@NotNull Element m) {
+ List<Element> list = m.getChildren();
+ return list.toArray(new Element[list.size()]);
}
@NotNull
@@ -186,15 +178,12 @@
public static void internElement(@NotNull Element element, @NotNull StringInterner interner) {
element.setName(intern(interner, element.getName()));
- final List attributes = element.getAttributes();
- for (Object o : attributes) {
- Attribute attr = (Attribute)o;
+ for (Attribute attr : element.getAttributes()) {
attr.setName(intern(interner, attr.getName()));
attr.setValue(intern(interner, attr.getValue()));
}
- final List content = element.getContent();
- for (Object o : content) {
+ for (Content o : element.getContent()) {
if (o instanceof Element) {
Element e = (Element)o;
internElement(e, interner);
@@ -226,7 +215,6 @@
StringBuilder result = new StringBuilder();
while(true) {
- //noinspection EmptyCatchBlock
try {
int each = reader.read();
if (each == -1) break;
@@ -237,7 +225,7 @@
result.append("0x").append(StringUtil.toUpperCase(Long.toHexString(each)));
}
}
- catch (IOException e) {
+ catch (IOException ignored) {
}
}
@@ -248,11 +236,7 @@
private static class EmptyTextFilter implements Filter {
@Override
public boolean matches(Object obj) {
- if (obj instanceof Text) {
- final Text t = (Text)obj;
- return !CharArrayUtil.containsOnlyWhiteSpaces(t.getText());
- }
- return true;
+ return !(obj instanceof Text) || !CharArrayUtil.containsOnlyWhiteSpaces(((Text)obj).getText());
}
}
@@ -375,7 +359,7 @@
@NotNull
public static Document loadDocument(@NotNull InputStream stream) throws JDOMException, IOException {
- InputStreamReader reader = new InputStreamReader(stream, ENCODING);
+ InputStreamReader reader = new InputStreamReader(stream, CharsetToolkit.UTF8_CHARSET);
try {
return getSaxBuilder().build(reader);
}
@@ -424,7 +408,7 @@
}
public static void writeDocument(@NotNull Document document, @NotNull OutputStream stream, String lineSeparator) throws IOException {
- writeDocument(document, new OutputStreamWriter(stream, ENCODING), lineSeparator);
+ writeDocument(document, new OutputStreamWriter(stream, CharsetToolkit.UTF8_CHARSET), lineSeparator);
}
@@ -433,7 +417,7 @@
CharArrayWriter writer = new CharArrayWriter();
writeDocument(document, writer, lineSeparator);
- return StringFactory.createShared(writer.toCharArray()).getBytes(ENCODING);
+ return StringFactory.createShared(writer.toCharArray()).getBytes(CharsetToolkit.UTF8_CHARSET);
}
@NotNull
@@ -529,7 +513,7 @@
Format format = Format.getCompactFormat().
setIndent(" ").
setTextMode(Format.TextMode.TRIM).
- setEncoding(ENCODING).
+ setEncoding(CharsetToolkit.UTF8).
setOmitEncoding(false).
setOmitDeclaration(false).
setLineSeparator(lineSeparator);
@@ -754,4 +738,35 @@
throw new IllegalArgumentException("Wrong node: " + node);
}
}
+
+ @Nullable
+ public static Element cloneElement(@NotNull Element element, @NotNull ElementFilter elementFilter) {
+ Element result = new Element(element.getName(), element.getNamespace());
+ List<Attribute> attributes = element.getAttributes();
+ if (!attributes.isEmpty()) {
+ ArrayList<Attribute> list = new ArrayList<Attribute>(attributes.size());
+ for (Attribute attribute : attributes) {
+ list.add(attribute.clone());
+ }
+ result.setAttributes(list);
+ }
+
+ for (Namespace namespace : element.getAdditionalNamespaces()) {
+ result.addNamespaceDeclaration(namespace);
+ }
+
+ boolean hasContent = false;
+ for (Content content : element.getContent()) {
+ if (content instanceof Element) {
+ if (elementFilter.matches(content)) {
+ hasContent = true;
+ }
+ else {
+ continue;
+ }
+ }
+ result.addContent(content.clone());
+ }
+ return hasContent ? result : null;
+ }
}
diff --git a/platform/util/src/com/intellij/openapi/util/Key.java b/platform/util/src/com/intellij/openapi/util/Key.java
index 2c3be89..7dc881b 100644
--- a/platform/util/src/com/intellij/openapi/util/Key.java
+++ b/platform/util/src/com/intellij/openapi/util/Key.java
@@ -59,12 +59,10 @@
return new Key<T>(name);
}
- @Nullable
public T get(@Nullable UserDataHolder holder) {
return holder == null ? null : holder.getUserData(this);
}
- @Nullable
public T get(@Nullable Map<Key, ?> holder) {
//noinspection unchecked
return holder == null ? null : (T)holder.get(this);
diff --git a/platform/util/src/com/intellij/openapi/util/RoamingTypePerPlatform.java b/platform/util/src/com/intellij/openapi/util/RoamingTypePerPlatform.java
deleted file mode 100644
index 153aaa0..0000000
--- a/platform/util/src/com/intellij/openapi/util/RoamingTypePerPlatform.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.openapi.util;
-
-public interface RoamingTypePerPlatform {
-}
diff --git a/platform/util/src/com/intellij/openapi/util/TextRange.java b/platform/util/src/com/intellij/openapi/util/TextRange.java
index 854f00d..797bc23 100644
--- a/platform/util/src/com/intellij/openapi/util/TextRange.java
+++ b/platform/util/src/com/intellij/openapi/util/TextRange.java
@@ -134,11 +134,17 @@
return segment1.getStartOffset() == segment2.getStartOffset()
&& segment1.getEndOffset() == segment2.getEndOffset();
}
+
@NotNull
public String replace(@NotNull String original, @NotNull String replacement) {
- String beginning = original.substring(0, getStartOffset());
- String ending = original.substring(getEndOffset(), original.length());
- return beginning + replacement + ending;
+ try {
+ String beginning = original.substring(0, getStartOffset());
+ String ending = original.substring(getEndOffset(), original.length());
+ return beginning + replacement + ending;
+ }
+ catch (StringIndexOutOfBoundsException e) {
+ throw new StringIndexOutOfBoundsException("Can't replace " + this + " range from '" + original + "' with '" + replacement + "'");
+ }
}
public boolean intersects(@NotNull TextRange textRange) {
diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
index 241244e..b93b988 100644
--- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
@@ -1620,8 +1620,14 @@
public static int indexOfAny(@NotNull final String s, @NotNull final String chars) {
return indexOfAny(s, chars, 0, s.length());
}
+ public static int indexOfAny(@NotNull final CharSequence s, @NotNull final String chars) {
+ return indexOfAny(s, chars, 0, s.length());
+ }
public static int indexOfAny(@NotNull final String s, @NotNull final String chars, final int start, final int end) {
+ return indexOfAny((CharSequence)s, chars, start, end);
+ }
+ public static int indexOfAny(@NotNull final CharSequence s, @NotNull final String chars, final int start, final int end) {
for (int i = start; i < end; i++) {
if (containsChar(chars, s.charAt(i))) return i;
}
diff --git a/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java
index c8871be..c96e79b 100644
--- a/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java
+++ b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java
@@ -142,11 +142,12 @@
if (iterable.isEmpty()) return 0;
final TextRange first = iterable.getHead();
+ boolean startMatch = first.getStartOffset() == 0;
int matchingCase = 0;
int p = -1;
- int integral = 0; // sum of matching-character-count * hump-index over all matched humps; favors longer fragments matching earlier words
+ int integral = 0; // -sum of matching-char-count * hump-index over all matched humps; favors longer fragments matching earlier words
int humpIndex = 1;
int nextHumpStart = 0;
for (TextRange range : iterable) {
@@ -161,7 +162,7 @@
humpIndex++;
}
}
- integral += humpIndex;
+ integral -= humpIndex;
char c = name.charAt(i);
p = StringUtil.indexOf(myPattern, c, p + 1, myPattern.length, false);
@@ -169,9 +170,10 @@
break;
}
- // favor uppercase letters matching hump start
if (c == myPattern[p]) {
- matchingCase += isUpperCase[p] ? 50 : isHumpStart ? 1 : 0;
+ if (isUpperCase[p]) matchingCase += 50; // strongly prefer user's uppercase matching uppercase: they made an effort to press Shift
+ else if (i == 0 && startMatch) matchingCase += 15; // the very first letter case distinguishes classes in Java etc
+ else if (isHumpStart) matchingCase += 1; // if a lowercase matches lowercase hump start, that also means something
} else if (isHumpStart) {
// disfavor hump starts where pattern letter case doesn't match name case
matchingCase -= 20;
@@ -183,9 +185,12 @@
boolean afterSeparator = StringUtil.indexOfAny(name, HARD_SEPARATORS, 0, startIndex) >= 0;
boolean wordStart = startIndex == 0 || isWordStart(name, startIndex) && !isWordStart(name, startIndex - 1);
boolean finalMatch = iterable.get(iterable.size() - 1).getEndOffset() == name.length();
- boolean startMatch = iterable.get(0).getStartOffset() == 0;
- return (wordStart ? 1000 : 0) - integral * 10 + matchingCase + (afterSeparator ? 0 : 2) + (startMatch ? 1 : 0) + (finalMatch ? 1 : 0);
+ return (wordStart ? 1000 : 0) +
+ integral * 10 +
+ matchingCase * (startMatch ? 10 : 1) + // in start matches, case is more important; in middle matches - fragment length (integral)
+ (afterSeparator ? 0 : 2) +
+ (finalMatch ? 1 : 0);
}
public boolean isStartMatch(@NotNull String name) {
diff --git a/platform/util/src/com/intellij/util/EnvironmentUtil.java b/platform/util/src/com/intellij/util/EnvironmentUtil.java
index 11ff535..333920b 100644
--- a/platform/util/src/com/intellij/util/EnvironmentUtil.java
+++ b/platform/util/src/com/intellij/util/EnvironmentUtil.java
@@ -15,6 +15,8 @@
*/
package com.intellij.util;
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
import com.intellij.execution.process.UnixProcessManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.AtomicNotNullLazyValue;
@@ -22,6 +24,7 @@
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.concurrency.FixedFuture;
import com.intellij.util.text.CaseInsensitiveStringHashingStrategy;
import gnu.trove.THashMap;
@@ -128,52 +131,63 @@
@SuppressWarnings("SpellCheckingInspection")
private static Map<String, String> getShellEnv() {
+ File envFile = null;
try {
String shell = System.getenv("SHELL");
if (shell == null || !new File(shell).canExecute()) {
throw new Exception("shell:" + shell);
}
- String[] command = {shell, "-l", "-c", "/usr/bin/printenv"};
+ envFile = FileUtil.createTempFile("intellij-shell-env", null, false);
+ String[] command = {shell, "-l", "-c", "/usr/bin/printenv > '" + envFile.getAbsolutePath() + "'"};
+ LOG.info("loading shell env: " + StringUtil.join(command, " "));
Process process = Runtime.getRuntime().exec(command);
ProcessKiller processKiller = new ProcessKiller(process);
processKiller.killAfter(SHELL_ENV_READING_TIMEOUT);
- List<String> lines = FileUtil.loadLines(process.getInputStream());
- processKiller.stopWaiting();
int rv = process.waitFor();
+ processKiller.stopWaiting();
+ List<String> lines = Files.readLines(envFile, Charsets.UTF_8);
if (rv != 0 || lines.isEmpty()) {
throw new Exception("rv:" + rv + " lines:" + lines.size());
}
-
- Set<String> toIgnore = new HashSet<String>(Arrays.asList("_", "PWD", "SHLVL"));
- Map<String, String> env = System.getenv();
- Map<String, String> newEnv = new HashMap<String, String>();
- for (String line : lines) {
- int pos = line.indexOf('=');
- if (pos <= 0) {
- LOG.warn("malformed:" + line);
- continue;
- }
- String name = line.substring(0, pos);
- if (!toIgnore.contains(name)) {
- newEnv.put(name, line.substring(pos + 1));
- }
- else if (env.containsKey(name)) {
- newEnv.put(name, env.get(name));
- }
- }
- if (newEnv.size() < lines.size() - toIgnore.size()) {
- // some lines weren't parsed - we're better to fall back to original environment than use possibly incomplete one
- throw new Exception("env:" + newEnv.size() + " lines:" + lines.size());
- }
-
- LOG.info("shell environment loaded (" + newEnv.size() + " vars)");
- return Collections.unmodifiableMap(newEnv);
+ return parseEnv(lines);
}
catch (Throwable t) {
LOG.warn("can't get shell environment", t);
return System.getenv();
}
+ finally {
+ if (envFile != null) {
+ FileUtil.delete(envFile);
+ }
+ }
+ }
+
+ private static Map<String, String> parseEnv(List<String> lines) throws Exception {
+ Set<String> toIgnore = new HashSet<String>(Arrays.asList("_", "PWD", "SHLVL"));
+ Map<String, String> env = System.getenv();
+ Map<String, String> newEnv = new HashMap<String, String>();
+ for (String line : lines) {
+ int pos = line.indexOf('=');
+ if (pos <= 0) {
+ LOG.warn("malformed:" + line);
+ continue;
+ }
+ String name = line.substring(0, pos);
+ if (!toIgnore.contains(name)) {
+ newEnv.put(name, line.substring(pos + 1));
+ }
+ else if (env.containsKey(name)) {
+ newEnv.put(name, env.get(name));
+ }
+ }
+ if (newEnv.size() < lines.size() - toIgnore.size()) {
+ // some lines weren't parsed - we're better to fall back to original environment than use possibly incomplete one
+ throw new Exception("env:" + newEnv.size() + " lines:" + lines.size());
+ }
+
+ LOG.info("shell environment loaded (" + newEnv.size() + " vars)");
+ return Collections.unmodifiableMap(newEnv);
}
private static class ProcessKiller {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
index 16013cf..ca8d5bb 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
@@ -67,7 +67,7 @@
/**
* @author max
*/
-public class ChangeListManagerImpl extends ChangeListManagerEx implements ProjectComponent, ChangeListOwner, JDOMExternalizable {
+public class ChangeListManagerImpl extends ChangeListManagerEx implements ProjectComponent, ChangeListOwner, JDOMExternalizable, RoamingTypeDisabled {
public static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.ChangeListManagerImpl");
private final Project myProject;
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeManagerImpl.java
index 70127c3..6e44a78 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeManagerImpl.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeManagerImpl.java
@@ -105,7 +105,7 @@
if ((! myProject.isOpen()) || myProject.isDisposed() || myVcsManager.getAllActiveVcss().length == 0) return;
if (LOG.isDebugEnabled()) {
- LOG.debug("everything dirty: " + ReflectionUtil.findCallerClass(1));
+ LOG.debug("everything dirty: " + ReflectionUtil.findCallerClass(2));
}
final LifeDrop lifeDrop = myLife.doIfAlive(new Runnable() {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesPanel.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesPanel.java
index 52b3c6b..3c606ee 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesPanel.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesPanel.java
@@ -102,7 +102,7 @@
if (auxiliary != null) {
myShouldBeCalledOnDispose.add(auxiliary.getCalledOnViewDispose());
- myBrowser.setTableContextMenu(group, (auxiliary.getPopupActions() == null) ? Collections.<AnAction>emptyList() : auxiliary.getPopupActions());
+ myBrowser.setTableContextMenu(group, auxiliary.getPopupActions());
} else {
myBrowser.setTableContextMenu(group, Collections.<AnAction>emptyList());
}
@@ -252,9 +252,9 @@
for(String word: filterWords) {
final String comment = changeList.getComment();
final String committer = changeList.getCommitterName();
- if ((comment != null && comment.toLowerCase().indexOf(word) >= 0) ||
- (committer != null && committer.toLowerCase().indexOf(word) >= 0) ||
- Long.toString(changeList.getNumber()).indexOf(word) >= 0) {
+ if ((comment != null && comment.toLowerCase().contains(word)) ||
+ (committer != null && committer.toLowerCase().contains(word)) ||
+ Long.toString(changeList.getNumber()).contains(word)) {
return true;
}
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/update/RestoreUpdateTree.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/update/RestoreUpdateTree.java
index 24c9a29..8ce0067 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/update/RestoreUpdateTree.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/update/RestoreUpdateTree.java
@@ -23,6 +23,7 @@
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.RoamingTypeDisabled;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.changes.committed.CommittedChangesCache;
@@ -31,7 +32,7 @@
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-public class RestoreUpdateTree implements ProjectComponent, JDOMExternalizable {
+public class RestoreUpdateTree implements ProjectComponent, JDOMExternalizable, RoamingTypeDisabled {
private final Project myProject;
private UpdateInfo myUpdateInfo;
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java
index b2485bf..48abf0f 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java
@@ -20,6 +20,7 @@
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.execution.ui.RunnerLayoutUi;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
@@ -131,6 +132,8 @@
boolean areBreakpointsMuted();
+ void addSessionListener(@NotNull XDebugSessionListener listener, @NotNull Disposable parentDisposable);
+
void addSessionListener(@NotNull XDebugSessionListener listener);
void removeSessionListener(@NotNull XDebugSessionListener listener);
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerUtil.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerUtil.java
index 1a52c2be..80b3e76 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerUtil.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerUtil.java
@@ -31,6 +31,7 @@
import org.jetbrains.annotations.Nullable;
import java.util.Comparator;
+import java.util.List;
/**
* @author nik
@@ -50,6 +51,7 @@
@NotNull VirtualFile file,
int line,
boolean temporary);
+
public abstract boolean canPutBreakpointAt(@NotNull Project project, @NotNull VirtualFile file, int line);
public <P extends XBreakpointProperties> void toggleLineBreakpoint(@NotNull Project project, @NotNull XLineBreakpointType<P> type,
@@ -87,6 +89,8 @@
public abstract <B extends XLineBreakpoint<?>> XBreakpointGroupingRule<B, ?> getGroupingByFileRule();
+ public abstract <B extends XLineBreakpoint<?>> List<XBreakpointGroupingRule<B, ?>> getGroupingByFileRuleAsList();
+
public abstract <B extends XBreakpoint<?>> Comparator<B> getDefaultBreakpointComparator(XBreakpointType<B, ?> type);
public abstract <P extends XBreakpointProperties> Comparator<XLineBreakpoint<P>> getDefaultLineBreakpointComparator();
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpoint.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpoint.java
index c02f3a3..bc6dca2 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpoint.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpoint.java
@@ -16,9 +16,9 @@
package com.intellij.xdebugger.breakpoints;
-import com.intellij.xdebugger.XSourcePosition;
-import com.intellij.pom.Navigatable;
import com.intellij.openapi.util.UserDataHolder;
+import com.intellij.pom.Navigatable;
+import com.intellij.xdebugger.XSourcePosition;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointAdapter.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointAdapter.java
index 9702b5f..ecdb658 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointAdapter.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointAdapter.java
@@ -21,13 +21,16 @@
/**
* @author nik
*/
-public abstract class XBreakpointAdapter<B extends XBreakpoint<?>> implements XBreakpointListener<B>{
+public abstract class XBreakpointAdapter<B extends XBreakpoint<?>> implements XBreakpointListener<B> {
+ @Override
public void breakpointAdded(@NotNull final B breakpoint) {
}
+ @Override
public void breakpointRemoved(@NotNull final B breakpoint) {
}
+ @Override
public void breakpointChanged(@NotNull final B breakpoint) {
}
}
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointListener.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointListener.java
index 9669402..83aa189 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointListener.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointListener.java
@@ -24,7 +24,6 @@
* @author nik
*/
public interface XBreakpointListener<B extends XBreakpoint<?>> extends EventListener {
-
void breakpointAdded(@NotNull B breakpoint);
void breakpointRemoved(@NotNull B breakpoint);
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointType.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointType.java
index 574b6a6..978e840 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointType.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointType.java
@@ -50,25 +50,14 @@
public static final ExtensionPointName<XBreakpointType> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.xdebugger.breakpointType");
private final @NonNls @NotNull String myId;
private final @Nls @NotNull String myTitle;
- private final boolean mySuspendThreadSupported;
/**
* @param id an unique id of breakpoint type
* @param title title of tab in the breakpoints dialog
*/
protected XBreakpointType(@NonNls @NotNull final String id, @Nls @NotNull final String title) {
- this(id, title, false);
- }
-
- /**
- * @param id an unique id of breakpoint type
- * @param title title of tab in the breakpoints dialog
- * @param suspendThreadSupported <code>true</code> if suspending only one thread is supported for this type of breakpoints
- */
- protected XBreakpointType(@NonNls @NotNull final String id, @Nls @NotNull final String title, boolean suspendThreadSupported) {
myId = id;
myTitle = title;
- mySuspendThreadSupported = suspendThreadSupported;
}
@Nullable
@@ -76,8 +65,11 @@
return null;
}
- public final boolean isSuspendThreadSupported() {
- return mySuspendThreadSupported;
+ /**
+ * @return {@code true} if suspending only one thread is supported
+ */
+ public boolean isSuspendThreadSupported() {
+ return false;
}
@NotNull
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java
index 48fdb82..a6b07b3 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java
@@ -50,17 +50,10 @@
}
/**
- * @deprecated implement {@link #canPutAt(com.intellij.openapi.vfs.VirtualFile, int, com.intellij.openapi.project.Project)} instead
- */
- public boolean canPutAt(@NotNull VirtualFile file, int line) {
- return false;
- }
-
- /**
* Return <code>true<code> if breakpoint can be put on <code>line</code> in <code>file</code>
*/
public boolean canPutAt(@NotNull VirtualFile file, int line, @NotNull Project project) {
- return canPutAt(file, line);
+ return false;
}
/**
@@ -70,6 +63,7 @@
@Nullable
public abstract P createBreakpointProperties(@NotNull VirtualFile file, int line);
+ @Override
public String getDisplayText(final XLineBreakpoint<P> breakpoint) {
return fileLineDisplayText(breakpoint.getPresentableFilePath(), breakpoint.getLine());
}
@@ -78,11 +72,6 @@
return XDebuggerBundle.message("xbreakpoint.default.display.text", line + 1, path);
}
- //@NotNull
- //public Comparator<XLineBreakpoint<P>> getBreakpointComparator() {
- // return XDebuggerUtil.getInstance().getDefaultLineBreakpointComparator();
- //}
-
/**
* Source position for line breakpoint is determined by its file and line
*/
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointTypeBase.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointTypeBase.java
new file mode 100644
index 0000000..adbc7b2
--- /dev/null
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointTypeBase.java
@@ -0,0 +1,31 @@
+package com.intellij.xdebugger.breakpoints;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class XLineBreakpointTypeBase extends XLineBreakpointType<XBreakpointProperties> {
+ private final XDebuggerEditorsProvider myEditorsProvider;
+
+ protected XLineBreakpointTypeBase(@NonNls @NotNull final String id, @Nls @NotNull final String title, @Nullable XDebuggerEditorsProvider editorsProvider) {
+ super(id, title);
+
+ myEditorsProvider = editorsProvider;
+ }
+
+ @Nullable
+ @Override
+ public XDebuggerEditorsProvider getEditorsProvider(@NotNull XLineBreakpoint<XBreakpointProperties> breakpoint, @NotNull Project project) {
+ return myEditorsProvider;
+ }
+
+ @Override
+ @Nullable
+ public XBreakpointProperties createBreakpointProperties(@NotNull final VirtualFile file, final int line) {
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEditorsProviderBase.java b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEditorsProviderBase.java
new file mode 100644
index 0000000..bedb6213
--- /dev/null
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEditorsProviderBase.java
@@ -0,0 +1,66 @@
+package com.intellij.xdebugger.evaluation;
+
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.xdebugger.XSourcePosition;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class XDebuggerEditorsProviderBase extends XDebuggerEditorsProvider {
+ @NotNull
+ @Override
+ public final Document createDocument(@NotNull Project project, @NotNull String text, @Nullable XSourcePosition sourcePosition, @NotNull EvaluationMode mode) {
+ PsiElement context = null;
+ if (sourcePosition != null) {
+ context = getContextElement(sourcePosition.getFile(), sourcePosition.getOffset(), project);
+ }
+
+ PsiFile codeFragment = createExpressionCodeFragment(project, text, context, true);
+ Document document = PsiDocumentManager.getInstance(project).getDocument(codeFragment);
+ assert document != null;
+ return document;
+ }
+
+ protected abstract PsiFile createExpressionCodeFragment(@NotNull Project project, @NotNull String text, @Nullable PsiElement context, boolean isPhysical);
+
+ protected PsiElement getContextElement(@NotNull VirtualFile virtualFile, int offset, @NotNull Project project) {
+ return doGetContextElement(virtualFile, offset, project);
+ }
+
+ public static PsiElement doGetContextElement(@NotNull VirtualFile virtualFile, int offset, @NotNull Project project) {
+ Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
+ PsiFile file = PsiManager.getInstance(project).findFile(virtualFile);
+ if (file == null || document == null) {
+ return null;
+ }
+
+ if (offset < 0) {
+ offset = 0;
+ }
+ if (offset > document.getTextLength()) {
+ offset = document.getTextLength();
+ }
+ int startOffset = offset;
+
+ int lineEndOffset = document.getLineEndOffset(document.getLineNumber(offset));
+ PsiElement result = null;
+ do {
+ PsiElement element = file.findElementAt(offset);
+ if (!(element instanceof PsiWhiteSpace) && !(element instanceof PsiComment)) {
+ result = element;
+ break;
+ }
+
+ offset = element.getTextRange().getEndOffset() + 1;
+ }
+ while (offset < lineEndOffset);
+
+ if (result == null) {
+ result = file.findElementAt(startOffset);
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
index 659f49d..ffbd3d4 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
@@ -32,6 +32,7 @@
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationGroup;
import com.intellij.notification.NotificationListener;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
@@ -387,6 +388,11 @@
}
@Override
+ public void addSessionListener(@NotNull XDebugSessionListener listener, @NotNull Disposable parentDisposable) {
+ myDispatcher.addListener(listener, parentDisposable);
+ }
+
+ @Override
public void addSessionListener(@NotNull final XDebugSessionListener listener) {
myDispatcher.addListener(listener);
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java
index 3e1f8c7..026380c 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java
@@ -56,6 +56,7 @@
private XLineBreakpointType<?>[] myLineBreakpointTypes;
private Map<Class<? extends XBreakpointType>, XBreakpointType<?,?>> myBreakpointTypeByClass;
+ @Override
public XLineBreakpointType<?>[] getLineBreakpointTypes() {
if (myLineBreakpointTypes == null) {
XBreakpointType[] types = XBreakpointUtil.getBreakpointTypes();
@@ -70,6 +71,7 @@
return myLineBreakpointTypes;
}
+ @Override
public void toggleLineBreakpoint(@NotNull final Project project, @NotNull final VirtualFile file, final int line, boolean temporary) {
for (XLineBreakpointType<?> type : getLineBreakpointTypes()) {
if (type.canPutAt(file, line, project)) {
@@ -89,12 +91,14 @@
return false;
}
+ @Override
public <P extends XBreakpointProperties> void toggleLineBreakpoint(@NotNull final Project project,
@NotNull final XLineBreakpointType<P> type,
@NotNull final VirtualFile file,
final int line,
final boolean temporary) {
new WriteAction() {
+ @Override
protected void run(final Result result) {
XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager();
XLineBreakpoint<P> breakpoint = breakpointManager.findBreakpointAtLine(type, file, line);
@@ -109,14 +113,17 @@
}.execute();
}
+ @Override
public void removeBreakpoint(final Project project, final XBreakpoint<?> breakpoint) {
new WriteAction() {
+ @Override
protected void run(final Result result) {
XDebuggerManager.getInstance(project).getBreakpointManager().removeBreakpoint(breakpoint);
}
}.execute();
}
+ @Override
public <B extends XBreakpoint<?>> XBreakpointType<B, ?> findBreakpointType(@NotNull Class<? extends XBreakpointType<B, ?>> typeClass) {
if (myBreakpointTypeByClass == null) {
myBreakpointTypeByClass = new HashMap<Class<? extends XBreakpointType>, XBreakpointType<?,?>>();
@@ -129,6 +136,7 @@
return (XBreakpointType<B, ?>)type;
}
+ @Override
public <T extends XDebuggerSettings<?>> T getDebuggerSettings(Class<T> aClass) {
return XDebuggerSettingsManager.getInstance().getSettings(aClass);
}
@@ -138,16 +146,19 @@
return XDebuggerTreeActionBase.getSelectedValue(dataContext);
}
+ @Override
@Nullable
public XSourcePosition createPosition(@NotNull final VirtualFile file, final int line) {
return XSourcePositionImpl.create(file, line);
}
- @Nullable
+ @Override
+ @Nullable
public XSourcePosition createPositionByOffset(@NotNull final VirtualFile file, final int offset) {
return XSourcePositionImpl.createByOffset(file, offset);
}
+ @Override
public <B extends XLineBreakpoint<?>> XBreakpointGroupingRule<B, ?> getGroupingByFileRule() {
return new XBreakpointFileGroupingRule<B>();
}
@@ -172,16 +183,20 @@
return editor;
}
+ @Override
public <B extends XBreakpoint<?>> Comparator<B> getDefaultBreakpointComparator(final XBreakpointType<B, ?> type) {
return new Comparator<B>() {
+ @Override
public int compare(final B o1, final B o2) {
return type.getDisplayText(o1).compareTo(type.getDisplayText(o2));
}
};
}
+ @Override
public <P extends XBreakpointProperties> Comparator<XLineBreakpoint<P>> getDefaultLineBreakpointComparator() {
return new Comparator<XLineBreakpoint<P>>() {
+ @Override
public int compare(final XLineBreakpoint<P> o1, final XLineBreakpoint<P> o2) {
int fileCompare = o1.getFileUrl().compareTo(o2.getFileUrl());
if (fileCompare != 0) return fileCompare;
@@ -202,6 +217,7 @@
return null;
}
+ @Override
public void iterateLine(@NotNull Project project, @NotNull Document document, int line, @NotNull Processor<PsiElement> processor) {
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
if (file == null) return;
@@ -235,4 +251,9 @@
}
}
}
+
+ @Override
+ public <B extends XLineBreakpoint<?>> List<XBreakpointGroupingRule<B, ?>> getGroupingByFileRuleAsList() {
+ return Collections.<XBreakpointGroupingRule<B, ?>>singletonList(this.<B>getGroupingByFileRule());
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EditBreakpointActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EditBreakpointActionHandler.java
index 5a53748..1e30a9c 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EditBreakpointActionHandler.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EditBreakpointActionHandler.java
@@ -16,8 +16,8 @@
package com.intellij.xdebugger.impl.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
@@ -39,7 +39,7 @@
@Override
public void perform(@NotNull Project project, AnActionEvent event) {
DataContext dataContext = event.getDataContext();
- Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
+ Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
if (editor == null) return;
final Pair<GutterIconRenderer,Object> pair = XBreakpointUtil.findSelectedBreakpoint(project, editor);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerEditBreakpointActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerEditBreakpointActionHandler.java
index 92eb909..3ac17a4 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerEditBreakpointActionHandler.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerEditBreakpointActionHandler.java
@@ -16,8 +16,8 @@
package com.intellij.xdebugger.impl.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.project.Project;
@@ -31,13 +31,6 @@
import javax.swing.*;
import java.awt.*;
-/**
- * Created with IntelliJ IDEA.
- * User: zajac
- * Date: 04.05.12
- * Time: 4:07
- * To change this template use File | Settings | File Templates.
- */
public class XDebuggerEditBreakpointActionHandler extends EditBreakpointActionHandler {
@Override
protected void doShowPopup(Project project, JComponent component, Point whereToShow, Object breakpoint) {
@@ -47,7 +40,7 @@
@Override
public boolean isEnabled(@NotNull Project project, AnActionEvent event) {
DataContext dataContext = event.getDataContext();
- Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
+ Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
if (editor == null) return false;
final Pair<GutterIconRenderer,Object> pair = XBreakpointUtil.findSelectedBreakpoint(project, editor);
return pair.first != null && pair.second instanceof XLineBreakpointImpl;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java
index 65bfc25..76be112 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java
@@ -33,6 +33,7 @@
class XBreakpointItem extends BreakpointItem {
private final XBreakpoint<?> myBreakpoint;
+ private XLightBreakpointPropertiesPanel<XBreakpoint<?>> myPropertiesPanel;
public XBreakpointItem(XBreakpoint<?> breakpoint) {
myBreakpoint = breakpoint;
@@ -75,13 +76,21 @@
return ((XBreakpointBase)myBreakpoint).getType().getDisplayText(myBreakpoint);
}
+ @Override
+ public void saveState() {
+ if (myPropertiesPanel != null) {
+ myPropertiesPanel.saveProperties();
+ }
+ }
+
public void doUpdateDetailView(DetailView panel, boolean editorOnly) {
Project project = ((XBreakpointBase)myBreakpoint).getProject();
- XLightBreakpointPropertiesPanel<XBreakpoint<?>> propertiesPanel = null;
+ saveState();
+ myPropertiesPanel = null;
if (!editorOnly) {
- propertiesPanel = new XLightBreakpointPropertiesPanel<XBreakpoint<?>>(project, getManager(), myBreakpoint, true);
+ myPropertiesPanel = new XLightBreakpointPropertiesPanel<XBreakpoint<?>>(project, getManager(), myBreakpoint, true);
- panel.setPropertiesPanel(propertiesPanel.getMainPanel());
+ panel.setPropertiesPanel(myPropertiesPanel.getMainPanel());
}
XSourcePosition sourcePosition = myBreakpoint.getSourcePosition();
@@ -92,10 +101,10 @@
panel.clearEditor();
}
- if (propertiesPanel != null) {
- propertiesPanel.setDetailView(panel);
- propertiesPanel.loadProperties();
- propertiesPanel.getMainPanel().revalidate();
+ if (myPropertiesPanel != null) {
+ myPropertiesPanel.setDetailView(panel);
+ myPropertiesPanel.loadProperties();
+ myPropertiesPanel.getMainPanel().revalidate();
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointChooser.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointChooser.java
index 1188613..563c614 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointChooser.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointChooser.java
@@ -126,7 +126,7 @@
if (selected) {
if (hackedSelection.get() != value) {
hackedSelection.set(value);
- myDetailController.selectionChanged();
+ myDetailController.updateDetailView();
}
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointItem.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointItem.java
index 26439a7..f515bb6 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointItem.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointItem.java
@@ -39,6 +39,8 @@
public abstract class BreakpointItem extends ItemWrapper implements Comparable<BreakpointItem>, Navigatable {
public static final Key<Object> EDITOR_ONLY = Key.create("EditorOnly");
+ public abstract void saveState();
+
public abstract Object getBreakpoint();
public abstract boolean isEnabled();
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointNoneItem.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointNoneItem.java
index 9c983c4..10b7d48 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointNoneItem.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointNoneItem.java
@@ -25,6 +25,11 @@
public class BreakpointNoneItem extends BreakpointItem {
@Override
+ public void saveState() {
+
+ }
+
+ @Override
public Object getBreakpoint() {
return null;
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialog.java
index a662cb4..6af4750 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialog.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialog.java
@@ -36,6 +36,7 @@
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
import com.intellij.xdebugger.impl.breakpoints.XBreakpointManagerImpl;
import com.intellij.xdebugger.impl.breakpoints.XBreakpointsDialogState;
+import com.intellij.xdebugger.impl.breakpoints.ui.tree.BreakpointItemNode;
import com.intellij.xdebugger.impl.breakpoints.ui.tree.BreakpointItemsTreeController;
import com.intellij.xdebugger.impl.breakpoints.ui.tree.BreakpointsCheckboxTree;
import org.jetbrains.annotations.NotNull;
@@ -198,7 +199,30 @@
}
private JComponent createMasterView() {
- myTreeController = new BreakpointItemsTreeController(myRulesEnabled);
+ myTreeController = new BreakpointItemsTreeController(myRulesEnabled) {
+ @Override
+ public void nodeStateWillChangeImpl(CheckedTreeNode node) {
+ if (node instanceof BreakpointItemNode) {
+ ((BreakpointItemNode)node).getBreakpointItem().saveState();
+ }
+ super.nodeStateWillChangeImpl(node);
+ }
+
+ @Override
+ public void nodeStateDidChangeImpl(CheckedTreeNode node) {
+ super.nodeStateDidChangeImpl(node);
+ if (node instanceof BreakpointItemNode) {
+ myDetailController.doUpdateDetailView(true);
+ }
+ }
+
+ @Override
+ protected void selectionChangedImpl() {
+ super.selectionChangedImpl();
+ saveCurrentItem();
+ myDetailController.updateDetailView();
+ }
+ };
JTree tree = new BreakpointsCheckboxTree(myProject, myTreeController);
new AnAction("BreakpointDialog.GoToSource") {
@@ -216,16 +240,6 @@
}
}.registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE).getShortcutSet(), tree);
- tree.addMouseListener(new MouseAdapter() {
- @Override
- public void mouseClicked(MouseEvent event) {
- if (event.getClickCount() == 2 && UIUtil.isActionClick(event, MouseEvent.MOUSE_CLICKED) && !UIUtil.isSelectionButtonDown(event) && !event.isConsumed()) {
- navigate();
- close(OK_EXIT_CODE);
- }
- }
- });
-
final DefaultActionGroup breakpointTypes = new DefaultActionGroup();
for (BreakpointPanelProvider provider : myBreakpointsPanelProviders) {
breakpointTypes.addAll(provider.getAddBreakpointActions(myProject));
@@ -268,8 +282,6 @@
JPanel decoratedTree = decorator.createPanel();
myTreeController.setTreeView(tree);
- myDetailController.setTree(tree);
-
myTreeController.buildTree(myBreakpointItems);
initSelection(myBreakpointItems);
@@ -344,8 +356,16 @@
@Override
protected void dispose() {
+ saveCurrentItem();
Disposer.dispose(myListenerDisposable);
saveBreakpointsDialogState();
super.dispose();
}
+
+ private void saveCurrentItem() {
+ ItemWrapper item = myDetailController.getSelectedItem();
+ if (item instanceof BreakpointItem) {
+ ((BreakpointItem)item).saveState();
+ }
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointPropertiesSubPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointPropertiesSubPanel.java
index 3ff9a41..4e53202d 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointPropertiesSubPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointPropertiesSubPanel.java
@@ -22,15 +22,7 @@
import com.intellij.xdebugger.breakpoints.XBreakpointType;
import org.jetbrains.annotations.NotNull;
-/**
- * Created by IntelliJ IDEA.
- * User: zajac
- * Date: 16.06.11
- * Time: 19:21
- * To change this template use File | Settings | File Templates.
- */
public abstract class XBreakpointPropertiesSubPanel<B extends XBreakpoint<?>> {
-
protected Project myProject;
protected XBreakpointManager myBreakpointManager;
protected B myBreakpoint;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointsTree.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointsTree.java
deleted file mode 100644
index 8610438..0000000
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointsTree.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.xdebugger.impl.breakpoints.ui;
-
-import com.intellij.ide.util.treeView.TreeState;
-import com.intellij.openapi.ui.DialogWrapper;
-import com.intellij.openapi.util.MultiValuesMap;
-import com.intellij.pom.Navigatable;
-import com.intellij.ui.CheckboxTree;
-import com.intellij.ui.CheckedTreeNode;
-import com.intellij.ui.SimpleTextAttributes;
-import com.intellij.util.ui.tree.TreeUtil;
-import com.intellij.xdebugger.breakpoints.XBreakpoint;
-import com.intellij.xdebugger.breakpoints.XBreakpointManager;
-import com.intellij.xdebugger.breakpoints.XBreakpointType;
-import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup;
-import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
-import com.intellij.xdebugger.impl.breakpoints.XBreakpointUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import javax.swing.tree.DefaultTreeModel;
-import javax.swing.tree.TreeNode;
-import javax.swing.tree.TreePath;
-import java.util.*;
-
-/**
- * @author nik
- */
-public class XBreakpointsTree<B extends XBreakpoint<?>> extends CheckboxTree {
- private final TreeNodeComparator myComparator;
- private final CheckedTreeNode myRoot;
- private DialogWrapper myParentDialog;
- private final Map<B, BreakpointNode<B>> myNodes = new HashMap<B, BreakpointNode<B>>();
- private List<XBreakpointGroupingRule<B, ?>> myGroupingRules;
- private final Map<XBreakpointGroup, BreakpointsGroupNode> myGroupNodes = new HashMap<XBreakpointGroup, BreakpointsGroupNode>();
- private final MultiValuesMap<XBreakpointGroupingRule<B, ?>, XBreakpointGroup> myGroups = new MultiValuesMap<XBreakpointGroupingRule<B,?>, XBreakpointGroup>();
-
- private XBreakpointsTree(final XBreakpointType<B, ?> type, final CheckedTreeNode root,
- Collection<XBreakpointGroupingRule<B, ?>> groupingRules,
- DialogWrapper parentDialog,
- XBreakpointManager breakpointManager) {
- super(new BreakpointsTreeCellRenderer(), root);
- myRoot = root;
- myParentDialog = parentDialog;
- myComparator = new TreeNodeComparator<B>(type, breakpointManager);
- setGroupingRulesInternal(groupingRules);
-
- getEmptyText().setText("No " + type.getTitle());
- }
-
- private void setGroupingRulesInternal(final Collection<XBreakpointGroupingRule<B, ?>> groupingRules) {
- myGroupingRules = new ArrayList<XBreakpointGroupingRule<B,?>>(groupingRules);
- setShowsRootHandles(!groupingRules.isEmpty());
- }
-
- public static <B extends XBreakpoint<?>> XBreakpointsTree<B> createTree(final XBreakpointType<B, ?> type,
- final Collection<XBreakpointGroupingRule<B, ?>> groupingRules,
- DialogWrapper parentDialog, XBreakpointManager breakpointManager) {
- return new XBreakpointsTree<B>(type, new CheckedTreeNode("root"), groupingRules, parentDialog, breakpointManager);
- }
-
- public void buildTree(@NotNull Collection<? extends B> breakpoints) {
- final TreeState state = TreeState.createOn(this, myRoot);
- myRoot.removeAllChildren();
- myNodes.clear();
- myGroupNodes.clear();
- myGroups.clear();
- for (B breakpoint : breakpoints) {
- BreakpointNode<B> node = new BreakpointNode<B>(breakpoint);
- CheckedTreeNode parent = getParentNode(breakpoint);
- parent.add(node);
- myNodes.put(breakpoint, node);
- }
- TreeUtil.sort(myRoot, myComparator);
- ((DefaultTreeModel)getModel()).nodeStructureChanged(myRoot);
- expandPath(new TreePath(myRoot));
- state.applyTo(this, myRoot);
- }
-
-
- @NotNull
- private CheckedTreeNode getParentNode(final B breakpoint) {
- CheckedTreeNode parent = myRoot;
- for (int i = 0; i < myGroupingRules.size(); i++) {
- XBreakpointGroup group = getGroup(breakpoint, myGroupingRules.get(i));
- if (group != null) {
- parent = getOrCreateGroupNode(parent, group, i);
- }
- }
- return parent;
- }
-
- private <G extends XBreakpointGroup> BreakpointsGroupNode<G> getOrCreateGroupNode(CheckedTreeNode parent, final G group,
- final int level) {
- //noinspection unchecked
- BreakpointsGroupNode<G> groupNode = (BreakpointsGroupNode<G>)myGroupNodes.get(group);
- if (groupNode == null) {
- groupNode = new BreakpointsGroupNode<G>(group, level);
- myGroupNodes.put(group, groupNode);
- parent.add(groupNode);
- }
- return groupNode;
- }
-
- @Override
- protected void onDoubleClick(CheckedTreeNode node) {
- if (node instanceof BreakpointNode<?>) {
- final Navigatable navigatable = ((BreakpointNode)node).getBreakpoint().getNavigatable();
- if (navigatable != null) {
- navigatable.navigate(true);
- myParentDialog.close(DialogWrapper.OK_EXIT_CODE);
- }
- }
- }
-
- @Nullable
- private <G extends XBreakpointGroup> XBreakpointGroup getGroup(final B breakpoint, final XBreakpointGroupingRule<B, G> groupingRule) {
- //noinspection unchecked
- Collection<G> groups = (Collection<G>)myGroups.get(groupingRule);
- if (groups == null) {
- groups = Collections.emptyList();
- }
- G group = groupingRule.getGroup(breakpoint, groups);
- if (group != null) {
- myGroups.put(groupingRule, group);
- }
- return group;
- }
-
- @Override
- protected void onNodeStateChanged(final CheckedTreeNode node) {
- if (node instanceof BreakpointNode) {
- ((BreakpointNode)node).getBreakpoint().setEnabled(node.isChecked());
- }
- }
-
- public void setGroupingRules(List<XBreakpointGroupingRule<B, ?>> groupingRules) {
- List<B> selectedBreakpoints = getSelectedBreakpoints();
- List<B> allBreakpoints = new ArrayList<B>(myNodes.keySet());
-
- setGroupingRulesInternal(groupingRules);
- buildTree(allBreakpoints);
-
- if (selectedBreakpoints.size() > 0) {
- selectBreakpoint(selectedBreakpoints.get(0));
- }
- }
-
- public List<B> getSelectedBreakpoints() {
- final ArrayList<B> list = new ArrayList<B>();
- TreePath[] selectionPaths = getSelectionPaths();
- if (selectionPaths == null || selectionPaths.length == 0) return list;
-
- for (TreePath selectionPath : selectionPaths) {
- TreeUtil.traverseDepth((TreeNode)selectionPath.getLastPathComponent(), new TreeUtil.Traverse() {
- public boolean accept(final Object node) {
- if (node instanceof BreakpointNode) {
- //noinspection unchecked
- list.add(((BreakpointNode<B>)node).getBreakpoint());
- }
- return true;
- }
- });
- }
-
- return list;
- }
-
- public void selectBreakpoint(final B breakpoint) {
- BreakpointNode<B> node = myNodes.get(breakpoint);
- if (node != null) {
- TreeUtil.selectNode(this, node);
- }
- }
-
- private static class BreakpointsTreeCellRenderer extends CheckboxTreeCellRenderer {
- @Override
- public void customizeRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
- if (value instanceof BreakpointNode) {
- BreakpointNode node = (BreakpointNode)value;
- XBreakpoint breakpoint = node.getBreakpoint();
- String text = XBreakpointUtil.getDisplayText(breakpoint);
- getTextRenderer().setIcon(node.getIcon());
- getTextRenderer().append(text, node.getTextAttributes());
- }
- else if (value instanceof BreakpointsGroupNode) {
- XBreakpointGroup group = ((BreakpointsGroupNode)value).getGroup();
- getTextRenderer().setIcon(group.getIcon(expanded));
- getTextRenderer().append(group.getName(), SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES);
- }
- }
- }
-
- private static class BreakpointsGroupNode<G extends XBreakpointGroup> extends CheckedTreeNode {
- private final G myGroup;
- private final int myLevel;
-
- private BreakpointsGroupNode(G group, int level) {
- super(group);
- myLevel = level;
- setChecked(false);
- myGroup = group;
- }
-
- public G getGroup() {
- return myGroup;
- }
-
- public int getLevel() {
- return myLevel;
- }
- }
-
- private static class BreakpointNode<B extends XBreakpoint<?>> extends CheckedTreeNode {
- private final B myBreakpoint;
-
- private BreakpointNode(final B breakpoint) {
- super(breakpoint);
- myBreakpoint = breakpoint;
- setChecked(breakpoint.isEnabled());
- }
-
- public B getBreakpoint() {
- return myBreakpoint;
- }
-
- public Icon getIcon() {
- XBreakpointType type = myBreakpoint.getType();
- return isChecked() ? type.getEnabledIcon() : type.getDisabledIcon();
- }
-
- public SimpleTextAttributes getTextAttributes() {
- return isChecked() ? SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES : SimpleTextAttributes.GRAYED_ATTRIBUTES;
- }
- }
-
- private static class TreeNodeComparator<B extends XBreakpoint<?>> implements Comparator<TreeNode> {
- private final Comparator<B> myBreakpointComparator;
- private final XBreakpointManager myBreakpointManager;
-
- public TreeNodeComparator(final XBreakpointType<B, ?> type, XBreakpointManager breakpointManager) {
- myBreakpointManager = breakpointManager;
- myBreakpointComparator = type.getBreakpointComparator();
- }
-
- public int compare(final TreeNode o1, final TreeNode o2) {
- if (o1 instanceof BreakpointNode && o2 instanceof BreakpointNode) {
- //noinspection unchecked
- B b1 = (B)((BreakpointNode)o1).getBreakpoint();
- //noinspection unchecked
- B b2 = (B)((BreakpointNode)o2).getBreakpoint();
- boolean default1 = myBreakpointManager.isDefaultBreakpoint(b1);
- boolean default2 = myBreakpointManager.isDefaultBreakpoint(b2);
- if (default1 && !default2) return -1;
- if (!default1 && default2) return 1;
- return myBreakpointComparator.compare(b1, b2);
- }
- if (o1 instanceof BreakpointsGroupNode && o2 instanceof BreakpointsGroupNode) {
- final BreakpointsGroupNode group1 = (BreakpointsGroupNode)o1;
- final BreakpointsGroupNode group2 = (BreakpointsGroupNode)o2;
- if (group1.getLevel() != group2.getLevel()) {
- return group1.getLevel() - group2.getLevel();
- }
- return group1.getGroup().compareTo(group2.getGroup());
- }
- return o1 instanceof BreakpointsGroupNode ? -1 : 1;
- }
- }
-
-}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.form b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.form
index a15e28b..ff5430f 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.form
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.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="com.intellij.xdebugger.impl.breakpoints.ui.XLightBreakpointPropertiesPanel">
- <grid id="27dc6" binding="myMainPanel" custom-create="true" layout-manager="GridLayoutManager" row-count="9" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="9" 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="453"/>
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
index 6be7cd0..d382829 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
@@ -38,7 +38,6 @@
import java.util.List;
public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implements XSuspendPolicyPanel.Delegate {
-
public boolean showMoreOptions() {
return myShowMoreOptions;
}
@@ -54,16 +53,6 @@
}
}
- private void createUIComponents() {
- myMainPanel = new JPanel() {
- @Override
- public void removeNotify() {
- super.removeNotify();
- saveProperties();
- }
- };
- }
-
public interface Delegate {
void showMoreOptions();
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.form b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.form
index 356145a..4c9a695 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.form
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.form
@@ -1,84 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.xdebugger.impl.breakpoints.ui.XSuspendPolicyPanel">
- <grid id="27dc6" binding="myContentPane" 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="myContentPane" layout-manager="GridLayoutManager" row-count="1" column-count="5" 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="537" height="59"/>
+ <xy x="20" y="20" width="537" height="57"/>
</constraints>
<properties/>
- <border type="none"/>
+ <border type="etched" title-resource-bundle="messages/XDebuggerBundle" title-key="suspend.policy.panel.title"/>
<children>
- <grid id="e69ea" binding="mySuspendPolicyPanel" layout-manager="CardLayout" hgap="0" vgap="0">
+ <hspacer id="d9eab">
<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"/>
+ <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
- <properties/>
- <clientProperties>
- <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
- </clientProperties>
- <border type="etched" title-resource-bundle="messages/XDebuggerBundle" title-key="xbreakpoints.suspend.group.title"/>
- <children>
- <grid id="190d5" 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>
- <card name="checkbox"/>
- </constraints>
- <properties/>
- <border type="none"/>
- <children>
- <component id="ac150" class="javax.swing.JCheckBox" binding="mySuspendCheckBox" default-binding="true">
- <constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <selected value="true"/>
- <text resource-bundle="messages/XDebuggerBundle" key="xbreakpoints.suspend.checkbox"/>
- </properties>
- </component>
- </children>
- </grid>
- <grid id="f5e5" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
- <margin top="0" left="0" bottom="0" right="0"/>
- <constraints>
- <card name="radioButtons"/>
- </constraints>
- <properties/>
- <border type="none"/>
- <children>
- <component id="aba21" class="javax.swing.JRadioButton" binding="mySuspendAllRadioButton">
- <constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <selected value="true"/>
- <text resource-bundle="messages/XDebuggerBundle" key="xbreakpoints.suspend.all.radio"/>
- </properties>
- </component>
- <component id="91d9b" class="javax.swing.JRadioButton" binding="mySuspendThreadRadioButton">
- <constraints>
- <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text resource-bundle="messages/XDebuggerBundle" key="xbreakpoints.suspend.thread.radio"/>
- </properties>
- </component>
- <component id="fbfd7" class="javax.swing.JRadioButton" binding="mySuspendNoneRadioButton">
- <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 resource-bundle="messages/XDebuggerBundle" key="xbreakpoints.suspend.none.radio"/>
- </properties>
- </component>
- <hspacer id="d9eab">
- <constraints>
- <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- </hspacer>
- </children>
- </grid>
- </children>
- </grid>
+ </hspacer>
+ <component id="aba21" class="javax.swing.JRadioButton" binding="mySuspendAll">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <selected value="true"/>
+ <text resource-bundle="messages/XDebuggerBundle" key="suspend.policy.panel.all"/>
+ </properties>
+ </component>
+ <component id="91d9b" class="javax.swing.JRadioButton" binding="mySuspendThread">
+ <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 resource-bundle="messages/XDebuggerBundle" key="suspend.policy.panel.thread"/>
+ </properties>
+ </component>
+ <component id="ac150" class="javax.swing.JCheckBox" binding="mySuspendCheckBox" default-binding="true">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <selected value="true"/>
+ <text resource-bundle="messages/XDebuggerBundle" key="suspend.policy.panel.suspend"/>
+ </properties>
+ </component>
+ <component id="ac069" class="javax.swing.JButton" binding="myMakeDefaultButton" default-binding="true">
+ <constraints>
+ <grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/XDebuggerBundle" key="suspend.policy.panel.makeDefault"/>
+ </properties>
+ </component>
</children>
</grid>
</form>
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java
index a7bf087..c46914f 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java
@@ -15,36 +15,29 @@
*/
package com.intellij.xdebugger.impl.breakpoints.ui;
+import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.breakpoints.SuspendPolicy;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.XBreakpointManager;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.HashMap;
-import java.util.Map;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
-/**
- * Created by IntelliJ IDEA.
- * User: zajac
- * Date: 16.06.11
- * Time: 17:40
- * To change this template use File | Settings | File Templates.
- */
public class XSuspendPolicyPanel<B extends XBreakpoint<?>> extends XBreakpointPropertiesSubPanel<B> {
-
- private JPanel mySuspendPolicyPanel;
private JCheckBox mySuspendCheckBox;
- private JRadioButton mySuspendAllRadioButton;
- private JRadioButton mySuspendThreadRadioButton;
- private JRadioButton mySuspendNoneRadioButton;
+ private JRadioButton mySuspendAll;
+ private JRadioButton mySuspendThread;
+
private JPanel myContentPane;
- private Map<SuspendPolicy, JRadioButton> mySuspendRadioButtons;
+ private JButton myMakeDefaultButton;
+
+ private ButtonGroup mySuspendPolicyGroup;
public interface Delegate {
void showMoreOptionsIfNeeded();
@@ -52,61 +45,137 @@
private Delegate myDelegate;
+ @Override
public void init(Project project, final XBreakpointManager breakpointManager, @NotNull B breakpoint) {
super.init(project, breakpointManager, breakpoint);
- mySuspendRadioButtons = new HashMap<SuspendPolicy, JRadioButton>();
- mySuspendRadioButtons.put(SuspendPolicy.ALL, mySuspendAllRadioButton);
- mySuspendRadioButtons.put(SuspendPolicy.THREAD, mySuspendThreadRadioButton);
- mySuspendRadioButtons.put(SuspendPolicy.NONE, mySuspendNoneRadioButton);
- @NonNls String card = myBreakpointType.isSuspendThreadSupported() ? "radioButtons" : "checkbox";
- ((CardLayout)mySuspendPolicyPanel.getLayout()).show(mySuspendPolicyPanel, card);
mySuspendCheckBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
- if (myDelegate != null && !mySuspendCheckBox.isSelected()) {
+ boolean selected = mySuspendCheckBox.isSelected();
+
+ if (myBreakpoint.getType().isSuspendThreadSupported()) {
+ changeEnableState(selected);
+ }
+
+ if (myDelegate != null && !selected) {
myDelegate.showMoreOptionsIfNeeded();
}
}
});
+
+ if (!myBreakpoint.getType().isSuspendThreadSupported()) {
+ return;
+ }
+
+ mySuspendPolicyGroup = new ButtonGroup();
+ mySuspendPolicyGroup.add(mySuspendAll);
+ mySuspendPolicyGroup.add(mySuspendThread);
+
+ updateSuspendPolicyFont(createSettingsKey());
+
+ ItemListener suspendPolicyChangeListener = new ItemListener() {
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ updateMakeDefaultEnableState();
+ }
+ };
+ updateMakeDefaultEnableState();
+
+ mySuspendAll.addItemListener(suspendPolicyChangeListener);
+ mySuspendThread.addItemListener(suspendPolicyChangeListener);
+
+ myMakeDefaultButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ SuspendPolicy suspendPolicy = getSelectedSuspendPolicy();
+ String settingsKey = createSettingsKey();
+ PropertiesComponent.getInstance().setValue(settingsKey, suspendPolicy.name());
+ updateSuspendPolicyFont(settingsKey);
+ if (SuspendPolicy.THREAD == suspendPolicy) {
+ mySuspendThread.requestFocus();
+ }
+ else {
+ mySuspendAll.requestFocus();
+ }
+ myMakeDefaultButton.setEnabled(false);
+ }
+ });
+ }
+
+ private void updateMakeDefaultEnableState() {
+ myMakeDefaultButton.setEnabled(!getSelectedSuspendPolicy().name().equalsIgnoreCase(PropertiesComponent.getInstance().getValue(createSettingsKey(), SuspendPolicy.ALL.name())));
+ }
+
+ private String createSettingsKey() {
+ return "debugger.suspend.policy-" + myBreakpointType.getId();
+ }
+
+ private void updateSuspendPolicyFont(String settingsKey) {
+ String defaultPolicy = PropertiesComponent.getInstance().getValue(settingsKey, SuspendPolicy.ALL.name());
+ Font font = mySuspendAll.getFont().deriveFont(Font.PLAIN);
+ Font boldFont = font.deriveFont(Font.BOLD);
+
+ mySuspendAll.setFont(SuspendPolicy.ALL.name().equalsIgnoreCase(defaultPolicy) ? boldFont : font);
+ mySuspendThread.setFont(SuspendPolicy.THREAD.name().equalsIgnoreCase(defaultPolicy) ? boldFont : font);
+ }
+
+ private void changeEnableState(boolean selected) {
+ mySuspendAll.setEnabled(selected);
+ mySuspendThread.setEnabled(selected);
+ if (selected) {
+ updateMakeDefaultEnableState();
+ }
+ else {
+ myMakeDefaultButton.setEnabled(false);
+ }
+ }
+
+ private void changeVisibleState(boolean suspendThreadSupported) {
+ mySuspendAll.setVisible(suspendThreadSupported);
+ mySuspendThread.setVisible(suspendThreadSupported);
+ myMakeDefaultButton.setVisible(suspendThreadSupported);
}
@Override
public boolean lightVariant(boolean showAllOptions) {
- mySuspendPolicyPanel.setBorder(null);
+ myContentPane.setBorder(null);
return false;
}
@Override
void loadProperties() {
SuspendPolicy suspendPolicy = myBreakpoint.getSuspendPolicy();
- mySuspendRadioButtons.get(suspendPolicy).setSelected(true);
- final boolean selected = suspendPolicy != SuspendPolicy.NONE;
+ boolean selected = suspendPolicy != SuspendPolicy.NONE;
+ boolean suspendThreadSupported = myBreakpoint.getType().isSuspendThreadSupported();
+
+ changeVisibleState(suspendThreadSupported);
+ if (suspendThreadSupported) {
+ mySuspendPolicyGroup.setSelected(suspendPolicy == SuspendPolicy.THREAD ? mySuspendThread.getModel() : mySuspendAll.getModel(), true);
+ changeEnableState(selected);
+ }
+
mySuspendCheckBox.setSelected(selected);
- if (!selected) {
- if (myDelegate != null) {
- myDelegate.showMoreOptionsIfNeeded();
- }
+ if (!selected && myDelegate != null) {
+ myDelegate.showMoreOptionsIfNeeded();
}
}
- private SuspendPolicy getConfiguredSuspendPolicy() {
- if (!myBreakpoint.getType().isSuspendThreadSupported()) {
- return mySuspendCheckBox.isSelected() ? SuspendPolicy.ALL : SuspendPolicy.NONE;
+ private SuspendPolicy getSelectedSuspendPolicy() {
+ if (!mySuspendCheckBox.isSelected()) {
+ return SuspendPolicy.NONE;
}
-
- for (SuspendPolicy policy : mySuspendRadioButtons.keySet()) {
- if (mySuspendRadioButtons.get(policy).isSelected()) {
- return policy;
- }
+ else if (myBreakpoint.getType().isSuspendThreadSupported()) {
+ return mySuspendAll.isSelected() ? SuspendPolicy.ALL : SuspendPolicy.THREAD;
}
- return SuspendPolicy.ALL;
+ else {
+ return SuspendPolicy.ALL;
+ }
}
-
@Override
void saveProperties() {
- myBreakpoint.setSuspendPolicy(getConfiguredSuspendPolicy());
+ myBreakpoint.setSuspendPolicy(getSelectedSuspendPolicy());
}
public Delegate getDelegate() {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemNode.java
index 8cbde4d..01d9482 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemNode.java
@@ -18,7 +18,7 @@
import com.intellij.ui.CheckedTreeNode;
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointItem;
-class BreakpointItemNode extends CheckedTreeNode {
+public class BreakpointItemNode extends CheckedTreeNode {
private final BreakpointItem myBreakpoint;
BreakpointItemNode(final BreakpointItem breakpoint) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java
index 9ebdfea..babdd09 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java
@@ -27,6 +27,8 @@
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
@@ -46,6 +48,7 @@
private final MultiValuesMap<XBreakpointGroupingRule, XBreakpointGroup> myGroups = new MultiValuesMap<XBreakpointGroupingRule, XBreakpointGroup>();
private JTree myTreeView;
+ protected boolean myInBuild;
public BreakpointItemsTreeController(Collection<XBreakpointGroupingRule> groupingRules) {
myRoot = new CheckedTreeNode("root");
@@ -58,12 +61,47 @@
public void setTreeView(JTree treeView) {
myTreeView = treeView;
+ myTreeView.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
+ @Override
+ public void valueChanged(TreeSelectionEvent event) {
+ selectionChanged();
+ }
+ });
if (treeView instanceof BreakpointsCheckboxTree) {
((BreakpointsCheckboxTree)treeView).setDelegate(this);
}
myTreeView.setShowsRootHandles(!myGroupingRules.isEmpty());
}
+ protected void selectionChanged() {
+ if (myInBuild) return;
+ selectionChangedImpl();
+ }
+
+ protected void selectionChangedImpl() {
+ }
+
+ @Override
+ public void nodeStateDidChange(CheckedTreeNode node) {
+ if (myInBuild) return;
+ nodeStateDidChangeImpl(node);
+ }
+
+ protected void nodeStateDidChangeImpl(CheckedTreeNode node) {
+ if (node instanceof BreakpointItemNode) {
+ ((BreakpointItemNode)node).getBreakpointItem().setEnabled(node.isChecked());
+ }
+ }
+
+ @Override
+ public void nodeStateWillChange(CheckedTreeNode node) {
+ if (myInBuild) return;
+ nodeStateWillChangeImpl(node);
+ }
+
+ protected void nodeStateWillChangeImpl(CheckedTreeNode node) {
+ }
+
private void setGroupingRulesInternal(final Collection<XBreakpointGroupingRule> groupingRules) {
myGroupingRules = new ArrayList<XBreakpointGroupingRule>(groupingRules);
}
@@ -81,9 +119,11 @@
myNodes.put(breakpoint, node);
}
TreeUtil.sort(myRoot, myComparator);
+ myInBuild = true;
((DefaultTreeModel)(myTreeView.getModel())).nodeStructureChanged(myRoot);
state.applyTo(myTreeView, myRoot);
TreeUtil.expandAll(myTreeView);
+ myInBuild = false;
}
@@ -140,25 +180,15 @@
return groupNode;
}
- @Override
- public void nodeStateChanged(CheckedTreeNode node) {
- if (node instanceof BreakpointItemNode) {
- ((BreakpointItemNode)node).getBreakpointItem().setEnabled(node.isChecked());
- }
- }
-
public void setGroupingRules(Collection<XBreakpointGroupingRule> groupingRules) {
setGroupingRulesInternal(groupingRules);
rebuildTree(new ArrayList<BreakpointItem>(myNodes.keySet()));
}
public void rebuildTree(Collection<BreakpointItem> items) {
- List<BreakpointItem> selectedBreakpoints = getSelectedBreakpoints();
TreePath path = myTreeView.getSelectionPath();
buildTree(items);
- if (selectedBreakpoints.size() > 0) {
- selectBreakpointItem(selectedBreakpoints.get(0), path);
- }
+ selectBreakpointItem(null, path);
}
public List<BreakpointItem> getSelectedBreakpoints() {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointsCheckboxTree.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointsCheckboxTree.java
index 7c113f5..c74e92d 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointsCheckboxTree.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointsCheckboxTree.java
@@ -21,17 +21,26 @@
public class BreakpointsCheckboxTree extends CheckboxTree {
+ @Override
+ protected void nodeStateWillChange(CheckedTreeNode node) {
+ super.nodeStateWillChange(node);
+ if (myDelegate != null) {
+ myDelegate.nodeStateWillChange(node);
+ }
+ }
@Override
protected void onNodeStateChanged(CheckedTreeNode node) {
super.onNodeStateChanged(node);
if (myDelegate != null) {
- myDelegate.nodeStateChanged(node);
+ myDelegate.nodeStateDidChange(node);
}
}
interface Delegate {
- void nodeStateChanged(CheckedTreeNode node);
+ void nodeStateDidChange(CheckedTreeNode node);
+
+ void nodeStateWillChange(CheckedTreeNode node);
}
public void setDelegate(Delegate delegate) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
index badb628..a9ccf69 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
@@ -83,7 +83,7 @@
});
}
};
- mySession.addSessionListener(mySessionListener);
+ mySession.addSessionListener(mySessionListener, myDisposable);
myTreePanel = new XDebuggerTreePanel(session.getProject(), editorsProvider, myDisposable, sourcePosition, XDebuggerActions.EVALUATE_DIALOG_TREE_POPUP_GROUP,
((XDebugSessionImpl)session).getValueMarkers());
@@ -122,12 +122,6 @@
}
@Override
- protected void dispose() {
- mySession.removeSessionListener(mySessionListener);
- super.dispose();
- }
-
- @Override
protected void doOKAction() {
evaluate();
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugView.java
new file mode 100644
index 0000000..85ff7b2
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugView.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.xdebugger.impl.frame;
+
+import com.intellij.openapi.Disposable;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public interface XDebugView extends Disposable {
+ enum SessionEvent {PAUSED, BEFORE_RESUME, RESUMED, STOPPED, FRAME_CHANGED, SETTINGS_CHANGED}
+
+ void processSessionEvent(@NotNull SessionEvent event);
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewBase.java
deleted file mode 100644
index c09bcf5..0000000
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewBase.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.xdebugger.impl.frame;
-
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.ui.AppUIUtil;
-import com.intellij.xdebugger.XDebugSession;
-import com.intellij.xdebugger.XDebugSessionAdapter;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * @author nik
- */
-public abstract class XDebugViewBase implements Disposable {
- protected enum SessionEvent {PAUSED, BEFORE_RESUME, RESUMED, STOPPED, FRAME_CHANGED, SETTINGS_CHANGED}
-
- protected final XDebugSession mySession;
- private final MyDebugSessionListener mySessionListener;
-
- public XDebugViewBase(@NotNull final XDebugSession session, @Nullable Disposable parentDisposable) {
- mySession = session;
- mySessionListener = new MyDebugSessionListener();
- mySession.addSessionListener(mySessionListener);
- if (parentDisposable != null) {
- Disposer.register(parentDisposable, this);
- }
- }
-
- public void rebuildView() {
- onSessionEvent(SessionEvent.SETTINGS_CHANGED);
- }
-
- private void onSessionEvent(final SessionEvent event) {
- AppUIUtil.invokeLaterIfProjectAlive(mySession.getProject(), new Runnable() {
- @Override
- public void run() {
- rebuildView(event);
- }
- });
- }
-
- protected abstract void rebuildView(final SessionEvent event);
-
- @Override
- public void dispose() {
- mySession.removeSessionListener(mySessionListener);
- }
-
- private class MyDebugSessionListener extends XDebugSessionAdapter {
- @Override
- public void sessionPaused() {
- onSessionEvent(SessionEvent.PAUSED);
- }
-
- @Override
- public void sessionResumed() {
- onSessionEvent(SessionEvent.RESUMED);
- }
-
- @Override
- public void sessionStopped() {
- onSessionEvent(SessionEvent.STOPPED);
- }
-
- @Override
- public void stackFrameChanged() {
- onSessionEvent(SessionEvent.FRAME_CHANGED);
- }
-
- @Override
- public void beforeSessionResume() {
- onSessionEvent(SessionEvent.BEFORE_RESUME);
- }
- }
-}
\ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewSessionListener.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewSessionListener.java
new file mode 100644
index 0000000..11b3020
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewSessionListener.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.xdebugger.impl.frame;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.ui.AppUIUtil;
+import com.intellij.xdebugger.XDebugSessionAdapter;
+import org.jetbrains.annotations.NotNull;
+
+/**
+* @author nik
+*/
+public class XDebugViewSessionListener extends XDebugSessionAdapter {
+ private XDebugView myDebugView;
+ private final Project myProject;
+
+ public XDebugViewSessionListener(@NotNull XDebugView debugView, @NotNull Project project) {
+ myDebugView = debugView;
+ myProject = project;
+ }
+
+ private void onSessionEvent(final @NotNull XDebugView.SessionEvent event) {
+ AppUIUtil.invokeLaterIfProjectAlive(myProject, new Runnable() {
+ @Override
+ public void run() {
+ myDebugView.processSessionEvent(event);
+ }
+ });
+ }
+
+ @Override
+ public void sessionPaused() {
+ onSessionEvent(XDebugView.SessionEvent.PAUSED);
+ }
+
+ @Override
+ public void sessionResumed() {
+ onSessionEvent(XDebugView.SessionEvent.RESUMED);
+ }
+
+ @Override
+ public void sessionStopped() {
+ onSessionEvent(XDebugView.SessionEvent.STOPPED);
+ }
+
+ @Override
+ public void stackFrameChanged() {
+ onSessionEvent(XDebugView.SessionEvent.FRAME_CHANGED);
+ }
+
+ @Override
+ public void beforeSessionResume() {
+ onSessionEvent(XDebugView.SessionEvent.BEFORE_RESUME);
+ }
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
index 7d1c9a9..275015c 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
@@ -16,7 +16,6 @@
package com.intellij.xdebugger.impl.frame;
import com.intellij.ide.CommonActionsManager;
-import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
@@ -34,7 +33,6 @@
import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.frame.XSuspendContext;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
@@ -51,19 +49,20 @@
/**
* @author nik
*/
-public class XFramesView extends XDebugViewBase {
+public class XFramesView implements XDebugView {
private final JPanel myMainPanel;
private final XDebuggerFramesList myFramesList;
private final JComboBox myThreadComboBox;
private final Set<XExecutionStack> myExecutionStacks = ContainerUtil.newHashSet();
+ @NotNull private final XDebugSession mySession;
private XExecutionStack mySelectedStack;
private boolean myListenersEnabled;
private final Map<XExecutionStack, StackFramesListBuilder> myBuilders = new HashMap<XExecutionStack, StackFramesListBuilder>();
private final ActionToolbarImpl myToolbar;
private final Wrapper myThreadsPanel;
- public XFramesView(@NotNull final XDebugSession session, @Nullable final Disposable parentDisposable) {
- super(session, parentDisposable);
+ public XFramesView(@NotNull final XDebugSession session) {
+ mySession = session;
myMainPanel = new JPanel(new BorderLayout());
@@ -97,7 +96,7 @@
myThreadsPanel.add(myToolbar.getComponent(), BorderLayout.EAST);
myMainPanel.add(myThreadsPanel, BorderLayout.NORTH);
- rebuildView(SessionEvent.RESUMED);
+ processSessionEvent(SessionEvent.RESUMED);
}
private ActionToolbarImpl createToolbar() {
@@ -125,7 +124,7 @@
}
@Override
- protected void rebuildView(final SessionEvent event) {
+ public void processSessionEvent(@NotNull final SessionEvent event) {
if (event == SessionEvent.BEFORE_RESUME) return;
if (event == SessionEvent.FRAME_CHANGED) {
XStackFrame currentStackFrame = mySession.getCurrentStackFrame();
@@ -191,6 +190,10 @@
}
}
+ @Override
+ public void dispose() {
+ }
+
public XDebuggerFramesList getFramesList() {
return myFramesList;
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java
index 9eb5884..f7f32ba 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java
@@ -15,51 +15,31 @@
*/
package com.intellij.xdebugger.impl.frame;
-import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
-import com.intellij.xdebugger.XDebuggerBundle;
+import com.intellij.ui.AppUIUtil;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.frame.XStackFrame;
-import com.intellij.xdebugger.impl.actions.XDebuggerActions;
-import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
-import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
-import com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode;
-import com.intellij.xdebugger.impl.ui.tree.nodes.XStackFrameNode;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
-
/**
* @author nik
*/
-public class XStandaloneVariablesView implements Disposable {
- private final XDebuggerTreePanel myDebuggerTreePanel;
+public class XStandaloneVariablesView extends XVariablesViewBase {
+ private final XStackFrame myStackFrame;
- public XStandaloneVariablesView(@NotNull Project project, @NotNull XDebuggerEditorsProvider editorsProvider) {
- myDebuggerTreePanel = new XDebuggerTreePanel(project, editorsProvider, this, null, XDebuggerActions.VARIABLES_TREE_POPUP_GROUP, null);
- getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.variables.not.available"));
+ public XStandaloneVariablesView(@NotNull Project project, @NotNull XDebuggerEditorsProvider editorsProvider, @NotNull XStackFrame stackFrame) {
+ super(project, editorsProvider, null);
+ myStackFrame = stackFrame;
+ buildTreeAndRestoreState(stackFrame);
}
- public void showVariables(@NotNull XStackFrame stackFrame) {
- getTree().setSourcePosition(stackFrame.getSourcePosition());
- getTree().setRoot(new XStackFrameNode(getTree(), stackFrame), false);
- }
-
- public void showMessage(@NotNull String message) {
- getTree().setSourcePosition(null);
- getTree().setRoot(MessageTreeNode.createInfoMessage(getTree(), message), true);
- }
-
- private XDebuggerTree getTree() {
- return myDebuggerTreePanel.getTree();
- }
-
- @Override
- public void dispose() {
-
- }
-
- public JComponent getPanel() {
- return myDebuggerTreePanel.getMainPanel();
+ public void rebuildView() {
+ AppUIUtil.invokeLaterIfProjectAlive(getTree().getProject(), new Runnable() {
+ @Override
+ public void run() {
+ saveCurrentTreeState(myStackFrame);
+ buildTreeAndRestoreState(myStackFrame);
+ }
+ });
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
index fb28bda..31b30a8 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
@@ -15,55 +15,34 @@
*/
package com.intellij.xdebugger.impl.frame;
-import com.intellij.ide.dnd.DnDManager;
-import com.intellij.openapi.Disposable;
import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugSession;
-import com.intellij.xdebugger.XDebuggerBundle;
-import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
-import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
-import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
-import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeRestorer;
-import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeState;
import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
-import com.intellij.xdebugger.impl.ui.tree.nodes.XStackFrameNode;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
import static com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode.createInfoMessage;
/**
* @author nik
*/
-public class XVariablesView extends XDebugViewBase {
- private final XDebuggerTreePanel myDebuggerTreePanel;
- private XDebuggerTreeState myTreeState;
- private Object myFrameEqualityObject;
- private XDebuggerTreeRestorer myTreeRestorer;
+public class XVariablesView extends XVariablesViewBase implements XDebugView {
+ @NotNull private final XDebugSession mySession;
- public XVariablesView(@NotNull XDebugSession session, @Nullable final Disposable parentDisposable) {
- super(session, parentDisposable);
- XDebuggerEditorsProvider editorsProvider = session.getDebugProcess().getEditorsProvider();
- XValueMarkers<?,?> markers = session instanceof XDebugSessionImpl ? ((XDebugSessionImpl)session).getValueMarkers() : null;
- myDebuggerTreePanel = new XDebuggerTreePanel(session.getProject(), editorsProvider, this, null, XDebuggerActions.VARIABLES_TREE_POPUP_GROUP, markers);
- myDebuggerTreePanel.getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.variables.not.available"));
- DnDManager.getInstance().registerSource(myDebuggerTreePanel, myDebuggerTreePanel.getTree());
+ public XVariablesView(@NotNull XDebugSession session) {
+ super(session.getProject(), session.getDebugProcess().getEditorsProvider(), ((XDebugSessionImpl)session).getValueMarkers());
+ mySession = session;
}
@Override
- protected void rebuildView(final SessionEvent event) {
+ public void processSessionEvent(@NotNull final SessionEvent event) {
XStackFrame stackFrame = mySession.getCurrentStackFrame();
- XDebuggerTree tree = myDebuggerTreePanel.getTree();
+ XDebuggerTree tree = getTree();
if (event == SessionEvent.BEFORE_RESUME || event == SessionEvent.SETTINGS_CHANGED) {
- disposeTreeRestorer();
- myFrameEqualityObject = stackFrame != null ? stackFrame.getEqualityObject() : null;
- myTreeState = XDebuggerTreeState.saveState(tree);
+ saveCurrentTreeState(stackFrame);
if (event == SessionEvent.BEFORE_RESUME) {
return;
}
@@ -71,16 +50,7 @@
tree.markNodesObsolete();
if (stackFrame != null) {
- tree.setSourcePosition(stackFrame.getSourcePosition());
- tree.setRoot(new XStackFrameNode(tree, stackFrame), false);
- Object newEqualityObject = stackFrame.getEqualityObject();
- if (myFrameEqualityObject != null &&
- newEqualityObject != null &&
- myFrameEqualityObject.equals(newEqualityObject) &&
- myTreeState != null) {
- disposeTreeRestorer();
- myTreeRestorer = myTreeState.restoreState(tree);
- }
+ buildTreeAndRestoreState(stackFrame);
}
else {
tree.setSourcePosition(null);
@@ -90,38 +60,10 @@
node = createInfoMessage(tree, "Frame is not available");
}
else {
- if (mySession instanceof XDebugSession) {
- XDebugProcess debugProcess = ((XDebugSession)mySession).getDebugProcess();
-
- node = createInfoMessage(tree, debugProcess.getCurrentStateMessage(), debugProcess.getCurrentStateHyperlinkListener());
- }
- else {
- node = createInfoMessage(tree, "Frame is not available");
- }
+ XDebugProcess debugProcess = mySession.getDebugProcess();
+ node = createInfoMessage(tree, debugProcess.getCurrentStateMessage(), debugProcess.getCurrentStateHyperlinkListener());
}
tree.setRoot(node, true);
}
}
-
- private void disposeTreeRestorer() {
- if (myTreeRestorer != null) {
- myTreeRestorer.dispose();
- myTreeRestorer = null;
- }
- }
-
- public XDebuggerTree getTree() {
- return myDebuggerTreePanel.getTree();
- }
-
- public JComponent getPanel() {
- return myDebuggerTreePanel.getMainPanel();
- }
-
- @Override
- public void dispose() {
- disposeTreeRestorer();
- DnDManager.getInstance().unregisterSource(myDebuggerTreePanel, myDebuggerTreePanel.getTree());
- super.dispose();
- }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java
new file mode 100644
index 0000000..33a1639
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.xdebugger.impl.frame;
+
+import com.intellij.ide.dnd.DnDManager;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.project.Project;
+import com.intellij.xdebugger.XDebuggerBundle;
+import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
+import com.intellij.xdebugger.frame.XStackFrame;
+import com.intellij.xdebugger.impl.actions.XDebuggerActions;
+import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
+import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
+import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeRestorer;
+import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeState;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XStackFrameNode;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * @author nik
+ */
+public abstract class XVariablesViewBase implements Disposable {
+ protected final XDebuggerTreePanel myDebuggerTreePanel;
+ private XDebuggerTreeState myTreeState;
+ private Object myFrameEqualityObject;
+ private XDebuggerTreeRestorer myTreeRestorer;
+
+ protected XVariablesViewBase(@NotNull Project project, @NotNull XDebuggerEditorsProvider editorsProvider, @Nullable XValueMarkers<?, ?> markers) {
+ myDebuggerTreePanel = new XDebuggerTreePanel(project, editorsProvider, this, null, XDebuggerActions.VARIABLES_TREE_POPUP_GROUP, markers);
+ myDebuggerTreePanel.getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.variables.not.available"));
+ DnDManager.getInstance().registerSource(myDebuggerTreePanel, myDebuggerTreePanel.getTree());
+ }
+
+ protected void buildTreeAndRestoreState(@NotNull XStackFrame stackFrame) {
+ XDebuggerTree tree = myDebuggerTreePanel.getTree();
+ tree.setSourcePosition(stackFrame.getSourcePosition());
+ tree.setRoot(new XStackFrameNode(tree, stackFrame), false);
+ Object newEqualityObject = stackFrame.getEqualityObject();
+ if (myFrameEqualityObject != null && newEqualityObject != null && myFrameEqualityObject.equals(newEqualityObject)
+ && myTreeState != null) {
+ disposeTreeRestorer();
+ myTreeRestorer = myTreeState.restoreState(tree);
+ }
+ }
+
+ protected void saveCurrentTreeState(@Nullable XStackFrame stackFrame) {
+ disposeTreeRestorer();
+ myFrameEqualityObject = stackFrame != null ? stackFrame.getEqualityObject() : null;
+ myTreeState = XDebuggerTreeState.saveState(myDebuggerTreePanel.getTree());
+ }
+
+ private void disposeTreeRestorer() {
+ if (myTreeRestorer != null) {
+ myTreeRestorer.dispose();
+ myTreeRestorer = null;
+ }
+ }
+
+ public XDebuggerTree getTree() {
+ return myDebuggerTreePanel.getTree();
+ }
+
+ public JComponent getPanel() {
+ return myDebuggerTreePanel.getMainPanel();
+ }
+
+ @Override
+ public void dispose() {
+ disposeTreeRestorer();
+ DnDManager.getInstance().unregisterSource(myDebuggerTreePanel, myDebuggerTreePanel.getTree());
+ }
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java
index 557d3fc..48defd3 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java
@@ -19,9 +19,7 @@
import com.intellij.ide.dnd.DnDEvent;
import com.intellij.ide.dnd.DnDManager;
import com.intellij.ide.dnd.DnDNativeTarget;
-import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
-import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.AnActionButton;
import com.intellij.ui.AnActionButtonRunnable;
@@ -56,18 +54,17 @@
/**
* @author nik
*/
-public class XWatchesViewImpl extends XDebugViewBase implements DnDNativeTarget, XWatchesView {
+public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugView {
private final XDebuggerTreePanel myTreePanel;
private XDebuggerTreeState myTreeState;
private XDebuggerTreeRestorer myTreeRestorer;
private final WatchesRootNode myRootNode;
+ @NotNull private final XDebugSession mySession;
private final XDebugSessionData mySessionData;
private final JPanel myDecoratedPanel;
- public XWatchesViewImpl(@NotNull final XDebugSession session,
- @NotNull final Disposable parentDisposable,
- final XDebugSessionData sessionData) {
- super(session, parentDisposable);
+ public XWatchesViewImpl(@NotNull final XDebugSession session, final @NotNull XDebugSessionData sessionData) {
+ mySession = session;
mySessionData = sessionData;
myTreePanel = new XDebuggerTreePanel(session.getProject(), session.getDebugProcess().getEditorsProvider(), this, null,
XDebuggerActions.WATCHES_TREE_POPUP_GROUP, ((XDebugSessionImpl)session).getValueMarkers());
@@ -82,12 +79,6 @@
actionManager.getAction(XDebuggerActions.XEDIT_WATCH).registerCustomShortcutSet(f2Shortcut, tree);
DnDManager.getInstance().registerTarget(this, tree);
- Disposer.register(parentDisposable, new Disposable() {
- @Override
- public void dispose() {
- DnDManager.getInstance().unregisterTarget(XWatchesViewImpl.this, myTreePanel.getTree());
- }
- });
myRootNode = new WatchesRootNode(tree, session, this, sessionData.getWatchExpressions());
tree.setRoot(myRootNode, false);
@@ -115,6 +106,11 @@
}
+ @Override
+ public void dispose() {
+ DnDManager.getInstance().unregisterTarget(this, myTreePanel.getTree());
+ }
+
private void executeAction(final String watch) {
AnAction action = ActionManager.getInstance().getAction(watch);
Presentation presentation = action.getTemplatePresentation().clone();
@@ -133,7 +129,7 @@
}
@Override
- protected void rebuildView(final SessionEvent event) {
+ public void processSessionEvent(@NotNull final SessionEvent event) {
XStackFrame stackFrame = mySession.getCurrentStackFrame();
XDebuggerTree tree = myTreePanel.getTree();
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java
index ac556ad..4a40d8a 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java
@@ -31,6 +31,7 @@
import com.intellij.ui.awt.RelativePoint;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
+import com.intellij.xdebugger.breakpoints.XBreakpointAdapter;
import com.intellij.xdebugger.breakpoints.XBreakpointListener;
import com.intellij.xdebugger.breakpoints.XBreakpointManager;
import com.intellij.xdebugger.frame.XFullValueEvaluator;
@@ -136,17 +137,13 @@
popup.show(point);
}
-
-
public static void showXBreakpointEditorBalloon(final Project project,
@Nullable final Point point,
final JComponent component,
final boolean showAllOptions,
final XBreakpoint breakpoint) {
final XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager();
- final XLightBreakpointPropertiesPanel propertiesPanel =
- new XLightBreakpointPropertiesPanel(project, breakpointManager,
- breakpoint, showAllOptions);
+ final XLightBreakpointPropertiesPanel<XBreakpoint<?>> propertiesPanel = new XLightBreakpointPropertiesPanel<XBreakpoint<?>>(project, breakpointManager, breakpoint, showAllOptions);
final Ref<Balloon> balloonRef = Ref.create(null);
final Ref<Boolean> isLoading = Ref.create(Boolean.FALSE);
@@ -164,49 +161,32 @@
}
});
-
isLoading.set(Boolean.TRUE);
propertiesPanel.loadProperties();
isLoading.set(Boolean.FALSE);
- final JComponent mainPanel = propertiesPanel.getMainPanel();
-
- final Runnable viewBreakpoints = new Runnable() {
+ Runnable showMoreOptions = new Runnable() {
@Override
public void run() {
propertiesPanel.saveProperties();
- //showXBreakpointEditorBalloon(project, point, component, true, breakpoint);
BreakpointsDialogFactory.getInstance(project).showDialog(breakpoint);
}
};
- final Balloon balloon = showBreakpointEditor(project, mainPanel, breakpoint.getType().getDisplayText(breakpoint), point, component, viewBreakpoints,
- breakpoint);
+ final JComponent mainPanel = propertiesPanel.getMainPanel();
+ final Balloon balloon = showBreakpointEditor(project, mainPanel, point, component, showMoreOptions, breakpoint);
balloonRef.set(balloon);
-
- final XBreakpointListener<XBreakpoint<?>> breakpointListener = new XBreakpointListener<XBreakpoint<?>>() {
+ final XBreakpointListener<XBreakpoint<?>> breakpointListener = new XBreakpointAdapter<XBreakpoint<?>>() {
@Override
- public void breakpointAdded(@NotNull XBreakpoint<?> breakpoint1) {
- }
-
- @Override
- public void breakpointRemoved(@NotNull XBreakpoint<?> breakpoint1) {
- if (breakpoint1.equals(breakpoint)) {
+ public void breakpointRemoved(@NotNull XBreakpoint<?> removedBreakpoint) {
+ if (removedBreakpoint.equals(breakpoint)) {
balloon.hide();
}
}
-
- @Override
- public void breakpointChanged(@NotNull XBreakpoint<?> breakpoint1) {
- }
};
- balloon.addListener(new JBPopupListener() {
- @Override
- public void beforeShown(LightweightWindowEvent event) {
- }
-
+ balloon.addListener(new JBPopupListener.Adapter() {
@Override
public void onClosed(LightweightWindowEvent event) {
propertiesPanel.saveProperties();
@@ -214,12 +194,10 @@
}
});
-
-
-
if (point == null) {
balloon.showInCenterOf(component);
- } else {
+ }
+ else {
balloon.show(new RelativePoint(component, point), Balloon.Position.atRight);
}
@@ -233,7 +211,6 @@
}
public static Balloon showBreakpointEditor(Project project, final JComponent mainPanel,
- final String displayName,
final Point whereToShow,
final JComponent component,
@Nullable final Runnable showMoreOptions, Object breakpoint) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
index 8779d02..e442654 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
@@ -33,7 +33,9 @@
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.ui.AppUIUtil;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.tabs.PinToolwindowTabAction;
import com.intellij.xdebugger.XDebugProcess;
@@ -57,7 +59,7 @@
*/
public class XDebugSessionTab extends DebuggerSessionTabBase {
private XWatchesViewImpl myWatchesView;
- private final List<XDebugViewBase> myViews = new ArrayList<XDebugViewBase>();
+ private final List<XDebugView> myViews = new ArrayList<XDebugView>();
public XDebugSessionTab(@NotNull final Project project, @NotNull final XDebugSessionImpl session, final @Nullable Icon icon,
ExecutionEnvironment environment, ProgramRunner runner) {
@@ -72,7 +74,7 @@
}
private Content createVariablesContent(final XDebugSession session) {
- final XVariablesView variablesView = new XVariablesView(session, this);
+ final XVariablesView variablesView = new XVariablesView(session);
myViews.add(variablesView);
Content result = myUi.createContent(DebuggerContentInfo.VARIABLES_CONTENT, variablesView.getPanel(),
XDebuggerBundle.message("debugger.session.tab.variables.title"),
@@ -86,7 +88,7 @@
}
private Content createWatchesContent(final XDebugSession session, final XDebugSessionData sessionData) {
- myWatchesView = new XWatchesViewImpl(session, this, sessionData);
+ myWatchesView = new XWatchesViewImpl(session, sessionData);
myViews.add(myWatchesView);
Content watchesContent = myUi.createContent(DebuggerContentInfo.WATCHES_CONTENT, myWatchesView.getMainPanel(),
XDebuggerBundle.message("debugger.session.tab.watches.title"), AllIcons.Debugger.Watches, null);
@@ -96,7 +98,7 @@
}
private Content createFramesContent(final XDebugSession session) {
- final XFramesView framesView = new XFramesView(session, this);
+ final XFramesView framesView = new XFramesView(session);
myViews.add(framesView);
Content framesContent = myUi.createContent(DebuggerContentInfo.FRAME_CONTENT, framesView.getMainPanel(),
XDebuggerBundle.message("debugger.session.tab.frames.title"), AllIcons.Debugger.Frame, null);
@@ -110,9 +112,14 @@
}
public void rebuildViews() {
- for (XDebugViewBase view : myViews) {
- view.rebuildView();
- }
+ AppUIUtil.invokeLaterIfProjectAlive(getProject(), new Runnable() {
+ @Override
+ public void run() {
+ for (XDebugView view : myViews) {
+ view.processSessionEvent(XDebugView.SessionEvent.SETTINGS_CHANGED);
+ }
+ }
+ });
}
public XWatchesView getWatchesView() {
@@ -125,6 +132,11 @@
myUi.addContent(createFramesContent(session), 0, PlaceInGrid.left, false);
myUi.addContent(createVariablesContent(session), 0, PlaceInGrid.center, false);
myUi.addContent(createWatchesContent(session, sessionData), 0, PlaceInGrid.right, false);
+ for (XDebugView view : myViews) {
+ Disposer.register(this, view);
+ session.addSessionListener(new XDebugViewSessionListener(view, getProject()), this);
+ }
+
myUi.getContentManager().addDataProvider(new DataProvider() {
@Nullable
@Override
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java
index da91db3..c84d2a1 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java
@@ -32,7 +32,10 @@
import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
-import com.intellij.xdebugger.impl.ui.tree.nodes.*;
+import com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode;
+import com.intellij.xdebugger.impl.ui.tree.nodes.RestorableStateNode;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -114,7 +117,13 @@
}
}
});
- new TreeSpeedSearch(this, SPEED_SEARCH_CONVERTER, true);
+
+ if (Boolean.valueOf(System.getProperty("xdebugger.variablesView.rss"))) {
+ new XDebuggerTreeSpeedSearch(this, SPEED_SEARCH_CONVERTER);
+ }
+ else {
+ new TreeSpeedSearch(this, SPEED_SEARCH_CONVERTER);
+ }
final ActionManager actionManager = ActionManager.getInstance();
addMouseListener(new PopupHandler() {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeSpeedSearch.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeSpeedSearch.java
new file mode 100644
index 0000000..0bc699a
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeSpeedSearch.java
@@ -0,0 +1,157 @@
+package com.intellij.xdebugger.impl.ui.tree;
+
+import com.intellij.ui.TreeSpeedSearch;
+import com.intellij.util.ObjectUtils;
+import com.intellij.util.containers.Convertor;
+import com.intellij.xdebugger.impl.ui.tree.nodes.RestorableStateNode;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+import java.util.LinkedList;
+import java.util.List;
+
+class XDebuggerTreeSpeedSearch extends TreeSpeedSearch implements XDebuggerTreeListener {
+ public XDebuggerTreeSpeedSearch(XDebuggerTree tree, Convertor<TreePath, String> toStringConvertor) {
+ super(tree, toStringConvertor, true);
+
+ //((XDebuggerTree)myComponent).addTreeListener(this);
+ }
+
+ @Nullable
+ @Override
+ protected Object findElement(String s) {
+ String string = s.trim();
+
+ XDebuggerTreeNode node = ObjectUtils.tryCast(myComponent.getLastSelectedPathComponent(), XDebuggerTreeNode.class);
+ if (node == null) {
+ node = ObjectUtils.tryCast(myComponent.getModel().getRoot(), XDebuggerTreeNode.class);
+ if (node == null) {
+ return null;
+ }
+ }
+ return findPath(string, node, true);
+ }
+
+ private Object findPath(String string, XDebuggerTreeNode node, boolean checkChildren) {
+ TreePath path = node.getPath();
+ if (isMatchingElement(path, string)) {
+ return path;
+ }
+
+ XDebuggerTreeNode parent = ObjectUtils.tryCast(node.getParent(), XDebuggerTreeNode.class);
+ int nodeIndex;
+ List<? extends TreeNode> parentChildren;
+ if (parent != null) {
+ parentChildren = parent.getChildren();
+ nodeIndex = parentChildren.indexOf(node);
+ if (nodeIndex != -1) {
+ for (int i = nodeIndex + 1; i < parentChildren.size(); i++) {
+ TreePath result = match(parentChildren.get(i), string);
+ if (result != null) {
+ return result;
+ }
+ }
+
+ for (int i = nodeIndex - 1; i >= 0; i--) {
+ TreePath result = match(parentChildren.get(i), string);
+ if (result != null) {
+ return result;
+ }
+ }
+ }
+ }
+ else {
+ nodeIndex = -1;
+ parentChildren = null;
+ }
+
+ // check children up to x level
+ if (checkChildren && !node.isLeaf()) {
+ TreePath result = findInChildren(node, string);
+ if (result != null) {
+ return result;
+ }
+ }
+
+ // check siblings children up to x level
+ if (parent != null) {
+ for (int i = nodeIndex + 1; i < parentChildren.size(); i++) {
+ TreePath result = findInChildren(parentChildren.get(i), string);
+ if (result != null) {
+ return result;
+ }
+ }
+
+ for (int i = nodeIndex - 1; i >= 0; i--) {
+ TreePath result = findInChildren(parentChildren.get(i), string);
+ if (result != null) {
+ return result;
+ }
+ }
+
+ return findPath(string, parent, false);
+ }
+
+ //myComponent.getSelectionPath()
+ return null;
+ }
+
+ private TreePath findInChildren(TreeNode node, String string) {
+ if (node.isLeaf() || !(node instanceof XDebuggerTreeNode)) {
+ return null;
+ }
+
+ LinkedList<XDebuggerTreeNode> queue = new LinkedList<XDebuggerTreeNode>();
+ queue.addLast((XDebuggerTreeNode)node);
+
+ int initialLevel = ((XDebuggerTreeNode)node).getPath().getPathCount();
+
+ while (!queue.isEmpty()) {
+ XDebuggerTreeNode p = queue.removeFirst();
+
+ if ((p.getPath().getPathCount() - initialLevel) > 3) {
+ return null;
+ }
+
+ List<? extends TreeNode> children = p.getChildren();
+ if (children.isEmpty()) {
+ continue;
+ }
+
+ for (TreeNode child : children) {
+ if (!(child instanceof XDebuggerTreeNode)) {
+ continue;
+ }
+
+ TreePath result = match(child, string);
+ if (result != null) {
+ return result;
+ }
+
+ if (!child.isLeaf()) {
+ queue.addLast((XDebuggerTreeNode)child);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Nullable
+ private TreePath match(TreeNode node, String string) {
+ TreePath path = node instanceof XDebuggerTreeNode ? ((XDebuggerTreeNode)node).getPath() : null;
+ return isMatchingElement(path, string) ? path : null;
+ }
+
+ @Override
+ public void nodeLoaded(@NotNull RestorableStateNode node, String name) {
+ }
+
+ @Override
+ public void childrenLoaded(@NotNull XDebuggerTreeNode node, @NotNull List<XValueContainerNode<?>> children, boolean last) {
+ }
+}
\ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java
index 94d4093..8f12813 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java
@@ -68,8 +68,9 @@
myEllipsis = false;
}
+ @NotNull
@Override
- protected List<? extends TreeNode> getChildren() {
+ public List<? extends TreeNode> getChildren() {
return Collections.emptyList();
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java
index a7e8393..21ceb24 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java
@@ -76,8 +76,9 @@
fireNodeStructureChanged();
}
+ @NotNull
@Override
- protected List<? extends TreeNode> getChildren() {
+ public List<? extends TreeNode> getChildren() {
return myChildren;
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java
index d60c0683..5af339e 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java
@@ -87,7 +87,8 @@
return Collections.enumeration(getChildren());
}
- protected abstract List<? extends TreeNode> getChildren();
+ @NotNull
+ public abstract List<? extends TreeNode> getChildren();
protected void setIcon(final Icon icon) {
myIcon = icon;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
index 55179e5..a7059a4 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
@@ -195,8 +195,9 @@
fireNodesInserted(messages);
}
+ @NotNull
@Override
- protected List<? extends TreeNode> getChildren() {
+ public List<? extends TreeNode> getChildren() {
loadChildren();
if (myCachedAllChildren == null) {
diff --git a/plugins/IdeaTestAssistant/src/META-INF/plugin.xml b/plugins/IdeaTestAssistant/src/META-INF/plugin.xml
index cc9c1ad..7f4d9a5 100644
--- a/plugins/IdeaTestAssistant/src/META-INF/plugin.xml
+++ b/plugins/IdeaTestAssistant/src/META-INF/plugin.xml
@@ -10,6 +10,9 @@
class="com.intellij.testAssistant.NavigateToTestDataAction"
text="Navigate to testdata" use-shortcut-of="GotoRelated">
</action>
+ <action id="DumpCleanTestData" internal="true" class="com.intellij.internal.DumpCleanHighlightingTestdataAction">
+ <add-to-group group-id="Internal.Dump"/>
+ </action>
</actions>
<extensions defaultExtensionNs="com.intellij">
@@ -18,6 +21,7 @@
<codeInsight.lineMarkerProvider language="Groovy" implementationClass="com.intellij.testAssistant.TestDataLineMarkerProvider"/>
<fileEditorProvider implementation="com.intellij.testAssistant.TestDataGroupEditorProvider"/>
<gotoRelatedProvider implementation="com.intellij.testAssistant.TestDataAsRelatedFileProvider"/>
+ <psi.referenceContributor implementation="com.intellij.testAssistant.TestDataReferenceContributor"/>
</extensions>
<project-components>
diff --git a/plugins/IdeaTestAssistant/src/com/intellij/internal/DumpCleanHighlightingTestdataAction.java b/plugins/IdeaTestAssistant/src/com/intellij/internal/DumpCleanHighlightingTestdataAction.java
new file mode 100644
index 0000000..5260028
--- /dev/null
+++ b/plugins/IdeaTestAssistant/src/com/intellij/internal/DumpCleanHighlightingTestdataAction.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.internal;
+
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.testFramework.ExpectedHighlightingData;
+
+import java.io.File;
+import java.io.IOException;
+
+public class DumpCleanHighlightingTestdataAction extends AnAction implements DumbAware {
+ private static final Logger LOG = Logger.getInstance("#" + DumpCleanHighlightingTestdataAction.class);
+
+ public DumpCleanHighlightingTestdataAction() {
+ super("Dump highlighting-markup-free data");
+ }
+
+ @Override
+ public void actionPerformed(final AnActionEvent event) {
+ final DataContext dataContext = event.getDataContext();
+ final Project project = CommonDataKeys.PROJECT.getData(dataContext);
+ final PsiFile psiFile = CommonDataKeys.PSI_FILE.getData(dataContext);
+ if (psiFile != null) {
+ final VirtualFile virtualFile = psiFile.getVirtualFile();
+ if (virtualFile != null) {
+ final Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
+ if (document != null) {
+ final ExpectedHighlightingData data = new ExpectedHighlightingData(document, true, true);
+ data.init();
+ }
+ return;
+ }
+ }
+ final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
+ descriptor.setTitle("Choose Directory");
+ descriptor.setDescription("Directory containing highlighting test data");
+ final VirtualFile dirToProcess = FileChooser.chooseFile(descriptor, project, null);
+ if (dirToProcess != null) {
+ LOG.assertTrue(project != null);
+ final FileChooserDescriptor targetDescriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
+ targetDescriptor.setTitle("Choose Directory");
+ targetDescriptor.setDescription("Directory where highlighting-markup-free copies would be placed");
+ final VirtualFile destinationFolder = FileChooser.chooseFile(targetDescriptor, project, null);
+ if (destinationFolder == dirToProcess) {
+ Messages.showErrorDialog(project, "Source and destination roots should differ", "Reject to Proceed");
+ return;
+ }
+ if (destinationFolder != null) {
+ final File destination = VfsUtilCore.virtualToIoFile(destinationFolder);
+ final VirtualFile[] files = dirToProcess.getChildren();
+ for (VirtualFile virtualFile : files) {
+ final Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
+ if (document != null) {
+ final ExpectedHighlightingData data = new ExpectedHighlightingData(document, true, true);
+ data.init();
+ final File file = new File(destination, virtualFile.getName());
+ try {
+ FileUtil.writeToFile(file, document.getText());
+ }
+ catch (IOException e) {
+ LOG.error(e);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ e.getPresentation().setEnabled(CommonDataKeys.PROJECT.getData(e.getDataContext()) != null);
+ }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataLineMarkerProvider.java b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataLineMarkerProvider.java
index 4f881e6..81d7543 100644
--- a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataLineMarkerProvider.java
+++ b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataLineMarkerProvider.java
@@ -38,6 +38,10 @@
* @author yole
*/
public class TestDataLineMarkerProvider implements LineMarkerProvider {
+ public static final String TEST_DATA_PATH_ANNOTATION_QUALIFIED_NAME = "com.intellij.testFramework.TestDataPath";
+ public static final String CONTENT_ROOT_VARIABLE = "$CONTENT_ROOT";
+ public static final String PROJECT_ROOT_VARIABLE = "$PROJECT_ROOT";
+
public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
return null;
@@ -80,7 +84,8 @@
@Nullable
public static String getTestDataBasePath(PsiClass psiClass) {
- final PsiAnnotation annotation = AnnotationUtil.findAnnotationInHierarchy(psiClass, Collections.singleton("com.intellij.testFramework.TestDataPath"));
+ final PsiAnnotation annotation = AnnotationUtil.findAnnotationInHierarchy(psiClass,
+ Collections.singleton(TEST_DATA_PATH_ANNOTATION_QUALIFIED_NAME));
if (annotation != null) {
final PsiAnnotationMemberValue value = annotation.findAttributeValue(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME);
if (value instanceof PsiExpression) {
@@ -89,7 +94,7 @@
final Object constantValue = evaluationHelper.computeConstantExpression(value, false);
if (constantValue instanceof String) {
String path = (String) constantValue;
- if (path.contains("$CONTENT_ROOT")) {
+ if (path.contains(CONTENT_ROOT_VARIABLE)) {
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
final VirtualFile file = psiClass.getContainingFile().getVirtualFile();
if (file == null) {
@@ -97,14 +102,14 @@
}
final VirtualFile contentRoot = fileIndex.getContentRootForFile(file);
if (contentRoot == null) return null;
- path = path.replace("$CONTENT_ROOT", contentRoot.getPath());
+ path = path.replace(CONTENT_ROOT_VARIABLE, contentRoot.getPath());
}
- if (path.contains("$PROJECT_ROOT")) {
+ if (path.contains(PROJECT_ROOT_VARIABLE)) {
final VirtualFile baseDir = project.getBaseDir();
if (baseDir == null) {
return null;
}
- path = path.replace("$PROJECT_ROOT", baseDir.getPath());
+ path = path.replace(PROJECT_ROOT_VARIABLE, baseDir.getPath());
}
return path;
}
diff --git a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceCollector.java b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceCollector.java
index ad7a448..3ee1864 100644
--- a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceCollector.java
+++ b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceCollector.java
@@ -23,12 +23,14 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
import java.util.*;
/**
* @author yole
*/
public class TestDataReferenceCollector {
+ private static final String TEST_DATA_FILE_ANNOTATION_QUALIFIED_NAME = "com.intellij.testFramework.TestDataFile";
private final String myTestDataPath;
private final String myTestName;
private final List<String> myLogMessages = new ArrayList<String>();
@@ -36,6 +38,9 @@
private boolean myFoundTestDataParameters = false;
public TestDataReferenceCollector(@Nullable String testDataPath, String testName) {
+ if (StringUtil.isNotEmpty(testDataPath) && StringUtil.endsWithChar(testDataPath, File.separatorChar)) {
+ testDataPath += File.separatorChar;
+ }
myTestDataPath = testDataPath;
myTestName = testName;
}
@@ -80,7 +85,7 @@
for (int i = 0, psiParametersLength = psiParameters.length; i < psiParametersLength; i++) {
PsiParameter psiParameter = psiParameters[i];
final PsiModifierList modifierList = psiParameter.getModifierList();
- if (modifierList != null && modifierList.findAnnotation("com.intellij.testFramework.TestDataFile") != null) {
+ if (modifierList != null && modifierList.findAnnotation(TEST_DATA_FILE_ANNOTATION_QUALIFIED_NAME) != null) {
myFoundTestDataParameters = true;
processCallArgument(expression, argumentMap, result, i);
haveAnnotatedParameters = true;
@@ -152,7 +157,6 @@
if (initializer != null) {
return evaluate(initializer, arguments);
}
-
}
}
else if (expression instanceof PsiMethodCallExpression) {
diff --git a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceContributor.java b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceContributor.java
new file mode 100644
index 0000000..28de8d3
--- /dev/null
+++ b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceContributor.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.testAssistant;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileInfoManager;
+import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
+import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
+import com.intellij.util.ProcessingContext;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import static com.intellij.patterns.PsiJavaPatterns.literalExpression;
+import static com.intellij.testAssistant.TestDataLineMarkerProvider.*;
+
+/**
+ * User: zolotov
+ * Date: 9/20/13
+ */
+public class TestDataReferenceContributor extends PsiReferenceContributor {
+ @Override
+ public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ registrar.registerReferenceProvider(literalExpression().annotationParam(TEST_DATA_PATH_ANNOTATION_QUALIFIED_NAME),
+ new TestDataReferenceProvider());
+ }
+
+ private static class TestDataReferenceProvider extends PsiReferenceProvider {
+ @NotNull
+ @Override
+ public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull final ProcessingContext context) {
+ final TestDataReferenceSet referenceSet = new TestDataReferenceSet(element);
+ referenceSet.addCustomization(FileReferenceSet.DEFAULT_PATH_EVALUATOR_OPTION, FileReferenceSet.ABSOLUTE_TOP_LEVEL);
+ return referenceSet.getAllReferences();
+ }
+ }
+
+ private static class TestDataReferenceSet extends FileReferenceSet {
+ public TestDataReferenceSet(@NotNull PsiElement element) {
+ super(element);
+ }
+
+ @Override
+ public boolean isEmptyPathAllowed() {
+ return false;
+ }
+
+ @Override
+ public boolean isAbsolutePathReference() {
+ return super.isAbsolutePathReference() || StringUtil.startsWithChar(getPathString(), '$');
+ }
+
+ @Override
+ public FileReference createFileReference(TextRange range, int index, String text) {
+ return new TestDataReference(this, range, index, text);
+ }
+
+ @NotNull
+ @Override
+ public Collection<PsiFileSystemItem> computeDefaultContexts() {
+ final VirtualFile localSystemRoot = LocalFileSystem.getInstance().getRoot();
+ final PsiManager psiManager = PsiManager.getInstance(getElement().getProject());
+ final PsiDirectory psiRoot = psiManager.findDirectory(localSystemRoot);
+ if (psiRoot != null) {
+ return Collections.<PsiFileSystemItem>singleton(psiRoot);
+ }
+ return super.computeDefaultContexts();
+ }
+
+ @Override
+ protected Condition<PsiFileSystemItem> getReferenceCompletionFilter() {
+ return DIRECTORY_FILTER;
+ }
+ }
+
+ public static class TestDataReference extends FileReference {
+ public TestDataReference(@NotNull FileReferenceSet fileReferenceSet, TextRange range, int index, String text) {
+ super(fileReferenceSet, range, index, text);
+ }
+
+ @NotNull
+ @Override
+ public Object[] getVariants() {
+ if (getIndex() == 0 && !StringUtil.startsWithChar(getFileReferenceSet().getPathString(), '/')) {
+ Collection<Object> variants = ContainerUtil.newHashSet(super.getVariants());
+ final PsiDirectory projectPsiRoot = getProjectPsiRoot();
+ if (projectPsiRoot != null) {
+ variants.add(FileInfoManager.getFileLookupItem(projectPsiRoot, PROJECT_ROOT_VARIABLE, projectPsiRoot.getIcon(0))
+ .withTypeText(projectPsiRoot.getVirtualFile().getPath(), true));
+ }
+
+ final PsiDirectory contentPsiRoot = getContentPsiRoot();
+ if (contentPsiRoot != null) {
+ variants.add(FileInfoManager.getFileLookupItem(contentPsiRoot, CONTENT_ROOT_VARIABLE, contentPsiRoot.getIcon(0))
+ .withTypeText(contentPsiRoot.getVirtualFile().getPath(), true));
+ }
+ return variants.toArray(new Object[variants.size()]);
+ }
+ return super.getVariants();
+ }
+
+ @NotNull
+ @Override
+ protected ResolveResult[] innerResolve(boolean caseSensitive) {
+ if (getIndex() == 0 && StringUtil.startsWithChar(getText(), '$')) {
+ if (PROJECT_ROOT_VARIABLE.equals(getText())) {
+ final PsiDirectory projectPsiRoot = getProjectPsiRoot();
+ if (projectPsiRoot != null) {
+ return new ResolveResult[]{new PsiElementResolveResult(projectPsiRoot)};
+ }
+ }
+ else if (CONTENT_ROOT_VARIABLE.equals(getText())) {
+ final PsiDirectory contentPsiRoot = getContentPsiRoot();
+ if (contentPsiRoot != null) {
+ return new ResolveResult[]{new PsiElementResolveResult(contentPsiRoot)};
+ }
+ }
+ }
+ return super.innerResolve(caseSensitive);
+ }
+
+ @Nullable
+ private PsiDirectory getProjectPsiRoot() {
+ final Project project = getElement().getProject();
+ final VirtualFile projectDir = project.getBaseDir();
+ if (projectDir != null) {
+ final PsiManager psiManager = PsiManager.getInstance(project);
+ return psiManager.findDirectory(projectDir);
+ }
+ return null;
+ }
+
+ @Nullable
+ private PsiDirectory getContentPsiRoot() {
+ final Project project = getElement().getProject();
+ final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
+ final VirtualFile file = getElement().getContainingFile().getOriginalFile().getVirtualFile();
+ if (file != null) {
+ final VirtualFile contentRoot = fileIndex.getContentRootForFile(file);
+ if (contentRoot != null) {
+ final PsiManager psiManager = PsiManager.getInstance(project);
+ return psiManager.findDirectory(contentRoot);
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ContentRoot.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ContentRoot.java
new file mode 100644
index 0000000..220113d
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ContentRoot.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$C<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+ protected void doTest() {
+ configureByFile(getTestName(true) + ".java");
+ }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ContentRoot_after.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ContentRoot_after.java
new file mode 100644
index 0000000..12ef5ce
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ContentRoot_after.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$CONTENT_ROOT<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+ protected void doTest() {
+ configureByFile(getTestName(true) + ".java");
+ }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ProjectRoot.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ProjectRoot.java
new file mode 100644
index 0000000..2480621
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ProjectRoot.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$P<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+ protected void doTest() {
+ configureByFile(getTestName(true) + ".java");
+ }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ProjectRoot_after.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ProjectRoot_after.java
new file mode 100644
index 0000000..73a9221
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ProjectRoot_after.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$PROJECT_ROOT<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+ protected void doTest() {
+ configureByFile(getTestName(true) + ".java");
+ }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterContentRoot.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterContentRoot.java
new file mode 100644
index 0000000..409e8da
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterContentRoot.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$CONTENT_ROOT/c<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+ protected void doTest() {
+ configureByFile(getTestName(true) + ".java");
+ }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterContentRoot_after.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterContentRoot_after.java
new file mode 100644
index 0000000..a3fff23
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterContentRoot_after.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$CONTENT_ROOT/contentRootSubdir<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+ protected void doTest() {
+ configureByFile(getTestName(true) + ".java");
+ }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterProjectRoot.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterProjectRoot.java
new file mode 100644
index 0000000..397ed2e
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterProjectRoot.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$PROJECT_ROOT/pro<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+ protected void doTest() {
+ configureByFile(getTestName(true) + ".java");
+ }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterProjectRoot_after.java b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterProjectRoot_after.java
new file mode 100644
index 0000000..0e4ed3d4
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/completeTestDataPath/ReferencesAfterProjectRoot_after.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$PROJECT_ROOT/projectSubdir<caret>")
+class ATest extends LightCodeInsightFixtureTestCase {
+ protected void doTest() {
+ configureByFile(getTestName(true) + ".java");
+ }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ContentRootReference.java b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ContentRootReference.java
new file mode 100644
index 0000000..d176a36
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ContentRootReference.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$C<caret>ONTENT_ROOT/path")
+class ATest extends LightCodeInsightFixtureTestCase {
+ protected void doTest() {
+ configureByFile(getTestName(true) + ".java");
+ }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ProjectRootReference.java b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ProjectRootReference.java
new file mode 100644
index 0000000..ccaf4a6
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ProjectRootReference.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$P<caret>ROJECT_ROOT/path")
+class ATest extends LightCodeInsightFixtureTestCase {
+ protected void doTest() {
+ configureByFile(getTestName(true) + ".java");
+ }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ReferencesAfterContentRoot.java b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ReferencesAfterContentRoot.java
new file mode 100644
index 0000000..283cd36
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ReferencesAfterContentRoot.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$CONTENT_ROOT/contentRootSub<caret>dir")
+class ATest extends LightCodeInsightFixtureTestCase {
+ protected void doTest() {
+ configureByFile(getTestName(true) + ".java");
+ }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ReferencesAfterProjectRoot.java b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ReferencesAfterProjectRoot.java
new file mode 100644
index 0000000..f718ad8
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testData/resolveTestDataPath/ReferencesAfterProjectRoot.java
@@ -0,0 +1,6 @@
+@com.intellij.testFramework.TestDataPath("$PROJECT_ROOT/pro<caret>jectSubdir/")
+class ATest extends LightCodeInsightFixtureTestCase {
+ protected void doTest() {
+ configureByFile(getTestName(true) + ".java");
+ }
+}
\ No newline at end of file
diff --git a/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathCompletionTest.java b/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathCompletionTest.java
new file mode 100644
index 0000000..9b0356c
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathCompletionTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.testAssistant;
+
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.testFramework.TestDataPath;
+
+/**
+ * User: zolotov
+ * Date: 9/23/13
+ */
+@TestDataPath("$CONTENT_ROOT/testData/completionTestDataPath")
+public class TestDataPathCompletionTest extends TestDataPathTestCase {
+ public void testProjectRoot() throws Exception {
+ doTest();
+ }
+
+ public void testReferencesAfterProjectRoot() throws Exception {
+ doTest();
+ }
+
+ public void testContentRoot() throws Exception {
+ doTest();
+ }
+
+ public void testReferencesAfterContentRoot() throws Exception {
+ doTest();
+ }
+
+ private void doTest() {
+ myFixture.configureByFile(getTestName(false) + ".java");
+ myFixture.completeBasic();
+ myFixture.checkResultByFile(getTestName(false) + "_after.java");
+ }
+
+ @Override
+ protected String getBasePath() {
+ return PluginPathManager.getPluginHomePathRelative("IdeaTestAssistant") + "/testData/completeTestDataPath";
+ }
+}
diff --git a/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathResolvingTest.java b/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathResolvingTest.java
new file mode 100644
index 0000000..7fbd5aa
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathResolvingTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.testAssistant;
+
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.psi.PsiFileSystemItem;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.PsiReference;
+import com.intellij.testFramework.TestDataPath;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * User: zolotov
+ * Date: 9/23/13
+ */
+@TestDataPath("$CONTENT_ROOT/testData/resolveTestDataPath/")
+public class TestDataPathResolvingTest extends TestDataPathTestCase {
+ public void testProjectRootReference() throws Exception {
+ doTest(PsiManager.getInstance(myFixture.getProject()).findDirectory(myFixture.getProject().getBaseDir()));
+ }
+
+ public void testReferencesAfterProjectRoot() throws Exception {
+ doTest(PsiManager.getInstance(myFixture.getProject()).findDirectory(myProjectSubdir));
+ }
+
+ public void testContentRootReference() throws Exception {
+ doTest(PsiManager.getInstance(myFixture.getProject()).findDirectory(myContentRoot));
+ }
+
+ public void testReferencesAfterContentRoot() throws Exception {
+ doTest(PsiManager.getInstance(myFixture.getProject()).findDirectory(myContentRootSubdir));
+ }
+
+ private void doTest(@Nullable PsiFileSystemItem expectedResolve) {
+ myFixture.configureByFile(getTestName(false) + ".java");
+ final PsiReference referenceAt = myFixture.getFile().findReferenceAt(myFixture.getEditor().getCaretModel().getOffset());
+ assertNotNull(referenceAt);
+ assertEquals(expectedResolve, referenceAt.resolve());
+ }
+
+ @Override
+ protected String getBasePath() {
+ return PluginPathManager.getPluginHomePathRelative("IdeaTestAssistant") + "/testData/resolveTestDataPath";
+ }
+}
diff --git a/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathTestCase.java b/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathTestCase.java
new file mode 100644
index 0000000..864985b
--- /dev/null
+++ b/plugins/IdeaTestAssistant/testSrc/com/intellij/testAssistant/TestDataPathTestCase.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.testAssistant;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
+import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
+
+import java.io.IOException;
+
+/**
+ * User: zolotov
+ * Date: 9/23/13
+ */
+abstract public class TestDataPathTestCase extends JavaCodeInsightFixtureTestCase {
+ protected VirtualFile myContentRoot;
+ protected VirtualFile myContentRootSubdir;
+ protected VirtualFile myProjectSubdir;
+
+ public void setUp() throws Exception {
+ super.setUp();
+ myContentRoot = LocalFileSystem.getInstance().refreshAndFindFileByPath(myFixture.getTempDirPath());
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ myProjectSubdir = myFixture.getProject().getBaseDir().createChildDirectory(this, "projectSubdir");
+ myContentRootSubdir = myContentRoot.createChildDirectory(this, "contentRootSubdir");
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ }
+
+ @Override
+ protected void tuneFixture(JavaModuleFixtureBuilder moduleBuilder) throws Exception {
+ moduleBuilder.addContentRoot(myFixture.getTempDirPath());
+ }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
index 44b5be3..6abd21a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
@@ -1117,6 +1117,10 @@
key="absolute.alignment.in.user.interface.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.internationalization.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.internationalization.AbsoluteAlignmentInUserInterfaceInspection"/>
+ <localInspection language="JAVA" shortName="UnnecessaryUnicodeEscape" bundle="com.siyeh.InspectionGadgetsBundle"
+ key="unnecessary.unicode.escape.display.name" groupBundle="messages.InspectionsBundle"
+ groupKey="group.names.internationalization.issues" enabledByDefault="false" level="WARNING"
+ implementationClass="com.siyeh.ig.internationalization.UnnecessaryUnicodeEscapeInspection"/>
<!--group.names.j2me.issues-->
<localInspection language="JAVA" shortName="AbstractClassWithOnlyOneDirectInheritor" bundle="com.siyeh.InspectionGadgetsBundle"
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
index 90800e4..6dc0cb8 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
@@ -2040,4 +2040,6 @@
boolean.parameters.problem.descriptor='public' method <code>#ref</code> with 'boolean' parameters
boolean.parameter.constructor.problem.descriptor='public' constructor <code>#ref</code> with 'boolean' parameter
boolean.parameters.constructor.problem.descriptor='public' constructor <code>#ref</code> with 'boolean' parameters
-boolean.parameter.only.report.multiple.option=Only report methods with multiple boolean parameters
\ No newline at end of file
+boolean.parameter.only.report.multiple.option=Only report methods with multiple boolean parameters
+unnecessary.unicode.escape.display.name=Unnecessary unicode escape sequence
+unnecessary.unicode.escape.problem.descriptor=Unicode escape sequence <code>#ref</code> can be replaced with ''{0}''
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspection.java
index 8a592c0..8461b1a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,60 +60,76 @@
final PsiParameter[] parameters = parameterList.getParameters();
final PsiParameter parameter = parameters[0];
final PsiCodeBlock body = method.getBody();
- if (body == null) {
- return;
- }
- if (isParameterChecked(body, parameter)) {
- return;
- }
- if (isParameterCheckNotNeeded(body)) {
+ if (body == null || isParameterChecked(body, parameter) || isParameterCheckNotNeeded(body, parameter)) {
return;
}
registerMethodError(method);
}
- private static boolean isParameterCheckNotNeeded(PsiCodeBlock body) {
- final PsiStatement[] statements = body.getStatements();
- if (statements.length == 0) {
- return true;
- }
- if (statements.length != 1) {
- return false;
- }
- final PsiStatement statement = statements[0];
- if (!(statement instanceof PsiReturnStatement)) {
- return false;
- }
- final PsiReturnStatement returnStatement = (PsiReturnStatement)statement;
- final PsiExpression returnValue = returnStatement.getReturnValue();
- final Object constant = ExpressionUtils.computeConstantExpression(returnValue);
- return Boolean.FALSE.equals(constant);
- }
-
private static boolean isParameterChecked(PsiCodeBlock body, PsiParameter parameter) {
- if (usesEqualsBuilderReflectionEquals(body)) {
- return true;
- }
final ParameterClassCheckVisitor visitor = new ParameterClassCheckVisitor(parameter);
body.accept(visitor);
return visitor.isChecked();
}
- private static boolean usesEqualsBuilderReflectionEquals(PsiCodeBlock body) {
+ private static boolean isParameterCheckNotNeeded(PsiCodeBlock body, PsiParameter parameter) {
final PsiStatement[] statements = body.getStatements();
+ if (statements.length == 0) {
+ return true; // incomplete code
+ }
if (statements.length != 1) {
return false;
}
final PsiStatement statement = statements[0];
if (!(statement instanceof PsiReturnStatement)) {
- return false;
+ return true; // incomplete code
}
final PsiReturnStatement returnStatement = (PsiReturnStatement)statement;
final PsiExpression returnValue = returnStatement.getReturnValue();
- if (!(returnValue instanceof PsiMethodCallExpression)) {
+ final Object constant = ExpressionUtils.computeConstantExpression(returnValue);
+ if (Boolean.FALSE.equals(constant)) {
+ return true; // incomplete code
+ }
+ if (isEqualsBuilderReflectionEquals(returnValue)) {
+ return true;
+ }
+ if (isIdentityEquals(returnValue, parameter)) {
+ return true;
+ }
+ return false;
+ }
+
+ private static boolean isIdentityEquals(PsiExpression expression, PsiParameter parameter) {
+ if (!(expression instanceof PsiBinaryExpression)) {
return false;
}
- final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)returnValue;
+ final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)expression;
+ final PsiExpression lhs = binaryExpression.getLOperand();
+ final PsiExpression rhs = binaryExpression.getROperand();
+ return isIdentityEquals(lhs, rhs, parameter) || isIdentityEquals(rhs, lhs, parameter);
+ }
+
+ private static boolean isIdentityEquals(PsiExpression lhs, PsiExpression rhs, PsiParameter parameter) {
+ if (!(lhs instanceof PsiReferenceExpression)) {
+ return false;
+ }
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)lhs;
+ final PsiElement target = referenceExpression.resolve();
+ if (target != parameter) {
+ return false;
+ }
+ if (!(rhs instanceof PsiThisExpression)) {
+ return false;
+ }
+ final PsiThisExpression thisExpression = (PsiThisExpression)rhs;
+ return thisExpression.getQualifier() == null;
+ }
+
+ private static boolean isEqualsBuilderReflectionEquals(PsiExpression expression) {
+ if (!(expression instanceof PsiMethodCallExpression)) {
+ return false;
+ }
+ final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
@NonNls final String referenceName = methodExpression.getReferenceName();
if (!"reflectionEquals".equals(referenceName)) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedRegexInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedRegexInspection.java
index e8e6755..c5c67ce 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedRegexInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedRegexInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,9 +15,10 @@
*/
package com.siyeh.ig.bugs;
-import com.intellij.psi.*;
-import com.intellij.psi.util.ConstantExpressionUtil;
-import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiExpressionList;
+import com.intellij.psi.PsiMethodCallExpression;
+import com.intellij.psi.PsiReferenceExpression;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
@@ -60,29 +61,39 @@
private static class MalformedRegexVisitor extends BaseInspectionVisitor {
@Override
- public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
- super.visitMethodCallExpression(expression);
- final PsiExpressionList argumentList = expression.getArgumentList();
- if (argumentList == null) {
+ public void visitMethodCallExpression(@NotNull PsiMethodCallExpression methodCallExpression) {
+ super.visitMethodCallExpression(methodCallExpression);
+ if (!MethodCallUtils.isCallToRegexMethod(methodCallExpression)) {
return;
}
+ final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
if (arguments.length == 0) {
return;
}
- final PsiExpression argument = arguments[0];
- if (!ExpressionUtils.hasStringType(argument)) {
+ final PsiExpression firstArgument = arguments[0];
+ if (!ExpressionUtils.hasStringType(firstArgument)) {
return;
}
- if (!PsiUtil.isConstantExpression(argument)) {
- return;
- }
- final PsiType regexType = argument.getType();
- final String value = (String)ConstantExpressionUtil.computeCastTo(argument, regexType);
+ final String value = (String)ExpressionUtils.computeConstantExpression(firstArgument);
if (value == null) {
return;
}
- if (!MethodCallUtils.isCallToRegexMethod(expression)) {
+ final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
+ if ("compile".equals(methodExpression.getReferenceName()) && arguments.length == 2) {
+ final PsiExpression secondArgument = arguments[1];
+ final Object flags = ExpressionUtils.computeConstantExpression(secondArgument);
+ if (flags instanceof Integer) {
+ try {
+ Pattern.compile(value, ((Integer)flags).intValue());
+ }
+ catch (PatternSyntaxException e) {
+ registerError(firstArgument, e.getDescription());
+ }
+ catch (NullPointerException e) {
+ registerError(firstArgument);
+ }
+ }
return;
}
//noinspection UnusedCatchParameter,ProhibitedExceptionCaught
@@ -90,10 +101,10 @@
Pattern.compile(value);
}
catch (PatternSyntaxException e) {
- registerError(argument, e.getDescription());
+ registerError(firstArgument, e.getDescription());
}
catch (NullPointerException e) {
- registerError(argument); // due to a bug in the sun regex code
+ registerError(firstArgument); // due to a bug in the sun regex code
}
}
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspectionBase.java
index fe02f96..3a291bd 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspectionBase.java
@@ -36,7 +36,7 @@
@SuppressWarnings({"PublicField"})
public final ExternalizableStringSet updateNames =
new ExternalizableStringSet("add", "clear", "drainTo", "insert", "load", "offer", "poll", "push", "put", "remove", "replace",
- "retain", "set", "take");
+ "retain", "set", "take", "compute");
private static boolean isEmptyCollectionInitializer(PsiExpression initializer) {
if (!(initializer instanceof PsiNewExpression)) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java
index 435dd24..550374f 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -140,7 +140,7 @@
@Override
public void visitVariable(@NotNull PsiVariable variable) {
super.visitVariable(variable);
- if (!(variable instanceof PsiLocalVariable)) {
+ if (!(variable instanceof PsiLocalVariable) || variable instanceof PsiResourceVariable) {
return;
}
final PsiExpression initializer = variable.getInitializer();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspection.java
new file mode 100644
index 0000000..4e0176e
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspection.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.internationalization;
+
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.lang.injection.InjectedLanguageManager;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.InspectionGadgetsFix;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.*;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class UnnecessaryUnicodeEscapeInspection extends BaseInspection {
+ @Nls
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return InspectionGadgetsBundle.message("unnecessary.unicode.escape.display.name");
+ }
+
+ @NotNull
+ @Override
+ protected String buildErrorString(Object... infos) {
+ final Character c = (Character)infos[0];
+ return InspectionGadgetsBundle.message("unnecessary.unicode.escape.problem.descriptor", c);
+ }
+
+ @Nullable
+ @Override
+ protected InspectionGadgetsFix buildFix(Object... infos) {
+ return new UnnecessaryUnicodeEscapeFix(((Character) infos[0]).charValue());
+ }
+
+ private static class UnnecessaryUnicodeEscapeFix extends InspectionGadgetsFix {
+
+ private final char c;
+
+ public UnnecessaryUnicodeEscapeFix(char c) {
+ this.c = c;
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return "Replace with '" + c + "'";
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace with character";
+ }
+
+ @Override
+ protected void doFix(Project project, ProblemDescriptor descriptor) {
+ final TextRange textRange = descriptor.getTextRangeInElement();
+ final PsiElement element = descriptor.getPsiElement();
+ if (!(element instanceof PsiFile)) {
+ return;
+ }
+ final PsiFile file = (PsiFile)element;
+ final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
+ if (document == null) {
+ return;
+ }
+ document.replaceString(textRange.getStartOffset(), textRange.getEndOffset(), String.valueOf(c));
+ }
+ }
+
+ @Override
+ public BaseInspectionVisitor buildVisitor() {
+ return new UnnecessaryUnicodeEscapeVisitor();
+ }
+
+ private static class UnnecessaryUnicodeEscapeVisitor extends BaseInspectionVisitor {
+
+ @Override
+ public void visitFile(PsiFile file) {
+ super.visitFile(file);
+ if (InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file) || !file.isPhysical()) {
+ return;
+ }
+ final VirtualFile virtualFile = file.getVirtualFile();
+ final String text = file.getText();
+ final Charset charset = LoadTextUtil.extractCharsetFromFileContent(file.getProject(), virtualFile, text);
+ final CharsetEncoder encoder = charset.newEncoder().onUnmappableCharacter(CodingErrorAction.REPORT);
+ final CharBuffer charBuffer = CharBuffer.allocate(1);
+ final ByteBuffer byteBuffer = ByteBuffer.allocate(10);
+ final int length = text.length();
+ for (int i = 0; i < length; i++) {
+ final char c = text.charAt(i);
+ if (c != '\\') {
+ continue;
+ }
+ boolean isEscape = true;
+ int previousChar = i - 1;
+ while (previousChar >= 0 && text.charAt(previousChar) == '\\') {
+ isEscape = !isEscape;
+ previousChar--;
+ }
+ if (!isEscape) {
+ continue;
+ }
+ int nextChar = i;
+ do {
+ nextChar++;
+ if (nextChar >= length) {
+ break;
+ }
+ }
+ while (text.charAt(nextChar) == 'u'); // \uuuu0061 is a legal unicode escape
+ if (nextChar == i + 1 || nextChar + 3 >= length) {
+ continue;
+ }
+ if (StringUtil.isHexDigit(text.charAt(nextChar)) &&
+ StringUtil.isHexDigit(text.charAt(nextChar + 1)) &&
+ StringUtil.isHexDigit(text.charAt(nextChar + 2)) &&
+ StringUtil.isHexDigit(text.charAt(nextChar + 3))) {
+ final int escapeEnd = nextChar + 4;
+ final char d = (char)Integer.parseInt(text.substring(nextChar, escapeEnd), 16);
+ if (Character.isISOControl(d)) {
+ continue;
+ }
+ byteBuffer.clear();
+ charBuffer.clear();
+ charBuffer.put(d).rewind();
+ final CoderResult coderResult = encoder.encode(charBuffer, byteBuffer, true);
+ if (!coderResult.isUnmappable()) {
+ registerErrorAtOffset(file, i, escapeEnd - i, Character.valueOf(d));
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/HtmlTagCanBeJavadocTagInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/HtmlTagCanBeJavadocTagInspection.java
index f8dace6..e6d4648 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/HtmlTagCanBeJavadocTagInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/HtmlTagCanBeJavadocTagInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2012 Bas Leijdekkers
+ * Copyright 2011-2013 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,12 +16,13 @@
package com.siyeh.ig.javadoc;
import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
import com.intellij.psi.JavaDocTokenType;
-import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiElementFactory;
-import com.intellij.psi.javadoc.PsiDocComment;
+import com.intellij.psi.PsiFile;
import com.intellij.psi.javadoc.PsiDocToken;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
@@ -52,23 +53,15 @@
@Override
protected InspectionGadgetsFix buildFix(Object... infos) {
- final int offset = ((Integer)infos[0]).intValue();
- return new HtmlTagCanBeJavaDocTagFix(offset);
+ return new HtmlTagCanBeJavaDocTagFix();
}
private static class HtmlTagCanBeJavaDocTagFix extends InspectionGadgetsFix {
- private final int startIndex;
-
- public HtmlTagCanBeJavaDocTagFix(int startIndex) {
- this.startIndex = startIndex;
- }
-
@Override
@NotNull
public String getName() {
- return InspectionGadgetsBundle.message(
- "html.tag.can.be.javadoc.tag.quickfix");
+ return InspectionGadgetsBundle.message("html.tag.can.be.javadoc.tag.quickfix");
}
@Override
@NotNull
@@ -78,60 +71,55 @@
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
- final PsiElement element = descriptor.getPsiElement();
- final PsiDocComment comment = PsiTreeUtil.getParentOfType(element, PsiDocComment.class);
- if (comment == null) {
+ final TextRange range = descriptor.getTextRangeInElement();
+ PsiElement element = descriptor.getPsiElement();
+ final PsiFile file = PsiTreeUtil.getParentOfType(element, PsiFile.class);
+ if (file == null) {
return;
}
- @NonNls final StringBuilder newCommentText = new StringBuilder();
- buildNewCommentText(comment, element, false, newCommentText);
- final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
- final PsiDocComment newComment = factory.createDocCommentFromText(newCommentText.toString());
- comment.replace(newComment);
+ final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
+ if (document == null) {
+ return;
+ }
+ final int startOffset = range.getStartOffset();
+ final int replaceStartOffset = element.getTextOffset() + startOffset;
+ final int endOffset = range.getEndOffset();
+ @NonNls String text = element.getText();
+ if (!"<code>".equals(text.substring(startOffset, endOffset))) {
+ return;
+ }
+ @NonNls final StringBuilder newCommentText = new StringBuilder("{@code");
+ int endTag = text.indexOf("</code>", startOffset);
+ boolean first = true;
+ while (endTag < 0) {
+ appendElementText(text, endOffset, text.length(), first, newCommentText);
+ first = false;
+ element = element.getNextSibling();
+ if (element == null) return;
+ text = element.getText();
+ endTag = text.indexOf("</code>");
+ }
+ appendElementText(text, endOffset, endTag, first, newCommentText);
+ newCommentText.append('}');
+ final int replaceEndOffset = element.getTextOffset() + endTag + 7;
+ final String oldText = document.getText(new TextRange(replaceStartOffset, replaceEndOffset));
+ if (!oldText.startsWith("<code>") || !oldText.endsWith("</code>")) { // sanity check
+ return;
+ }
+ document.replaceString(replaceStartOffset, replaceEndOffset, newCommentText);
}
- private boolean buildNewCommentText(PsiElement element, PsiElement elementToReplace, boolean missingEndTag,
- @NonNls StringBuilder newCommentText) {
- final PsiElement[] children = element.getChildren();
- if (children.length != 0) {
- for (PsiElement child : children) {
- missingEndTag = buildNewCommentText(child, elementToReplace, missingEndTag, newCommentText);
+ private static void appendElementText(String text, int startOffset, int endOffset, boolean first, StringBuilder out) {
+ if (first) {
+ final String substring = text.substring(startOffset, endOffset);
+ if (!substring.isEmpty() && !Character.isWhitespace(substring.charAt(0))) {
+ out.append(' ');
}
- return missingEndTag;
- }
- @NonNls final String text = element.getText();
- if (element != elementToReplace) {
- if (missingEndTag) {
- final int endIndex = text.indexOf("</code>");
- if (endIndex >= 0) {
- final String codeText = text.substring(0, endIndex);
- newCommentText.append(codeText);
- newCommentText.append('}');
- newCommentText.append(text.substring(endIndex + 7));
- return false;
- }
- }
- newCommentText.append(text);
+ out.append(substring);
}
else {
- newCommentText.append(text.substring(0, startIndex));
- newCommentText.append("{@code ");
- final int endIndex = text.indexOf("</code>", startIndex);
- if (endIndex >= 0) {
- final String codeText = text.substring(startIndex + 6, endIndex);
- newCommentText.append(codeText);
- //StringUtil.replace(codeText, "}", "}"));
- newCommentText.append('}');
- newCommentText.append(text.substring(endIndex + 7));
- }
- else {
- final String codeText = text.substring(startIndex + 6);
- newCommentText.append(codeText);
- //StringUtil.replace(codeText, "}", "}"));
- return true;
- }
+ out.append(text.substring(0, endOffset));
}
- return missingEndTag;
}
}
@@ -160,14 +148,14 @@
return;
}
if (hasMatchingCloseTag(token, startIndex + 6)) {
- registerErrorAtOffset(token, startIndex, 6, Integer.valueOf(startIndex));
+ registerErrorAtOffset(token, startIndex, 6);
}
startIndex++;
}
}
private static boolean hasMatchingCloseTag(PsiElement element, int offset) {
- final String text = element.getText();
+ @NonNls final String text = element.getText();
final int endOffset1 = text.indexOf("</code>", offset);
if (endOffset1 >= 0) {
final int startOffset1 = text.indexOf("<code>", offset);
@@ -175,7 +163,7 @@
}
PsiElement sibling = element.getNextSibling();
while (sibling != null) {
- final String text1 = sibling.getText();
+ @NonNls final String text1 = sibling.getText();
final int endOffset = text1.indexOf("</code>");
if (endOffset >= 0) {
final int startOffset = text1.indexOf("<code>");
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java
index 0de37c8..257ab04 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-201@ Bas Leijdekkers
+ * Copyright 2006-2013 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package com.siyeh.ig.style;
import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
@@ -60,11 +61,6 @@
if (parameterList == null) {
return;
}
- if (parameterList.getTypeArguments().length > 0) {
- // optimization: reference with type arguments are
- // definitely not references to fields.
- return;
- }
final PsiElement element = expression.resolve();
if (!(element instanceof PsiField)) {
return;
@@ -73,9 +69,13 @@
if (field.hasModifierProperty(PsiModifier.STATIC)) {
return;
}
- final PsiClass containingClass = field.getContainingClass();
- if (containingClass instanceof PsiAnonymousClass) {
- return;
+ final PsiClass fieldClass = field.getContainingClass();
+ if (fieldClass instanceof PsiAnonymousClass) {
+ final PsiClass expressionClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class);
+ if (expressionClass != null && !expressionClass.equals(fieldClass)) {
+ // qualified this expression not possible for anonymous class
+ return;
+ }
}
registerError(expression);
}
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnicodeEscape.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnicodeEscape.html
new file mode 100644
index 0000000..0cb8778
--- /dev/null
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnicodeEscape.html
@@ -0,0 +1,9 @@
+<html>
+<body>
+Reports unicode escape sequences that are unnecessary, i.e. the file's encoding can handle the character without escaping it.
+Unicode control characters are not reported by this inspection.
+ <!-- tooltip end -->
+<p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/javadoc/html_tag_can_be_javadoc_tag/Second.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/javadoc/html_tag_can_be_javadoc_tag/Second.after.java
index 1added5..8d13805 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igfixes/javadoc/html_tag_can_be_javadoc_tag/Second.after.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/javadoc/html_tag_can_be_javadoc_tag/Second.after.java
@@ -3,7 +3,7 @@
class Second {
/**
- * <code></code>{@code }
+ * <code></code>{@code}
*/
void foo2() {}
}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java
index c7519ff..bf0af06 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java
@@ -96,3 +96,9 @@
return ((Child)o).childField.equals(childField);
}
}
+class Six {
+ @Override
+ public boolean equals(Object obj) {
+ return this == obj;
+ }
+}
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_regex/MalformedRegex.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_regex/MalformedRegex.java
new file mode 100644
index 0000000..9783f8f
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_regex/MalformedRegex.java
@@ -0,0 +1,12 @@
+import java.util.regex.Pattern;
+
+class MalformedRegex {
+ Pattern BACKSLASH_PATTERN = Pattern.compile("<error descr="Illegal/unsupported escape sequence">\</error>\" , Pattern.LITERAL);
+
+ private static final String ASTERISK = "<error descr="Dangling metacharacter">*</error>";
+
+ public void foo() {
+ "bar".matches(".*");
+ Pattern.compile(<warning descr="Regular expression 'ASTERISK' is malformed: Dangling meta character '*'">ASTERISK</warning>);
+ }
+}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java
index 529592f..8302df83 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java
@@ -109,4 +109,12 @@
System.out.println(i);
}
}
+
+ void resourceVariable(boolean b) {
+ try (AutoCloseable ac = null) {
+ if (b) {
+ System.out.println(ac);
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/unnecessary_unicode_escape/UnnecessaryUnicodeEscape.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/unnecessary_unicode_escape/UnnecessaryUnicodeEscape.java
new file mode 100644
index 0000000..b258b17
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/unnecessary_unicode_escape/UnnecessaryUnicodeEscape.java
@@ -0,0 +1,6 @@
+package com.siyeh.igtest.internationalization.unnecessary_unicode_escape;
+
+class UnnecessaryUnicodeEscape {
+ // <warning descr="Unicode escape sequence '\uuuuuu0061' can be replaced with 'a'">\uuuuuu0061</warning><warning descr="Unicode escape sequence '\u0062' can be replaced with 'b'">\u0062</warning>
+ // control char & not representable char: \u0010 \u00e4
+}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java
index 6c7518d..ac24026 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java
@@ -22,4 +22,14 @@
}
};
}
+
+ void simpleAnonymous() {
+ new Object() {
+ String s;
+
+ void foo() {
+ System.out.println(s);
+ }
+ };
+ }
}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/expected.xml
index f13588a..aa352ac 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/expected.xml
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/expected.xml
@@ -7,11 +7,17 @@
<description>Instance field access <code>field</code> is not qualified with 'this' #loc</description>
</problem>
-
<problem>
<file>UnqualifiedFieldAccess.java</file>
<line>9</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Instance field access not qualified with 'this'</problem_class>
<description>Instance field access <code>field</code> is not qualified with 'this' #loc</description>
</problem>
+
+ <problem>
+ <file>UnqualifiedFieldAccess.java</file>
+ <line>31</line>
+ <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Instance field access not qualified with 'this'</problem_class>
+ <description>Instance field access <code>s</code> is not qualified with 'this' #loc</description>
+ </problem>
</problems>
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java
index 6f56e02..e045e8a 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java
@@ -79,4 +79,46 @@
myFixture.configureByText("X.java", newText.toString());
myFixture.testHighlighting(true, false, false);
}
+
+ @Override
+ protected String getBasePath() {
+ final Class<? extends LocalInspectionTool> inspectionClass = getInspection().getClass();
+ final String className = inspectionClass.getName();
+ final String[] words = className.split("\\.");
+ @NonNls final StringBuilder basePath = new StringBuilder("/plugins/InspectionGadgets/test/");
+ final int lastWordIndex = words.length - 1;
+ for (int i = 0; i < lastWordIndex; i++) {
+ final String word = words[i];
+ if (word.equals("ig")) {
+ basePath.append("igtest");
+ }
+ else {
+ basePath.append(word);
+ }
+ basePath.append('/');
+ }
+ String lastWord = words[lastWordIndex];
+ if (lastWord.endsWith("Inspection")) {
+ lastWord = lastWord.substring(0, lastWord.length() - 10);
+ }
+ final int length = lastWord.length();
+ for (int i = 0; i < length; i++) {
+ final char ch = lastWord.charAt(i);
+ if (Character.isUpperCase(ch)) {
+ if (i != 0) {
+ basePath.append('_');
+ }
+ basePath.append(Character.toLowerCase(ch));
+ }
+ else {
+ basePath.append(ch);
+ }
+ }
+ return basePath.toString();
+ }
+
+ protected final void doTest() {
+ myFixture.configureByFile(getTestName(false) + ".java");
+ myFixture.testHighlighting(true, false, false);
+ }
}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedRegexInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedRegexInspectionTest.java
new file mode 100644
index 0000000..68a1a06
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedRegexInspectionTest.java
@@ -0,0 +1,39 @@
+/**
+ * (c) 2013 Desert Island BV
+ * created: 20 09 2013
+ */
+package com.siyeh.ig.bugs;
+
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.siyeh.ig.LightInspectionTestCase;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class MalformedRegexInspectionTest extends LightInspectionTestCase {
+
+ public void testMalformedRegex() {
+ doTest();
+ }
+
+ @Override
+ protected LocalInspectionTool getInspection() {
+ return new MalformedRegexInspection();
+ }
+
+ @Override
+ protected String[] getEnvironmentClasses() {
+ return new String[] {
+ "package java.util.regex;" +
+ "public class Pattern {" +
+ " public static final int LITERAL = 0x10;" +
+ " public static Pattern compile(String regex) {" +
+ " return null;" +
+ " }" +
+ " public static Pattern compile(String regex, int flags) {" +
+ " return null;" +
+ " }" +
+ "}"
+ };
+ }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspectionTest.java
new file mode 100644
index 0000000..7079c5f
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/internationalization/UnnecessaryUnicodeEscapeInspectionTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * (c) 2013 Desert Island BV
+ * created: 23 09 2013
+ */
+package com.siyeh.ig.internationalization;
+
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.encoding.EncodingManager;
+import com.siyeh.ig.LightInspectionTestCase;
+
+import java.nio.charset.Charset;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class UnnecessaryUnicodeEscapeInspectionTest extends LightInspectionTestCase {
+
+ public void testUnnecessaryUnicodeEscape() {
+ myFixture.configureByFile(getTestName(false) + ".java");
+ final VirtualFile vFile = myFixture.getFile().getVirtualFile();
+ Charset ascii = CharsetToolkit.forName("US-ASCII");
+ EncodingManager.getInstance().setEncoding(vFile, ascii);
+ assertEquals(ascii, vFile.getCharset());
+ myFixture.testHighlighting(true, false, false);
+ }
+
+ @Override
+ protected LocalInspectionTool getInspection() {
+ return new UnnecessaryUnicodeEscapeInspection();
+ }
+}
diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/AdvancedSettingsUI.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/AdvancedSettingsUI.java
index 887107e..e9083b06 100644
--- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/AdvancedSettingsUI.java
+++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/AdvancedSettingsUI.java
@@ -20,8 +20,8 @@
import com.intellij.ide.util.TreeClassChooser;
import com.intellij.ide.util.TreeClassChooserFactory;
import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
@@ -31,6 +31,7 @@
import org.intellij.plugins.intelliLang.util.PsiUtilEx;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -41,7 +42,7 @@
/**
* @author Gregory.Shrago
*/
-public class AdvancedSettingsUI implements Configurable {
+public class AdvancedSettingsUI implements SearchableConfigurable {
private final Configuration.AdvancedConfiguration myConfiguration;
@SuppressWarnings({"UnusedDeclaration", "FieldCanBeLocal"})
@@ -214,6 +215,18 @@
return "reference.settings.injection.advanced";
}
+ @NotNull
+ @Override
+ public String getId() {
+ return "IntelliLang.Advanced";
+ }
+
+ @Nullable
+ @Override
+ public Runnable enableSearch(String option) {
+ return null;
+ }
+
private static class BrowseClassListener implements ActionListener {
private final Project myProject;
private final ReferenceEditorWithBrowseButton myField;
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 0d6a2be..bc54939 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java
@@ -192,8 +192,10 @@
JBPopup popup = new PopupChooserBuilder(list).setItemChoosenCallback(new Runnable() {
public void run() {
Injectable value = (Injectable)list.getSelectedValue();
- onChosen.process(value);
- PropertiesComponent.getInstance().setValue(LAST_INJECTED_LANGUAGE, value.getId());
+ if (value != null) {
+ onChosen.process(value);
+ PropertiesComponent.getInstance().setValue(LAST_INJECTED_LANGUAGE, value.getId());
+ }
}
}).setFilteringEnabled(new Function<Object, String>() {
@Override
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java
index d921a2b0..b6eee7d 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java
@@ -88,6 +88,10 @@
* see JLS 3.3. Unicode Escapes
*/
private static int indexOfUnicodeEscape(String text, int offset) {
+ if (text == null) {
+ // apparently an editor can have a selection, but still null for selected text.
+ return -1;
+ }
final int length = text.length();
for (int i = 0; i < length; i++) {
final char c = text.charAt(i);
@@ -111,7 +115,7 @@
}
}
while (text.charAt(nextChar) == 'u'); // \uuuu0061 is a legal unicode escape
- if (nextChar + 3 >= length) {
+ if (nextChar == i + 1 || nextChar + 3 >= length) {
break;
}
if (StringUtil.isHexDigit(text.charAt(nextChar)) &&
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/CyclicInference_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/CyclicInference_after.java
new file mode 100644
index 0000000..dfa25f3
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/CyclicInference_after.java
@@ -0,0 +1,18 @@
+class Test2 {
+ class Y<T>{}
+
+ interface I<X> {
+ X foo(Y<X> list);
+ }
+
+ static <T> I<T> bar(I<T> i){return i;}
+
+ {
+ bar(new I() {
+ @Override
+ public Object foo(Y x) {
+ <selection>return x;</selection>
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/unicode/unescape/U.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/unicode/unescape/U.java
new file mode 100644
index 0000000..9b64522
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/unicode/unescape/U.java
@@ -0,0 +1,3 @@
+class U {{
+ // <caret>\0183
+}}
\ No newline at end of file
diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntentionTest.java
index 09f7f44..21841d1 100644
--- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntentionTest.java
+++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntentionTest.java
@@ -44,7 +44,7 @@
}
public void testCyclicInference() {
- assertIntentionNotAvailable();
+ doTest();
}
public void testNoFunctionalInterfaceFound() {
diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/unicode/UnicodeUnescapeIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/unicode/UnicodeUnescapeIntentionTest.java
index b474566..e5d8eff 100644
--- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/unicode/UnicodeUnescapeIntentionTest.java
+++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/unicode/UnicodeUnescapeIntentionTest.java
@@ -9,8 +9,9 @@
public class UnicodeUnescapeIntentionTest extends IPPTestCase {
public void testSimple() { doTest(); }
- public void testNoException() { assertIntentionNotAvailable(); }
public void testSelection() { doTest(); }
+ public void testNoException() { assertIntentionNotAvailable(); }
+ public void testU() { assertIntentionNotAvailable(); }
@Override
protected String getRelativePath() {
diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/AntBuildMessageView.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntBuildMessageView.java
index ca8f376..47f23f5 100644
--- a/plugins/ant/src/com/intellij/lang/ant/config/execution/AntBuildMessageView.java
+++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntBuildMessageView.java
@@ -287,7 +287,7 @@
new CloseListener(content, ijMessageView.getContentManager(), project);
// Do not inline next two variabled. Seeking for NPE.
ToolWindow messageToolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.MESSAGES_WINDOW);
- messageToolWindow.activate(null);
+ messageToolWindow.activate(null, false);
return messageView;
}
diff --git a/plugins/devkit/jps-plugin/src/org/jetbrains/jps/devkit/model/JpsPluginModuleType.java b/plugins/devkit/jps-plugin/src/org/jetbrains/jps/devkit/model/JpsPluginModuleType.java
index 2cc4166..296fd24 100644
--- a/plugins/devkit/jps-plugin/src/org/jetbrains/jps/devkit/model/JpsPluginModuleType.java
+++ b/plugins/devkit/jps-plugin/src/org/jetbrains/jps/devkit/model/JpsPluginModuleType.java
@@ -16,12 +16,13 @@
package org.jetbrains.jps.devkit.model;
import org.jetbrains.jps.model.JpsSimpleElement;
+import org.jetbrains.jps.model.ex.JpsElementTypeBase;
import org.jetbrains.jps.model.module.JpsModuleType;
/**
* @author nik
*/
-public class JpsPluginModuleType extends JpsModuleType<JpsSimpleElement<JpsPluginModuleProperties>> {
+public class JpsPluginModuleType extends JpsElementTypeBase<JpsSimpleElement<JpsPluginModuleProperties>> implements JpsModuleType<JpsSimpleElement<JpsPluginModuleProperties>> {
public static final JpsPluginModuleType INSTANCE = new JpsPluginModuleType();
}
diff --git a/plugins/devkit/src/build/PluginModuleBuildConfEditor.java b/plugins/devkit/src/build/PluginModuleBuildConfEditor.java
index 64e63d5..3e5a614 100644
--- a/plugins/devkit/src/build/PluginModuleBuildConfEditor.java
+++ b/plugins/devkit/src/build/PluginModuleBuildConfEditor.java
@@ -102,13 +102,10 @@
if (myUseUserManifest.isSelected() && myManifest.getText() != null && !new File(myManifest.getText()).exists()){
throw new ConfigurationException(DevKitBundle.message("error.file.not.found.message", myManifest.getText()));
}
- final File plugin = myBuildProperties.getPluginXmlPath() != null ? new File(myBuildProperties.getPluginXmlPath()) : null;
+ final File plugin = new File(myBuildProperties.getPluginXmlPath());
final String newPluginPath = myPluginXML.getText() + File.separator + META_INF + File.separator + PLUGIN_XML;
- if (plugin != null &&
- plugin.exists() &&
- !plugin.getPath().equals(newPluginPath) &&
- Messages.showYesNoDialog(myModule.getProject(),
- DevKitBundle.message("deployment.view.delete", plugin.getPath()),
+ if (plugin.exists() && !plugin.getPath().equals(newPluginPath) &&
+ Messages.showYesNoDialog(myModule.getProject(), DevKitBundle.message("deployment.view.delete", plugin.getPath()),
DevKitBundle.message("deployment.cleanup", META_INF), null) == DialogWrapper.OK_EXIT_CODE) {
CommandProcessor.getInstance().executeCommand(myModule.getProject(),
diff --git a/plugins/devkit/testSources/PluginProjectWizardTest.java b/plugins/devkit/testSources/PluginProjectWizardTest.java
index 6331769..603110a 100644
--- a/plugins/devkit/testSources/PluginProjectWizardTest.java
+++ b/plugins/devkit/testSources/PluginProjectWizardTest.java
@@ -19,7 +19,7 @@
import com.intellij.ide.projectWizard.ProjectWizardTestCase;
import com.intellij.openapi.module.JavaModuleType;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.idea.devkit.module.PluginModuleType;
import org.jetbrains.idea.devkit.projectRoots.IdeaJdk;
@@ -34,7 +34,7 @@
createSdk("devkit", IdeaJdk.getInstance());
Project project = createProjectFromTemplate(JavaModuleType.JAVA_GROUP, PluginModuleType.getInstance().getName(), null);
VirtualFile baseDir = project.getBaseDir();
- VirtualFile virtualFile = VfsUtil.findRelativeFile("META-INF/plugin.xml", baseDir);
+ VirtualFile virtualFile = VfsUtilCore.findRelativeFile("META-INF/plugin.xml", baseDir);
assertNotNull(virtualFile);
}
diff --git a/plugins/eclipse/resources/META-INF/plugin.xml b/plugins/eclipse/resources/META-INF/plugin.xml
index a17e668..5145ea5 100644
--- a/plugins/eclipse/resources/META-INF/plugin.xml
+++ b/plugins/eclipse/resources/META-INF/plugin.xml
@@ -13,6 +13,10 @@
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
<fileTypeFactory implementation="org.jetbrains.idea.eclipse.config.EclipseFileTypeFactory"/>
<syntaxHighlighter key="Eclipse" implementationClass="com.intellij.ide.highlighter.XmlFileHighlighter"/>
+ <schemeImporter
+ name="Eclpse XML Profile"
+ implementationClass="org.jetbrains.idea.eclipse.importer.EclipseCodeStyleSchemeImporter"
+ schemeClass="com.intellij.psi.codeStyle.CodeStyleScheme"/>
</extensions>
<module-components>
<component>
diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseCodeStyleSchemeImporter.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseCodeStyleSchemeImporter.java
new file mode 100644
index 0000000..c3d99b9
--- /dev/null
+++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseCodeStyleSchemeImporter.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.eclipse.importer;
+
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
+import com.intellij.openapi.options.SchemeImportException;
+import com.intellij.openapi.options.SchemeImporter;
+import com.intellij.psi.codeStyle.CodeStyleScheme;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Rustam Vishnyakov
+ */
+public class EclipseCodeStyleSchemeImporter implements SchemeImporter<CodeStyleScheme>, EclipseXmlProfileElements {
+
+ private static final Logger LOG = Logger.getInstance("#" + EclipseCodeStyleSchemeImporter.class.getName());
+
+ private final static String PROGRAMMATIC_IMPORT_KEY = "<Programmatic>";
+
+ private final EclipseImportMap myImportMap;
+
+ public EclipseCodeStyleSchemeImporter() {
+ myImportMap = new EclipseImportMap();
+ myImportMap.load();
+ }
+
+ @Override
+ public String getSourceExtension() {
+ return "xml";
+ }
+
+ @NotNull
+ @Override
+ public String[] readSchemeNames(@NotNull InputStream inputStream) throws SchemeImportException {
+ final Set<String> names = new HashSet<String>();
+ EclipseXmlProfileReader reader = new EclipseXmlProfileReader(new EclipseXmlProfileReader.OptionHandler() {
+ @Override
+ public void handleOption(@NotNull String eclipseKey, @NotNull String value) throws SchemeImportException {
+ // Ignore
+ }
+ @Override
+ public void handleName(String name) {
+ names.add(name);
+ }
+ });
+ reader.readSettings(inputStream);
+ return ArrayUtil.toStringArray(names);
+ }
+
+ @Override
+ public void importScheme(@NotNull InputStream inputStream, final @Nullable String sourceScheme, final CodeStyleScheme scheme)
+ throws SchemeImportException {
+ final CodeStyleSettings settings = scheme.getCodeStyleSettings();
+ EclipseXmlProfileReader reader = new EclipseXmlProfileReader(new EclipseXmlProfileReader.OptionHandler() {
+ private String myCurrScheme;
+
+ @Override
+ public void handleOption(@NotNull String eclipseKey, @NotNull String value) throws SchemeImportException {
+ if (sourceScheme == null || myCurrScheme != null && myCurrScheme.equals(sourceScheme)) {
+ setCodeStyleOption(settings, eclipseKey, value);
+ }
+ }
+ @Override
+ public void handleName(String name) {
+ myCurrScheme = name;
+ }
+ });
+ reader.readSettings(inputStream);
+ }
+
+ private void setCodeStyleOption(@NotNull CodeStyleSettings settings, @NotNull String key, @NotNull String value)
+ throws SchemeImportException {
+ EclipseImportMap.ImportDescriptor importDescriptor = myImportMap.getImportDescriptor(key);
+ if (importDescriptor != null) {
+ try {
+ if (importDescriptor.isLanguageSpecific()) {
+ CommonCodeStyleSettings languageSettings = settings.getCommonSettings(importDescriptor.getLanguage());
+ if (languageSettings != null) {
+ if (importDescriptor.isIndentOptions()) {
+ CommonCodeStyleSettings.IndentOptions indentOptions = languageSettings.getIndentOptions();
+ if (indentOptions != null) {
+ setValue(indentOptions, key, importDescriptor.getFieldName(), value);
+ }
+ }
+ else {
+ setValue(languageSettings, key, importDescriptor.getFieldName(), value);
+ }
+ }
+ }
+ else {
+ setValue(settings, key, importDescriptor.getFieldName(), value);
+ }
+ }
+ catch (Exception e) {
+ throw new SchemeImportException(e);
+ }
+ }
+ }
+
+ private static void setValue(Object object, String key, String fieldName, String value) throws SchemeImportException {
+ if (PROGRAMMATIC_IMPORT_KEY.equalsIgnoreCase(fieldName)) {
+ setProgrammatically(object, key, value);
+ return;
+ }
+ try {
+ Field targetField = object.getClass().getField(fieldName);
+ Class<?> fieldType = targetField.getType();
+ if (fieldType.isPrimitive()) {
+ if (Boolean.TYPE.equals(fieldType)) {
+ targetField.setBoolean(object, valueToBoolean(key, value));
+ }
+ else if (Integer.TYPE.equals(fieldType)) {
+ targetField.setInt(object, valueToInt(value));
+ }
+ }
+ else if (fieldType.equals(String.class)) {
+ targetField.set(object, value);
+ }
+ }
+ catch (IllegalAccessException e) {
+ LOG.error(e);
+ }
+ catch (NoSuchFieldException e) {
+ LOG.error("Field '" + fieldName + "' does not exist in " + object.getClass().getName(), e);
+ }
+ }
+
+ private static boolean valueToBoolean(@NotNull String key, @NotNull String value) throws SchemeImportException {
+ if (VALUE_INSERT.equals(value) ||
+ VALUE_TRUE.equals(value)) {
+ return true;
+ }
+ if (key.contains("alignment") && value.matches("\\d*")) {
+ return isAlignmentOn(value);
+ }
+ if (!(VALUE_DO_NOT_INSERT.equals(value) ||
+ VALUE_FALSE.equals(value))) {
+ throw new SchemeImportException("Unrecognized boolean value: " + value + ", key: " + key);
+ }
+ return false;
+ }
+
+ private static int valueToInt(@NotNull String value) {
+ if (VALUE_END_OF_LINE.equals(value)) return CommonCodeStyleSettings.END_OF_LINE;
+ if (VALUE_NEXT_LINE.equals(value)) return CommonCodeStyleSettings.NEXT_LINE;
+ if (VALUE_NEXT_LINE_SHIFTED.equals(value)) return CommonCodeStyleSettings.NEXT_LINE_SHIFTED;
+ if (VALUE_NEXT_LINE_IF_WRAPPED.equals(value)) return CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED;
+ return Integer.parseInt(value);
+ }
+
+ private static boolean isAlignmentOn(@NotNull String value) {
+ int packed = valueToInt(value);
+ return (packed & 2) != 0;
+ }
+
+ private static void setProgrammatically(@NotNull Object object, @NotNull String key, @NotNull String value) throws SchemeImportException {
+ if (object instanceof CodeStyleSettings) {
+ CodeStyleSettings settings = (CodeStyleSettings)object;
+ if (OPTION_REMOVE_JAVADOC_BLANK_LINES.equals(key)) {
+ settings.JD_KEEP_EMPTY_LINES = !valueToBoolean(key, value);
+ }
+ else if (OPTION_NEW_LINE_AT_EOF.equals(key)) {
+ EditorSettingsExternalizable editorSettings = EditorSettingsExternalizable.getInstance();
+ editorSettings.setEnsureNewLineAtEOF(valueToBoolean(key, value));
+ }
+ }
+ else if (object instanceof CommonCodeStyleSettings) {
+ CommonCodeStyleSettings commonSettings = (CommonCodeStyleSettings)object;
+ if (OPTION_SPACE_AFTER_BINARY_OPERATOR.equals(key)) {
+ boolean addSpace = valueToBoolean(key, value);
+ commonSettings.SPACE_AROUND_ADDITIVE_OPERATORS =
+ commonSettings.SPACE_AROUND_BITWISE_OPERATORS =
+ commonSettings.SPACE_AROUND_LOGICAL_OPERATORS =
+ commonSettings.SPACE_AROUND_MULTIPLICATIVE_OPERATORS =
+ commonSettings.SPACE_AROUND_RELATIONAL_OPERATORS =
+ commonSettings.SPACE_AROUND_SHIFT_OPERATORS =
+ commonSettings.SPACE_AROUND_EQUALITY_OPERATORS =
+ addSpace;
+ }
+ else if (OPTION_INDENT_CLASS_BODY_DECL.equals(key)) {
+ commonSettings.DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS = !valueToBoolean(key, value);
+ }
+ }
+ else if (object instanceof CommonCodeStyleSettings.IndentOptions) {
+ CommonCodeStyleSettings.IndentOptions indentOptions = (CommonCodeStyleSettings.IndentOptions)object;
+ if (OPTION_TAB_CHAR.equals(key)) {
+ if (TAB_CHAR_TAB.equals(value) || TAB_CHAR_MIXED.equals(value)) {
+ indentOptions.USE_TAB_CHARACTER = true;
+ }
+ else if (TAB_CHAR_SPACE.equals(value)) {
+ indentOptions.USE_TAB_CHARACTER = false;
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.java
new file mode 100644
index 0000000..35dde4d
--- /dev/null
+++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.eclipse.importer;
+
+import com.intellij.openapi.diagnostic.Logger;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * @author Rustam Vishnyakov
+ */
+public class EclipseImportMap {
+ private Properties myProperties;
+ private final static String MAP_PROPERTIES = "EclipseImportMap.properties";
+ private static final Logger LOG = Logger.getInstance("#" + EclipseImportMap.class.getName());
+
+ public EclipseImportMap() {
+ myProperties = new Properties();
+ }
+
+ public void load() {
+ try {
+ InputStream sourceStream = getClass().getResourceAsStream(MAP_PROPERTIES);
+ try {
+ myProperties.load(sourceStream);
+ }
+ finally {
+ sourceStream.close();
+ }
+ }
+ catch (IOException e) {
+ LOG.error(e);
+ }
+ }
+
+ @Nullable
+ public ImportDescriptor getImportDescriptor(String name) {
+ String rawData = myProperties.getProperty(name);
+ if (rawData != null && !rawData.trim().isEmpty()) {
+ if (rawData.contains(":")) {
+ String[] parameters = rawData.split(":");
+ if (parameters.length == 2) {
+ return new ImportDescriptor(parameters[0].trim(), parameters[1].trim());
+ }
+ else if (parameters.length == 3) {
+ boolean indentOptions = "indentOptions".equalsIgnoreCase(parameters[1].trim());
+ return new ImportDescriptor(parameters[0].trim(), parameters[2], indentOptions);
+ }
+ }
+ else {
+ return new ImportDescriptor(rawData.trim());
+ }
+ }
+ return null;
+ }
+
+ public static class ImportDescriptor {
+ private String myLanguage;
+ private String myFieldName;
+ private boolean myIndentOptions;
+
+ public ImportDescriptor(String language, String fieldName, boolean indentOptions) {
+ myLanguage = language;
+ myFieldName = fieldName;
+ myIndentOptions = indentOptions;
+ }
+
+ public ImportDescriptor(String language, String fieldName) {
+ this(language, fieldName, false);
+ }
+
+ public ImportDescriptor(String fieldName) {
+ this(null, fieldName);
+ }
+
+ public String getLanguage() {
+ return myLanguage;
+ }
+
+ public String getFieldName() {
+ return myFieldName;
+ }
+
+ public boolean isIndentOptions() {
+ return myIndentOptions;
+ }
+
+ public boolean isLanguageSpecific() {
+ return myLanguage != null;
+ }
+ }
+}
diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.properties b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.properties
new file mode 100644
index 0000000..e4ac52c
--- /dev/null
+++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.properties
@@ -0,0 +1,289 @@
+# suppress inspection "UnusedProperty" for whole file
+#
+# A set of properties describing a map from Eclipse settings to equivalent Intellij IDEA ones.
+# Property value format:
+# [Language:[IndentOptions:]]OPTION_NAME
+#
+# If Language is omitted, root CodeStyleSettings are used, otherwise CommonCodeStyleSettings for the specified Language.
+# OPTION_NAME = <programmatic> means that the value is set programmatically, probably for many target options at a time.
+#
+
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=Java:SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS
+#org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=
+#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=Java:SPACE_WITHIN_ARRAY_INITIALIZER_BRACES
+#org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=
+#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=Java:ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=Java:SPACE_WITHIN_ANNOTATION_PARENTHESES
+org.eclipse.jdt.core.formatter.blank_lines_before_field=Java:BLANK_LINES_AROUND_FIELD
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=Java:SPACE_WITHIN_WHILE_PARENTHESES
+#org.eclipse.jdt.core.formatter.use_on_off_tags=
+#org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=Java:ELSE_ON_NEW_LINE
+#org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=
+#org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=
+#org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=
+#org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=
+#org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=
+#org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=Java:ALIGN_GROUP_FIELD_DECLARATIONS
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=Java:ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION
+#org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=Java:SPACE_BEFORE_FOR_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=Java:<Programmatic>
+#org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=
+#org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=
+#org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=Java:FINALLY_ON_NEW_LINE
+#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=Java:CATCH_ON_NEW_LINE
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=Java:SPACE_BEFORE_WHILE_PARENTHESES
+org.eclipse.jdt.core.formatter.blank_lines_after_package=Java:BLANK_LINES_AFTER_PACKAGE
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=
+org.eclipse.jdt.core.formatter.continuation_indentation=Java:IndentOptions:CONTINUATION_INDENT_SIZE
+#org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=Java:ALIGN_MULTILINE_PARAMETERS_IN_CALLS
+#org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=
+#org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=
+#org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=
+org.eclipse.jdt.core.formatter.blank_lines_before_package=Java:BLANK_LINES_BEFORE_PACKAGE
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=
+#org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=
+#org.eclipse.jdt.core.formatter.comment.format_line_comments=
+#org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=
+#org.eclipse.jdt.core.formatter.join_wrapped_lines=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=
+#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=Java:SPACE_BEFORE_COMMA
+#org.eclipse.jdt.core.formatter.blank_lines_before_member_type=
+#org.eclipse.jdt.core.formatter.align_type_members_on_columns=
+#org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=Java:SPACE_WITHIN_FOR_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=Java:SPACE_BEFORE_METHOD_PARENTHESES
+#org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=Java:SPACE_WITHIN_SWITCH_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=Java:SPACE_AROUND_UNARY_OPERATOR
+#org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=
+#org.eclipse.jdt.core.formatter.comment.indent_parameter_description=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=Java:SPACE_WITHIN_METHOD_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=Java:SPACE_WITHIN_SWITCH_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=
+#org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=
+#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=
+org.eclipse.jdt.core.formatter.lineSplit=RIGHT_MARGIN
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=Java:SPACE_BEFORE_IF_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=Java:SPACE_WITHIN_BRACKETS
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=Java:SPACE_WITHIN_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaratio n=
+#org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=
+#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=
+org.eclipse.jdt.core.formatter.indentation.size=Java:IndentOptions:INDENT_SIZE
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=Java:SPACE_WITHIN_EMPTY_METHOD_PARENTHESES
+#org.eclipse.jdt.core.formatter.enabling_tag=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=Java:ALIGN_MULTILINE_EXTENDS_LIST
+org.eclipse.jdt.core.formatter.alignment_for_assignment=Java:ALIGN_MULTILINE_ASSIGNMENT
+org.eclipse.jdt.core.formatter.tabulation.char=Java:IndentOptions:<Programmatic>
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=
+#org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=
+#org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=
+#org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=
+org.eclipse.jdt.core.formatter.blank_lines_before_method=Java:BLANK_LINES_AROUND_METHOD
+#org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=
+#org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=
+#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=
+#org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=
+#org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=
+#org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=
+#org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=
+#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=Java:ALIGN_MULTILINE_PARAMETERS_IN_CALLS
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=Java:SPACE_WITHIN_METHOD_CALL_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=Java:SPACE_WITHIN_TRY_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=
+#org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=Java:SPACE_WITHIN_IF_PARENTHESES
+#org.eclipse.jdt.core.formatter.brace_position_for_switch=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=
+#org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=Java:SPACE_AFTER_QUEST
+#org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=Java:SPACE_WITHIN_TRY_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=
+#org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=
+#org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=Java:INDENT_CASE_FROM_SWITCH
+#org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=
+org.eclipse.jdt.core.formatter.brace_position_for_block=Java:BRACE_STYLE
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=Java:METHOD_BRACE_STYLE
+org.eclipse.jdt.core.formatter.compact_else_if=Java:SPECIAL_ELSE_IF_TREATMENT
+#org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=
+#org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=Java:SPACE_WITHIN_BRACKETS
+#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=
+#org.eclipse.jdt.core.formatter.comment.indent_root_tags=
+#org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=
+#org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=Java:SPACE_BEFORE_SWITCH_LBRACE
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=Java:SPACE_BEFORE_COMMA
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=
+org.eclipse.jdt.core.formatter.tabulation.size=Java:IndentOptions:TAB_SIZE
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=Java:ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE
+#org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=
+#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=
+#org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=Java:SPACE_WITHIN_IF_PARENTHESES
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=<Programmatic>
+#org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=Java:SPACE_AROUND_ASSIGNMENT_OPERATORS
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=Java:SPACE_AROUND_ASSIGNMENT_OPERATORS
+#org.eclipse.jdt.core.formatter.indent_empty_lines=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=Java:SPACE_WITHIN_SYNCHRONIZED_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=Java:SPACE_AFTER_TYPE_CAST
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=Java:SPACE_AFTER_COMMA
+#org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=Java:KEEP_BLANK_LINES_IN_CODE
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=Java:SPACE_BEFORE_METHOD_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=Java:SPACE_WITHIN_CATCH_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=Java:SPACE_BEFORE_METHOD_CALL_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=Java:SPACE_WITHIN_BRACKETS
+#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=
+#org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=
+#org.eclipse.jdt.core.compiler.compliance=
+#org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=
+#org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=
+#org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=
+#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=Java:SPACE_WITHIN_CAST_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=Java:SPACE_AROUND_UNARY_OPERATOR
+#org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=
+#org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=
+#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=Java:KEEP_SIMPLE_BLOCKS_IN_ONE_LINE
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=
+#org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=<Programmatic>
+#org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=
+#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=
+#org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=Java:ALIGN_MULTILINE_BINARY_OPERATION
+#org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=
+#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=Java:SPACE_WITHIN_WHILE_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=Java:SPACE_BEFORE_TRY_PARENTHESES
+#org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=
+#org.eclipse.jdt.core.formatter.insert_new_line_after_label=
+#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=
+#org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=Java:SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=Java:WHILE_ON_NEW_LINE
+#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=ENABLE_JAVADOC_FORMATTING
+#org.eclipse.jdt.core.formatter.comment.line_length=
+#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=
+#org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=Java:SPACE_BEFORE_SEMICOLON
+#org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=Java:BLANK_LINES_BEFORE_METHOD_BODY
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=Java:SPACE_BEFORE_COLON
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=Java:<Programmatic>
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=Java:BINARY_OPERATION_SIGN_ON_NEXT_LINE
+#org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=
+#org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=Java:SPACE_WITHIN_SYNCHRONIZED_PARENTHESES
+#org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=
+#org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=
+#org.eclipse.jdt.core.formatter.join_lines_in_comments=
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=Java:SPACE_BEFORE_QUEST
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=
+#org.eclipse.jdt.core.formatter.alignment_for_compact_if=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=
+#org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=
+#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=
+#org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=
+#org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=Java:BLANK_LINES_BEFORE_IMPORTS
+#org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=
+#org.eclipse.jdt.core.formatter.comment.format_html=
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=Java:ALIGN_MULTILINE_THROWS_LIST
+#org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=
+#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=Java:SPACE_AFTER_COLON
+#org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=Java:SPACE_WITHIN_FOR_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=
+#org.eclipse.jdt.core.formatter.comment.format_source_code=
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=Java:SPACE_BEFORE_SYNCHRONIZED_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=Java:ALIGN_MULTILINE_PARAMETERS
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=Java:SPACE_WITHIN_ARRAY_INITIALIZER_BRACES
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=Java:ALIGN_MULTILINE_RESOURCES
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=Java:IndentOptions:SMART_TABS
+#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=
+#org.eclipse.jdt.core.formatter.comment.format_header=
+#org.eclipse.jdt.core.formatter.comment.format_block_comments=
+#org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=
+#org.eclipse.jdt.core.formatter.alignment_for_enum_constants=
+#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=
+#org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=Java:SPACE_WITHIN_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=Java:SPACE_WITHIN_CATCH_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=Java:SPACE_BEFORE_SWITCH_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=Java:SPACE_WITHIN_METHOD_CALL_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=Java:CLASS_BRACE_STYLE
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=Java:SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE
+#org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=Java:SPACE_WITHIN_METHOD_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=Java:SPACE_BEFORE_CATCH_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=Java:SPACE_WITHIN_ANNOTATION_PARENTHESES
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=
+#org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=Java:BLANK_LINES_AFTER_IMPORTS
+#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=
+#org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=
+#org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=Java:KEEP_FIRST_COLUMN_COMMENT
+#org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=
+#org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=
+#org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=Java:KEEP_CONTROL_STATEMENT_IN_ONE_LINE
diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileElements.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileElements.java
new file mode 100644
index 0000000..b30a3a8
--- /dev/null
+++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileElements.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.eclipse.importer;
+
+/**
+ * @author Rustam Vishnyakov
+ */
+@SuppressWarnings("UnusedDeclaration")
+public interface EclipseXmlProfileElements {
+ String PROFILES_TAG = "profiles";
+ String PROFILE_TAG = "profile";
+ String NAME_ATTR = "name";
+ String SETTING_TAG = "setting";
+ String ID_ATTR = "id";
+ String VALUE_ATTR = "value";
+
+ String VALUE_INSERT = "insert";
+ String VALUE_DO_NOT_INSERT = "do not insert";
+ String VALUE_FALSE = "false";
+ String VALUE_TRUE = "true";
+
+ String VALUE_NEXT_LINE = "next_line";
+ String VALUE_NEXT_LINE_SHIFTED = "next_line_shifted";
+ String VALUE_END_OF_LINE = "end_of_line";
+ String VALUE_NEXT_LINE_IF_WRAPPED = "next_line_on_wrap";
+
+ String TAB_CHAR_TAB = "tab";
+ String TAB_CHAR_SPACE = "space";
+ String TAB_CHAR_MIXED = "mixed";
+
+ String OPTION_SPACE_AFTER_BINARY_OPERATOR = "org.eclipse.jdt.core.formatter.insert_space_after_binary_operator";
+ String OPTION_REMOVE_JAVADOC_BLANK_LINES = "org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment";
+ String OPTION_NEW_LINE_AT_EOF = "org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing";
+ String OPTION_INDENT_CLASS_BODY_DECL = "org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header";
+ String OPTION_TAB_CHAR = "org.eclipse.jdt.core.formatter.tabulation.char";
+}
diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileReader.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileReader.java
new file mode 100644
index 0000000..4216e58
--- /dev/null
+++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileReader.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.eclipse.importer;
+
+import com.intellij.openapi.options.SchemeImportException;
+import org.jetbrains.annotations.NotNull;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import java.io.InputStream;
+
+/**
+ * Reads settings from Eclipse XML profile. The actual work is done by an implementor of <code>handleOption()</code> method.
+ *
+ * @author Rustam Vishnyakov
+ */
+public class EclipseXmlProfileReader extends DefaultHandler implements EclipseXmlProfileElements {
+
+ private OptionHandler myOptionHandler;
+
+ protected EclipseXmlProfileReader(OptionHandler optionHandler) {
+ myOptionHandler = optionHandler;
+ }
+
+ /**
+ * Reads either basic profile info (name) or all the settings depending on whether <code>settings</code> parameter is null.
+ *
+ * @param input The input stream to read from.
+ * @throws SchemeImportException
+ */
+ protected void readSettings(InputStream input) throws SchemeImportException {
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ spf.setValidating(false);
+ SAXParser parser;
+ try {
+ parser = spf.newSAXParser();
+ parser.parse(input, this);
+ }
+ catch (Exception e) {
+ throw new SchemeImportException(e);
+ }
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ if (PROFILE_TAG.equals(qName)) {
+ myOptionHandler.handleName(attributes.getValue(NAME_ATTR));
+ }
+ else if (SETTING_TAG.equals(qName)) {
+ String key = attributes.getValue(ID_ATTR);
+ String value = attributes.getValue(VALUE_ATTR);
+ if (key != null && value != null) {
+ try {
+ myOptionHandler.handleOption(key, value);
+ }
+ catch (SchemeImportException e) {
+ throw new SAXException(e);
+ }
+ }
+ }
+ else //noinspection StatementWithEmptyBody
+ if (PROFILES_TAG.equals(qName)) {
+ // Ignore
+ }
+ else {
+ throw new SAXException("Unknown XML element: " + qName);
+ }
+ }
+
+
+ interface OptionHandler {
+ void handleOption(@NotNull String eclipseKey, @NotNull String value) throws SchemeImportException;
+ void handleName(String name);
+ }
+}
diff --git a/plugins/eclipse/testData/import/settings/eclipse_exported.xml b/plugins/eclipse/testData/import/settings/eclipse_exported.xml
new file mode 100644
index 0000000..813c43b
--- /dev/null
+++ b/plugins/eclipse/testData/import/settings/eclipse_exported.xml
@@ -0,0 +1,291 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<profiles version="12">
+<profile kind="CodeFormatterProfile" name="MyOwn" version="12">
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
+<setting id="org.eclipse.jdt.core.compiler.source" value="1.7"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="next_line_shifted"/>
+<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.7"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="next_line_on_wrap"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
+</profile>
+</profiles>
diff --git a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseSettingsImportTest.java b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseSettingsImportTest.java
new file mode 100644
index 0000000..30c309e
--- /dev/null
+++ b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseSettingsImportTest.java
@@ -0,0 +1,168 @@
+package org.jetbrains.idea.eclipse;
+
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
+import com.intellij.psi.codeStyle.CodeStyleScheme;
+import com.intellij.psi.codeStyle.CodeStyleSchemes;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import com.intellij.testFramework.PlatformTestCase;
+import org.jetbrains.idea.eclipse.importer.EclipseCodeStyleSchemeImporter;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+/**
+ * @author Rustam Vishnyakov
+ */
+public class EclipseSettingsImportTest extends PlatformTestCase {
+
+ private static String getTestDataPath() {
+ return PluginPathManager.getPluginHomePath("eclipse") + "/testData/import/settings/";
+ }
+
+ public void testImportCodeStyleSettingsFromXmlProfile() throws Exception {
+ File input = new File(getTestDataPath() + "eclipse_exported.xml");
+ EclipseCodeStyleSchemeImporter codeStyleSchemeImporter = new EclipseCodeStyleSchemeImporter();
+ CodeStyleSchemes schemes = CodeStyleSchemes.getInstance();
+ CodeStyleScheme scheme = schemes.createNewScheme(getTestName(false), null);
+ CodeStyleSettings settings = scheme.getCodeStyleSettings();
+
+ CommonCodeStyleSettings javaSettings = settings.getCommonSettings("Java");
+ CommonCodeStyleSettings.IndentOptions indentOptions = javaSettings.getIndentOptions();
+ javaSettings.SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS = false;
+ javaSettings.SPACE_WITHIN_ARRAY_INITIALIZER_BRACES = false;
+ javaSettings.ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE = true;
+ javaSettings.SPACE_WITHIN_ANNOTATION_PARENTHESES = true;
+ javaSettings.BLANK_LINES_AROUND_FIELD = -1;
+ javaSettings.SPACE_WITHIN_WHILE_PARENTHESES = true;
+ javaSettings.ELSE_ON_NEW_LINE = true;
+ javaSettings.ALIGN_GROUP_FIELD_DECLARATIONS = true;
+ javaSettings.SPACE_BEFORE_FOR_PARENTHESES = false;
+ javaSettings.SPACE_AROUND_ADDITIVE_OPERATORS = false;
+ javaSettings.SPACE_AROUND_BITWISE_OPERATORS = false;
+ javaSettings.SPACE_AROUND_EQUALITY_OPERATORS = false;
+ javaSettings.SPACE_AROUND_LOGICAL_OPERATORS = false;
+ javaSettings.FINALLY_ON_NEW_LINE = true;
+ javaSettings.CATCH_ON_NEW_LINE = true;
+ javaSettings.SPACE_BEFORE_WHILE_PARENTHESES = false;
+ javaSettings.BLANK_LINES_AFTER_PACKAGE = -1;
+ javaSettings.getIndentOptions().CONTINUATION_INDENT_SIZE = 0;
+ javaSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
+ javaSettings.BLANK_LINES_BEFORE_PACKAGE = -1;
+ javaSettings.SPACE_WITHIN_FOR_PARENTHESES = true;
+ javaSettings.ALIGN_MULTILINE_ASSIGNMENT = true;
+ javaSettings.SPACE_BEFORE_METHOD_PARENTHESES = true;
+ javaSettings.SPACE_WITHIN_CATCH_PARENTHESES = true;
+ javaSettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES = true;
+ javaSettings.SPACE_WITHIN_CAST_PARENTHESES = true;
+ javaSettings.SPACE_AROUND_UNARY_OPERATOR = true;
+ javaSettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = false;
+ EditorSettingsExternalizable editorSettings = EditorSettingsExternalizable.getInstance();
+ boolean currAddLineFeed = editorSettings.isEnsureNewLineAtEOF();
+ editorSettings.setEnsureNewLineAtEOF(true);
+ javaSettings.ALIGN_MULTILINE_BINARY_OPERATION = true;
+ javaSettings.SPACE_WITHIN_TRY_PARENTHESES = true;
+ javaSettings.SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES = true;
+ javaSettings.WHILE_ON_NEW_LINE = true;
+ settings.ENABLE_JAVADOC_FORMATTING = false;
+ javaSettings.SPACE_BEFORE_SEMICOLON = true;
+ javaSettings.BLANK_LINES_BEFORE_METHOD_BODY = -1;
+ javaSettings.SPACE_BEFORE_COLON = false;
+ javaSettings.DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS = true;
+ javaSettings.BINARY_OPERATION_SIGN_ON_NEXT_LINE = false;
+ javaSettings.SPACE_WITHIN_SYNCHRONIZED_PARENTHESES = true;
+ javaSettings.SPACE_BEFORE_QUEST = false;
+ javaSettings.BLANK_LINES_BEFORE_IMPORTS = 0;
+ javaSettings.ALIGN_MULTILINE_THROWS_LIST = true;
+ javaSettings.SPACE_AFTER_COLON = false;
+ javaSettings.SPACE_WITHIN_FOR_PARENTHESES = true;
+ javaSettings.SPACE_BEFORE_SYNCHRONIZED_PARENTHESES = false;
+ javaSettings.ALIGN_MULTILINE_PARAMETERS = true;
+ javaSettings.ALIGN_MULTILINE_RESOURCES = true;
+ javaSettings.SPACE_BEFORE_SWITCH_PARENTHESES = false;
+ javaSettings.SPACE_WITHIN_METHOD_CALL_PARENTHESES = true;
+ javaSettings.CLASS_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE;
+ javaSettings.SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE = false;
+ javaSettings.SPACE_WITHIN_METHOD_PARENTHESES = true;
+ javaSettings.SPACE_BEFORE_CATCH_PARENTHESES = false;
+ javaSettings.SPACE_WITHIN_ANNOTATION_PARENTHESES = true;
+ javaSettings.BLANK_LINES_AFTER_IMPORTS = -1;
+ javaSettings.KEEP_FIRST_COLUMN_COMMENT = true;
+ javaSettings.KEEP_CONTROL_STATEMENT_IN_ONE_LINE = true;
+ indentOptions.USE_TAB_CHARACTER = false;
+ indentOptions.SMART_TABS = false;
+
+ InputStream inputStream = new FileInputStream(input);
+ try {
+ codeStyleSchemeImporter.importScheme(inputStream, null, scheme);
+
+ assertTrue(javaSettings.SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS);
+ assertTrue(javaSettings.SPACE_WITHIN_ARRAY_INITIALIZER_BRACES);
+ assertFalse(javaSettings.ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE);
+ assertFalse(javaSettings.SPACE_WITHIN_ANNOTATION_PARENTHESES);
+ assertEquals(0, javaSettings.BLANK_LINES_AROUND_FIELD);
+ assertFalse(javaSettings.SPACE_WITHIN_WHILE_PARENTHESES);
+ assertFalse(javaSettings.ELSE_ON_NEW_LINE);
+ assertFalse(javaSettings.ALIGN_GROUP_FIELD_DECLARATIONS);
+ assertTrue(javaSettings.SPACE_BEFORE_FOR_PARENTHESES);
+ assertTrue(javaSettings.SPACE_AROUND_ADDITIVE_OPERATORS);
+ assertTrue(javaSettings.SPACE_AROUND_BITWISE_OPERATORS);
+ assertTrue(javaSettings.SPACE_AROUND_EQUALITY_OPERATORS);
+ assertTrue(javaSettings.SPACE_AROUND_LOGICAL_OPERATORS);
+ assertFalse(javaSettings.FINALLY_ON_NEW_LINE);
+ assertFalse(javaSettings.CATCH_ON_NEW_LINE);
+ assertTrue(javaSettings.SPACE_BEFORE_WHILE_PARENTHESES);
+ assertEquals(1, javaSettings.BLANK_LINES_AFTER_PACKAGE);
+ assertEquals(2, javaSettings.getIndentOptions().CONTINUATION_INDENT_SIZE);
+ assertFalse(javaSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS);
+ assertEquals(0, javaSettings.BLANK_LINES_BEFORE_PACKAGE);
+ assertFalse(javaSettings.SPACE_WITHIN_FOR_PARENTHESES);
+ assertFalse(javaSettings.ALIGN_MULTILINE_ASSIGNMENT);
+ assertFalse(javaSettings.SPACE_BEFORE_METHOD_PARENTHESES);
+ assertFalse(javaSettings.SPACE_WITHIN_CATCH_PARENTHESES);
+ assertFalse(javaSettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES);
+ assertFalse(javaSettings.SPACE_WITHIN_CATCH_PARENTHESES);
+ assertFalse(javaSettings.SPACE_AROUND_UNARY_OPERATOR);
+ assertTrue(javaSettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE);
+ assertFalse(editorSettings.isEnsureNewLineAtEOF());
+ assertFalse(javaSettings.ALIGN_MULTILINE_BINARY_OPERATION);
+ assertFalse(javaSettings.SPACE_WITHIN_TRY_PARENTHESES);
+ assertFalse(javaSettings.SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES);
+ assertFalse(javaSettings.WHILE_ON_NEW_LINE);
+ assertTrue(settings.ENABLE_JAVADOC_FORMATTING);
+ assertFalse(javaSettings.SPACE_BEFORE_SEMICOLON);
+ assertEquals(0, javaSettings.BLANK_LINES_BEFORE_METHOD_BODY);
+ assertTrue(javaSettings.SPACE_BEFORE_COLON);
+ assertFalse(javaSettings.DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS);
+ assertTrue(javaSettings.BINARY_OPERATION_SIGN_ON_NEXT_LINE);
+ assertFalse(javaSettings.SPACE_WITHIN_SYNCHRONIZED_PARENTHESES);
+ assertTrue(javaSettings.SPACE_BEFORE_QUEST);
+ assertEquals(1, javaSettings.BLANK_LINES_BEFORE_IMPORTS);
+ assertFalse(javaSettings.ALIGN_MULTILINE_THROWS_LIST);
+ assertTrue(javaSettings.SPACE_AFTER_COLON);
+ assertFalse(javaSettings.SPACE_WITHIN_FOR_PARENTHESES);
+ assertTrue(javaSettings.SPACE_BEFORE_SYNCHRONIZED_PARENTHESES);
+ assertFalse(javaSettings.ALIGN_MULTILINE_PARAMETERS);
+ assertFalse(javaSettings.ALIGN_MULTILINE_RESOURCES);
+ assertTrue(javaSettings.SPACE_BEFORE_SWITCH_PARENTHESES);
+ assertFalse(javaSettings.SPACE_WITHIN_METHOD_CALL_PARENTHESES);
+ assertEquals(CommonCodeStyleSettings.END_OF_LINE, javaSettings.CLASS_BRACE_STYLE);
+ assertTrue(javaSettings.SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE);
+ assertFalse(javaSettings.SPACE_WITHIN_METHOD_PARENTHESES);
+ assertTrue(javaSettings.SPACE_BEFORE_CATCH_PARENTHESES);
+ assertFalse(javaSettings.SPACE_WITHIN_ANNOTATION_PARENTHESES);
+ assertEquals(1, javaSettings.BLANK_LINES_AFTER_IMPORTS);
+ assertFalse(javaSettings.KEEP_FIRST_COLUMN_COMMENT);
+ assertFalse(javaSettings.KEEP_CONTROL_STATEMENT_IN_ONE_LINE);
+ assertTrue(indentOptions.USE_TAB_CHARACTER);
+ assertTrue(indentOptions.SMART_TABS);
+ }
+ finally {
+ inputStream.close();
+ schemes.deleteScheme(scheme);
+ editorSettings.setEnsureNewLineAtEOF(currAddLineFeed);
+ }
+ }
+}
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 b3b1cc6..8ef616b 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java
@@ -22,6 +22,7 @@
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.settings.DistributionType;
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings;
import org.jetbrains.plugins.gradle.settings.GradleSettings;
import org.jetbrains.plugins.gradle.util.GradleEnvironment;
@@ -122,32 +123,34 @@
return null;
}
GradleProjectSettings settings = GradleSettings.getInstance(project).getLinkedProjectSettings(linkedProjectPath);
- if (settings == null) {
+ if (settings == null || settings.getDistributionType() == null) {
return null;
}
+ return getGradleHome(settings.getDistributionType(), linkedProjectPath, settings.getGradleHome());
+ }
+ @Nullable
+ public File getGradleHome(@NotNull DistributionType distributionType, @NotNull String linkedProjectPath, @Nullable String gradleHome) {
File candidate = null;
- if (settings.getDistributionType() != null) {
- switch (settings.getDistributionType()) {
- case LOCAL:
- if (settings.getGradleHome() != null) {
- candidate = new File(settings.getGradleHome());
- }
- break;
- case DEFAULT_WRAPPED:
- WrapperConfiguration wrapperConfiguration = GradleUtil.getWrapperConfiguration(linkedProjectPath);
- candidate = getWrappedGradleHome(linkedProjectPath, wrapperConfiguration);
- break;
- case WRAPPED:
- // not supported yet
- break;
- case BUNDLED:
- WrapperConfiguration bundledWrapperSettings = new WrapperConfiguration();
- DistributionLocator distributionLocator = new DistributionLocator();
- bundledWrapperSettings.setDistribution(distributionLocator.getDistributionFor(GradleVersion.current()));
- candidate = getWrappedGradleHome(linkedProjectPath, bundledWrapperSettings);
- break;
- }
+ switch (distributionType) {
+ case LOCAL:
+ if (gradleHome != null) {
+ candidate = new File(gradleHome);
+ }
+ break;
+ case DEFAULT_WRAPPED:
+ WrapperConfiguration wrapperConfiguration = GradleUtil.getWrapperConfiguration(linkedProjectPath);
+ candidate = getWrappedGradleHome(linkedProjectPath, wrapperConfiguration);
+ break;
+ case WRAPPED:
+ // not supported yet
+ break;
+ case BUNDLED:
+ WrapperConfiguration bundledWrapperSettings = new WrapperConfiguration();
+ DistributionLocator distributionLocator = new DistributionLocator();
+ bundledWrapperSettings.setDistribution(distributionLocator.getDistributionFor(GradleVersion.current()));
+ candidate = getWrappedGradleHome(linkedProjectPath, bundledWrapperSettings);
+ break;
}
File result = 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 c0873f7..9c9e361 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
@@ -444,9 +444,7 @@
ProjectData projectData = rootProjectNode.getData();
final String rootProjectPath = projectData.getLinkedExternalProjectPath();
Map<String/* module name */, Collection<TaskData>> tasksByModule = ContainerUtilRt.newHashMap();
- TObjectIntHashMap<Pair<String/* task name */, String /* task description */>> rootProjectTaskCandidates
- = new TObjectIntHashMap<Pair<String, String>>();
- final Collection<TaskData> rootProjectTasks = ContainerUtilRt.newArrayList();
+ Set<Pair<String/* task name */, String /* task description */>> rootProjectTaskCandidates = ContainerUtilRt.newHashSet();
final DomainObjectSet<? extends IdeaModule> modules = project.getModules();
for (IdeaModule module : modules) {
String moduleConfigPath = GradleUtil.getConfigPath(module.getGradleProject(), rootProjectPath);
@@ -462,39 +460,28 @@
}
TaskData taskData = new TaskData(GradleConstants.SYSTEM_ID, name, moduleConfigPath, task.getDescription());
-
- if (rootProjectPath.equals(moduleConfigPath)) {
- rootProjectTasks.add(taskData);
+
+ Collection<TaskData> tasks = tasksByModule.get(module.getName());
+ if (tasks == null) {
+ tasksByModule.put(module.getName(), tasks = ContainerUtilRt.newArrayList());
}
- else {
- Collection<TaskData> tasks = tasksByModule.get(module.getName());
- if (tasks == null) {
- tasksByModule.put(module.getName(), tasks = ContainerUtilRt.newArrayList());
- }
- tasks.add(taskData);
- Pair<String, String> key = Pair.create(name, task.getDescription());
- rootProjectTaskCandidates.put(key, rootProjectTaskCandidates.get(key) + 1);
- }
+ tasks.add(taskData);
+ rootProjectTaskCandidates.add(Pair.create(name, task.getDescription()));
}
}
- rootProjectTaskCandidates.forEachEntry(new TObjectIntProcedure<Pair<String, String>>() {
- @Override
- public boolean execute(Pair<String, String> p, int occurrenceNumber) {
- if (modules.size() == 1 || occurrenceNumber >= modules.size() - 1) {
- rootProjectTasks.add(new TaskData(GradleConstants.SYSTEM_ID, p.first, rootProjectPath, p.second));
- }
- return true;
- }
- });
- for (TaskData task : rootProjectTasks) {
- rootProjectNode.createChild(ProjectKeys.TASK, task);
+
+ for(Pair<String, String> p : rootProjectTaskCandidates) {
+ rootProjectNode.createChild(ProjectKeys.TASK, new TaskData(GradleConstants.SYSTEM_ID, p.first, rootProjectPath, p.second));
}
Collection<DataNode<ModuleData>> moduleNodes = ExternalSystemApiUtil.findAll(rootProjectNode, ProjectKeys.MODULE);
for (DataNode<ModuleData> moduleNode : moduleNodes) {
ModuleData moduleData = moduleNode.getData();
- if (rootProjectPath.equals(moduleData.getLinkedExternalProjectPath()) && !projectData.getName().equals(moduleData.getName())) {
- moduleData.setName(projectData.getName());
+ if (rootProjectPath.equals(moduleData.getLinkedExternalProjectPath())) {
+ if (!projectData.getName().equals(moduleData.getName())) {
+ moduleData.setName(projectData.getName());
+ }
+ continue;
}
Collection<TaskData> tasks = tasksByModule.get(moduleData.getName());
if (tasks != null && !tasks.isEmpty()) {
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java
index 6bebf3a6..d5a20ed 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java
@@ -22,11 +22,15 @@
* @since 9/3/13
*/
public final class GradleCommonClassNames {
+ @NonNls public static final String GRADLE_API_SCRIPT = "org.gradle.api.Script";
@NonNls public static final String GRADLE_API_PROJECT = "org.gradle.api.Project";
@NonNls public static final String GRADLE_API_CONFIGURATION_CONTAINER = "org.gradle.api.artifacts.ConfigurationContainer";
@NonNls public static final String GRADLE_API_CONFIGURATION = "org.gradle.api.artifacts.Configuration";
@NonNls public static final String GRADLE_API_ARTIFACT_HANDLER = "org.gradle.api.artifacts.dsl.ArtifactHandler";
@NonNls public static final String GRADLE_API_DEPENDENCY_HANDLER = "org.gradle.api.artifacts.dsl.DependencyHandler";
+ @NonNls public static final String GRADLE_API_ARTIFACTS_EXTERNAL_MODULE_DEPENDENCY = "org.gradle.api.artifacts.ExternalModuleDependency";
+ @NonNls public static final String GRADLE_API_ARTIFACTS_MODULE_DEPENDENCY = "org.gradle.api.artifacts.ModuleDependency";
+ @NonNls public static final String GRADLE_API_ARTIFACTS_DEPENDENCY_ARTIFACT = "org.gradle.api.artifacts.DependencyArtifact";
@NonNls public static final String GRADLE_API_REPOSITORY_HANDLER = "org.gradle.api.artifacts.dsl.RepositoryHandler";
@NonNls public static final String GRADLE_API_SOURCE_DIRECTORY_SET = "org.gradle.api.file.SourceDirectorySet";
@NonNls public static final String GRADLE_API_SOURCE_SET = "org.gradle.api.tasks.SourceSet";
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.java
index 161e4c7..7685a25 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.java
@@ -15,75 +15,72 @@
*/
package org.jetbrains.plugins.gradle.service.resolve;
-import com.intellij.psi.*;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.ResolveState;
import com.intellij.psi.scope.PsiScopeProcessor;
-import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
-import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
-import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightParameter;
import java.util.List;
+import java.util.Set;
/**
* @author Denis Zhdanov
* @since 8/14/13 12:58 PM
*/
public class GradleDependenciesContributor implements GradleMethodContextContributor {
+ private final static Set<String> BUILD_SCRIPT_BLOCKS = ContainerUtil.newHashSet(
+ "subprojects",
+ "allprojects",
+ "buildscript"
+ );
@Override
public void process(@NotNull List<String> methodCallInfo,
@NotNull PsiScopeProcessor processor,
@NotNull ResolveState state,
@NotNull PsiElement place) {
- if (methodCallInfo.isEmpty()) {
- return;
+ if (methodCallInfo.isEmpty()) return;
+
+ String methodCall = ContainerUtil.getLastItem(methodCallInfo);
+ if (methodCall == null) return;
+
+ if (methodCallInfo.size() > 1 && BUILD_SCRIPT_BLOCKS.contains(methodCall)) {
+ methodCallInfo.remove(methodCallInfo.size() - 1);
+ methodCall = ContainerUtil.getLastItem(methodCallInfo);
}
- int i = methodCallInfo.indexOf("dependencies");
- if (i != 1) {
- return;
- }
+ if (!StringUtil.equals(methodCall, "dependencies")) return;
- // Assuming that the method call is addition of new dependency into configuration.
- GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- PsiClass contributorClass =
- psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_DEPENDENCY_HANDLER, place.getResolveScope());
- if (contributorClass == null) {
- return;
- }
- processDependencyAddition(methodCallInfo.get(0), contributorClass, processor, state, place);
- }
-
- private static void processDependencyAddition(@NotNull String gradleConfigurationName,
- @NotNull PsiClass dependencyHandlerClass,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place) {
- GrLightMethodBuilder builder = new GrLightMethodBuilder(place.getManager(), gradleConfigurationName);
- PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getManager().getProject());
- PsiType type = new PsiArrayType(factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, place.getResolveScope()));
- builder.addParameter(new GrLightParameter("dependencyInfo", type, builder));
- processor.execute(builder, state);
-
- GrMethodCall call = PsiTreeUtil.getParentOfType(place, GrMethodCall.class);
- if (call == null) {
- return;
- }
- GrArgumentList args = call.getArgumentList();
- if (args == null) {
- return;
- }
-
- int argsCount = GradleResolverUtil.getGrMethodArumentsCount(args);
- argsCount++; // Configuration name is delivered as an argument.
-
- for (PsiMethod method : dependencyHandlerClass.findMethodsByName("add", false)) {
- if (method.getParameterList().getParametersCount() == argsCount) {
- builder.setNavigationElement(method);
+ final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
+ if (methodCallInfo.size() == 2) {
+ PsiClass psiClass =
+ psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_ARTIFACTS_EXTERNAL_MODULE_DEPENDENCY, place.getResolveScope());
+ if (psiClass != null) {
+ psiClass.processDeclarations(processor, state, null, place);
}
+ // Assuming that the method call is addition of new dependency into configuration.
+ PsiClass contributorClass =
+ psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_DEPENDENCY_HANDLER, place.getResolveScope());
+ if (contributorClass == null) return;
+ GradleResolverUtil.processMethod(methodCallInfo.get(0), contributorClass, processor, state, place, "add");
+ }
+ else if (methodCallInfo.size() == 3) {
+ GradleResolverUtil.processDeclarations(psiManager, processor, state, place,
+ GradleCommonClassNames.GRADLE_API_DEPENDENCY_HANDLER,
+ GradleCommonClassNames.GRADLE_API_ARTIFACTS_EXTERNAL_MODULE_DEPENDENCY,
+ GradleCommonClassNames.GRADLE_API_ARTIFACTS_DEPENDENCY_ARTIFACT,
+ GradleCommonClassNames.GRADLE_API_PROJECT);
+ }
+ else if (methodCallInfo.size() == 4) {
+ // Assuming that the method call is addition of new dependency into configuration.
+ PsiClass contributorClass =
+ psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_DEPENDENCY_HANDLER, place.getResolveScope());
+ if (contributorClass == null) return;
+ GradleResolverUtil.processMethod(methodCallInfo.get(0), contributorClass, processor, state, place, "add");
}
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java
index c44810e..ace5839 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java
@@ -17,11 +17,14 @@
import com.intellij.psi.*;
import com.intellij.psi.scope.PsiScopeProcessor;
+import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceExpressionImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrImplicitVariableImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
@@ -77,10 +80,73 @@
GrLightParameter closureParameter = new GrLightParameter("closure", closureType, methodWithClosure);
methodWithClosure.addParameter(closureParameter);
- if (returnType != null) {
- PsiClassType retType = factory.createTypeByFQClassName(returnType, place.getResolveScope());
- methodWithClosure.setReturnType(retType);
- }
+ PsiClassType retType = factory.createTypeByFQClassName(
+ returnType != null ? returnType : CommonClassNames.JAVA_LANG_OBJECT, place.getResolveScope());
+ methodWithClosure.setReturnType(retType);
return methodWithClosure;
}
+
+ public static void processMethod(@NotNull String gradleConfigurationName,
+ @NotNull PsiClass dependencyHandlerClass,
+ @NotNull PsiScopeProcessor processor,
+ @NotNull ResolveState state,
+ @NotNull PsiElement place) {
+ processMethod(gradleConfigurationName, dependencyHandlerClass, processor, state, place, null);
+ }
+
+ public static void processMethod(@NotNull String gradleConfigurationName,
+ @NotNull PsiClass dependencyHandlerClass,
+ @NotNull PsiScopeProcessor processor,
+ @NotNull ResolveState state,
+ @NotNull PsiElement place,
+ @Nullable String defaultMethodName) {
+ GrLightMethodBuilder builder = new GrLightMethodBuilder(place.getManager(), gradleConfigurationName);
+ PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getManager().getProject());
+ PsiType type = new PsiArrayType(factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, place.getResolveScope()));
+ builder.addParameter(new GrLightParameter("param", type, builder));
+ PsiClassType retType = factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, place.getResolveScope());
+ builder.setReturnType(retType);
+ processor.execute(builder, state);
+
+ GrMethodCall call = PsiTreeUtil.getParentOfType(place, GrMethodCall.class);
+ if (call == null) {
+ return;
+ }
+ GrArgumentList args = call.getArgumentList();
+ if (args == null) {
+ return;
+ }
+
+ int argsCount = getGrMethodArumentsCount(args);
+ argsCount++; // Configuration name is delivered as an argument.
+
+ for (PsiMethod method : dependencyHandlerClass.findMethodsByName(gradleConfigurationName, false)) {
+ if (method.getParameterList().getParametersCount() == argsCount) {
+ builder.setNavigationElement(method);
+ return;
+ }
+ }
+
+ if (defaultMethodName != null) {
+ for (PsiMethod method : dependencyHandlerClass.findMethodsByName(defaultMethodName, false)) {
+ if (method.getParameterList().getParametersCount() == argsCount) {
+ builder.setNavigationElement(method);
+ return;
+ }
+ }
+ }
+ }
+
+ public static void processDeclarations(@NotNull GroovyPsiManager psiManager,
+ @NotNull PsiScopeProcessor processor,
+ @NotNull ResolveState state,
+ @NotNull PsiElement place,
+ @NotNull String... fqNames) {
+ for (String fqName : fqNames) {
+ PsiClass psiClass = psiManager.findClassWithCache(fqName, place.getResolveScope());
+ if (psiClass != null) {
+ psiClass.processDeclarations(processor, state, null, place);
+ }
+ }
+ }
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java
index 655a05f..8599392 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java
@@ -75,6 +75,7 @@
MyState state = new MyState();
fillState(state);
state.serviceDirectoryPath = myServiceDirectoryPath;
+ state.gradleVmOptions = myGradleVmOptions;
return state;
}
@@ -82,6 +83,7 @@
public void loadState(MyState state) {
super.loadState(state);
myServiceDirectoryPath = state.serviceDirectoryPath;
+ myGradleVmOptions = state.gradleVmOptions;
}
/**
@@ -130,6 +132,7 @@
private Set<GradleProjectSettings> myProjectSettings = ContainerUtilRt.newTreeSet();
public String serviceDirectoryPath;
+ public String gradleVmOptions;
@AbstractCollection(surroundWithTag = false, elementTypes = {GradleProjectSettings.class})
public Set<GradleProjectSettings> getLinkedExternalProjectsSettings() {
diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml
index 9ae01a8..bc60ac5 100644
--- a/plugins/groovy/src/META-INF/plugin.xml
+++ b/plugins/groovy/src/META-INF/plugin.xml
@@ -167,7 +167,7 @@
<groovyFrameworkConfigNotification implementation="org.jetbrains.plugins.groovy.griffon.GriffonConfigureNotification"/>
<defaultImportContributor implementation="org.jetbrains.plugins.groovy.griffon.GriffonDefaultImportContributor"/>
- <groovyShellRunner implementation="org.jetbrains.plugins.groovy.console.DefaultGroovyShellRunner" order="last"/>
+ <groovyShellRunner implementation="org.jetbrains.plugins.groovy.console.GroovyConsoleRunner" order="last"/>
<closureCompleter implementation="org.jetbrains.plugins.groovy.lang.completion.GdslClosureCompleter"/>
<closureCompleter implementation="org.jetbrains.plugins.groovy.lang.completion.EachWithIndexClosureCompleter"/>
@@ -1444,6 +1444,8 @@
implementation="org.jetbrains.plugins.groovy.springloaded.SpringLoadedPositionManagerFactory"/>
<codeStyle.ReferenceAdjuster language="Groovy" implementationClass="org.jetbrains.plugins.groovy.codeStyle.GrReferenceAdjuster"/>
<codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.plugins.groovy.jarFinder.GroovyFindJarQuickFixProvider"/>
+ <lang.refactoringSupport.classMembersRefactoringSupport language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.refactoring.classMembers.GroovyClassMembersRefactoringSupport"/>
</extensions>
<extensions defaultExtensionNs="com.intellij.debugger">
@@ -1547,13 +1549,20 @@
icon="JetgroovyIcons.Groovy.GroovyDoc">
<add-to-group group-id="ToolsMenu" anchor="last"/>
</action>
- <action id="Groovy.Console"
+ <action id="Groovy.Shell"
class="org.jetbrains.plugins.groovy.console.GroovyShellAction"
text="Groovy Shell..." description="Launch Groovy Shell"
icon="JetgroovyIcons.Groovy.Groovy_16x16">
<add-to-group group-id="ToolsMenu" anchor="last"/>
</action>
+ <action id="Groovy.Console"
+ class="org.jetbrains.plugins.groovy.console.GroovyConsoleAction"
+ text="Groovy Console..." description="Launch Groovy Console"
+ icon="JetgroovyIcons.Groovy.Groovy_16x16">
+ <add-to-group group-id="ToolsMenu" anchor="last"/>
+ </action>
+
<group id="Mvc.Actions" popup="true" class="org.jetbrains.plugins.groovy.mvc.MvcActionGroup">
<action id="Mvc.Upgrade"
class="org.jetbrains.plugins.groovy.mvc.MvcUpgradeAction"
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties
index 05ba87c..a2704e2 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties
@@ -368,3 +368,4 @@
annotation.attribute.expected=Annotation attribute expected
highlight.constructor.calls.of.a.non.static.inner.classes.without.enclosing.instance.passed=Highlight constructor calls of non-static inner classes without enclosing instance passed
doc.end.expected='*/' expected
+mixing.private.and.public.protected.methods.of.the.same.name=Mixing private and public/protected methods of the same name
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
index 748f7c8..de7bb9e 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
@@ -391,6 +391,39 @@
checkConstructors(myHolder, typeDefinition);
checkAnnotationCollector(myHolder, typeDefinition);
+
+ checkSameNameMethodsWithDifferentAccessModifiers(myHolder, typeDefinition.getCodeMethods());
+ }
+
+ private static void checkSameNameMethodsWithDifferentAccessModifiers(AnnotationHolder holder, GrMethod[] methods) {
+ MultiMap<String, GrMethod> map = MultiMap.create();
+ for (GrMethod method : methods) {
+ map.putValue(method.getName(), method);
+ }
+
+ for (Map.Entry<String, Collection<GrMethod>> entry : map.entrySet()) {
+ Collection<GrMethod> collection = entry.getValue();
+ if (collection.size() > 1 && !sameAccessModifier(collection)) {
+ for (GrMethod method : collection) {
+ holder.createErrorAnnotation(GrHighlightUtil.getMethodHeaderTextRange(method), GroovyBundle.message("mixing.private.and.public.protected.methods.of.the.same.name"));
+ }
+ }
+ }
+ }
+
+ private static boolean sameAccessModifier(Collection<GrMethod> collection) {
+ Iterator<GrMethod> iterator = collection.iterator();
+ GrMethod method = iterator.next();
+ boolean privateAccess = PsiModifier.PRIVATE.equals(VisibilityUtil.getVisibilityModifier(method.getModifierList()));
+
+ while (iterator.hasNext()) {
+ GrMethod next = iterator.next();
+ if (privateAccess != PsiModifier.PRIVATE.equals(VisibilityUtil.getVisibilityModifier(next.getModifierList()))) {
+ return false;
+ }
+ }
+
+ return true;
}
private static void checkAnnotationCollector(AnnotationHolder holder, GrTypeDefinition definition) {
@@ -1345,6 +1378,7 @@
final PsiClass scriptClass = file.getScriptClass();
if (scriptClass != null) {
checkDuplicateMethod(scriptClass, myHolder);
+ checkSameNameMethodsWithDifferentAccessModifiers(myHolder, file.getCodeMethods());
}
}
@@ -1430,6 +1464,7 @@
private boolean checkAnnotationAttributeValue(GrAnnotationMemberValue value, PsiElement toHighlight) {
if (value instanceof GrLiteral) return false;
if (value instanceof GrClosableBlock) return false;
+ if (value instanceof GrAnnotation) return false;
if (value instanceof GrReferenceExpression) {
PsiElement resolved = ((GrReferenceExpression)value).resolve();
@@ -1619,7 +1654,7 @@
private static void checkGrDocReferenceElement(AnnotationHolder holder, PsiElement element) {
ASTNode node = element.getNode();
- if (node != null && TokenSets.BUILT_IN_TYPE.contains(node.getElementType())) {
+ if (node != null && TokenSets.BUILT_IN_TYPES.contains(node.getElementType())) {
Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setTextAttributes(KEYWORD);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/DefaultGroovyShellRunner.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/DefaultGroovyShellRunner.java
index 58b672d1..39aa7a0 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/DefaultGroovyShellRunner.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/DefaultGroovyShellRunner.java
@@ -19,6 +19,7 @@
import com.intellij.execution.configurations.JavaParameters;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.search.GlobalSearchScope;
@@ -51,15 +52,14 @@
boolean useBundled = !hasGroovyAll(module);
DefaultGroovyScriptRunner.configureGenericGroovyRunner(res, module, "org.codehaus.groovy.tools.shell.Main", false, true);
if (useBundled) {
- String parent = GroovyUtils.getBundledGroovyJar().getParent();
- String groovyHome = parent + File.separator + "groovy";
- File libDir = new File(groovyHome + File.separator + "lib");
+ String libRoot = GroovyUtils.getBundledGroovyJar().getParent();
+ File libDir = new File(libRoot + "/groovy/lib");
assert libDir.isDirectory();
for (File file : libDir.listFiles()) {
res.getClassPath().add(file);
}
- GroovyScriptRunner.setGroovyHome(res, groovyHome);
+ GroovyScriptRunner.setGroovyHome(res, FileUtil.toCanonicalPath(libRoot + "/groovy"));
}
res.setWorkingDirectory(getWorkingDirectory(module));
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyConsoleAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyConsoleAction.java
new file mode 100644
index 0000000..308f932
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyConsoleAction.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.console;
+
+import com.intellij.execution.console.LanguageConsoleImpl;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import com.intellij.testFramework.LightVirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.GroovyFileType;
+import org.jetbrains.plugins.groovy.debugger.fragments.GroovyCodeFragment;
+
+/**
+ * Created by Max Medvedev on 9/20/13
+ */
+public class GroovyConsoleAction extends GroovyShellActionBase {
+ @Override
+ protected GroovyShellRunner getRunner(Module module) {
+ return GroovyShellRunner.getAppropriateRunner(module);
+ }
+
+ @Override
+ public String getTitle() {
+ return "Groovy Console";
+ }
+
+ @Override
+ protected LanguageConsoleImpl createConsole(Project project, String title) {
+ return new LanguageConsoleImpl(project, title, GroovyFileType.GROOVY_LANGUAGE) {
+ @NotNull
+ @Override
+ protected PsiFile createFile(@NotNull LightVirtualFile virtualFile, @NotNull Document document, @NotNull Project project) {
+ return new GroovyCodeFragment(getProject(), virtualFile);
+ }
+ };
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyConsoleRunner.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyConsoleRunner.java
new file mode 100644
index 0000000..bf46a21
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyConsoleRunner.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.console;
+
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.JavaParameters;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.PathsList;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.config.AbstractConfigUtils;
+import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
+import org.jetbrains.plugins.groovy.runner.DefaultGroovyScriptRunner;
+import org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfiguration;
+import org.jetbrains.plugins.groovy.runner.GroovyScriptRunner;
+import org.jetbrains.plugins.groovy.util.GroovyUtils;
+import org.jetbrains.plugins.groovy.util.LibrariesUtil;
+
+/**
+ * @author Max Medvedev
+ */
+public class GroovyConsoleRunner extends GroovyShellRunner {
+ @NotNull
+ @Override
+ public String getWorkingDirectory(@NotNull Module module) {
+ VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots();
+ return contentRoots[0].getPath();
+ }
+
+ @NotNull
+ @Override
+ public JavaParameters createJavaParameters(@NotNull Module module) throws ExecutionException {
+ JavaParameters res = GroovyScriptRunConfiguration.createJavaParametersWithSdk(module);
+ DefaultGroovyScriptRunner.configureGenericGroovyRunner(res, module, "groovy.ui.GroovyMain", !hasGroovyAll(module), true);
+ PathsList list = GroovyScriptRunner.getClassPathFromRootModel(module, true, res, true, res.getClassPath());
+ if (list != null) {
+ res.getClassPath().addAll(list.getPathList());
+ }
+ res.getProgramParametersList().addAll("-p", GroovyScriptRunner.getPathInConf("console.txt"));
+ //res.getVMParametersList().add("-Xdebug"); res.getVMParametersList().add("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5239");
+ res.setWorkingDirectory(getWorkingDirectory(module));
+
+ return res;
+ }
+
+ @Override
+ public boolean canRun(@NotNull Module module) {
+ VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots();
+ return contentRoots.length > 0;
+ }
+
+ @NotNull
+ @Override
+ public String getTitle(@NotNull Module module) {
+ String homePath = LibrariesUtil.getGroovyHomePath(module);
+ boolean bundled = false;
+ if (homePath == null || !hasGroovyAll(module)) {
+ homePath = GroovyUtils.getBundledGroovyJar().getParentFile().getParent();
+ bundled = true;
+ }
+ String version = GroovyConfigUtils.getInstance().getSDKVersion(homePath);
+ return version == AbstractConfigUtils.UNDEFINED_VERSION ? "" : " (" + (bundled ? "Bundled " : "") + "Groovy " + version + ")";
+ }
+
+ private static boolean hasGroovyAll(Module module) {
+ GlobalSearchScope scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module);
+ JavaPsiFacade facade = JavaPsiFacade.getInstance(module.getProject());
+ return (facade.findClass("org.apache.commons.cli.CommandLineParser", scope) != null ||
+ facade.findClass("groovyjarjarcommonscli.CommandLineParser", scope) != null) &&
+ facade.findClass("groovy.ui.GroovyMain", scope) != null;
+ }
+
+ @NotNull
+ @Override
+ public String transformUserInput(@NotNull String userInput) {
+ return StringUtil.replace(userInput, "\n", "###\\n");
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellAction.java
index 289977c..835687a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellAction.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellAction.java
@@ -15,218 +15,49 @@
*/
package org.jetbrains.plugins.groovy.console;
-import com.intellij.execution.ExecutionException;
-import com.intellij.execution.configurations.JavaParameters;
-import com.intellij.execution.console.ConsoleHistoryController;
-import com.intellij.execution.console.LanguageConsoleViewImpl;
-import com.intellij.execution.process.OSProcessHandler;
-import com.intellij.execution.runners.AbstractConsoleRunnerWithHistory;
-import com.intellij.execution.runners.ConsoleExecuteActionHandler;
-import com.intellij.ide.util.PropertiesComponent;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.compiler.CompileContext;
-import com.intellij.openapi.compiler.CompileStatusNotification;
-import com.intellij.openapi.compiler.CompilerManager;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.JavaSdkType;
-import com.intellij.openapi.projectRoots.JdkUtil;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.projectRoots.SdkTypeId;
-import com.intellij.openapi.roots.ModuleRootManager;
-import com.intellij.openapi.roots.ui.configuration.ModulesAlphaComparator;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.ui.popup.JBPopupFactory;
-import com.intellij.openapi.ui.popup.PopupStep;
-import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
-import com.intellij.openapi.util.Key;
-import com.intellij.util.PlatformIcons;
-import icons.JetgroovyIcons;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFileImpl;
-import org.jetbrains.plugins.groovy.util.GroovyUtils;
-
-import java.util.*;
/**
* @author peter
*/
-public class GroovyShellAction extends DumbAwareAction {
- private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.console.GroovyShellAction");
-
- private static final String GROOVY_SHELL_LAST_MODULE = "Groovy.Shell.LastModule";
- public static final Key<Boolean> GROOVY_SHELL_FILE = Key.create("GROOVY_SHELL_FILE");
-
- private static List<Module> getGroovyCompatibleModules(Project project) {
- ArrayList<Module> result = new ArrayList<Module>();
- for (Module module : ModuleManager.getInstance(project).getModules()) {
- if (GroovyUtils.isSuitableModule(module)) {
- Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
- if (sdk != null && sdk.getSdkType() instanceof JavaSdkType) {
- result.add(module);
- }
- }
- }
- return result;
+public class GroovyShellAction extends GroovyShellActionBase {
+ protected GroovyShellRunner getRunner(Module module) {
+ return new DefaultGroovyShellRunner();
}
@Override
- public void update(AnActionEvent e) {
- final Project project = e.getData(CommonDataKeys.PROJECT);
-
- boolean enabled = project != null && !getGroovyCompatibleModules(project).isEmpty();
-
- e.getPresentation().setEnabled(enabled);
- e.getPresentation().setVisible(enabled);
+ public String getTitle() {
+ return "Groovy Shell";
}
@Override
- public void actionPerformed(AnActionEvent e) {
- final Project project = e.getData(CommonDataKeys.PROJECT);
- assert project != null;
+ protected GroovyShellConsoleImpl createConsole(Project project, String title) {
+ final GroovyShellConsoleImpl console = new GroovyShellConsoleImpl(project, title);
- CompilerManager.getInstance(project).make(new CompileStatusNotification() {
+ /*UiNotifyConnector.doWhenFirstShown(console.getComponent(), new Runnable() {
@Override
- public void finished(boolean aborted, int errors, int warnings, CompileContext compileContext) {
- if (aborted) return;
-
- final Project project = compileContext.getProject();
-
- if (errors == 0 ||
- Messages.showYesNoDialog(project, "Compilation failed with errors. Do you want to run Groovy shell anyway?", "Groovy Shell",
- JetgroovyIcons.Groovy.Groovy_32x32) == Messages.YES) {
- runGroovyShell(project);
- }
- }
- });
- }
-
- private static void runGroovyShell(Project project) {
- List<Module> modules = new ArrayList<Module>();
- final Map<Module, String> versions = new HashMap<Module, String>();
-
- for (Module module : getGroovyCompatibleModules(project)) {
- GroovyShellRunner runner = GroovyShellRunner.getAppropriateRunner(module);
- if (runner != null) {
- modules.add(module);
- versions.put(module, runner.getTitle(module));
- }
- }
-
- if (modules.size() == 1) {
- doRun(modules.get(0));
- return;
- }
-
- Collections.sort(modules, ModulesAlphaComparator.INSTANCE);
-
- BaseListPopupStep<Module> step =
- new BaseListPopupStep<Module>("Which module to use classpath of?", modules, PlatformIcons.CONTENT_ROOT_ICON_CLOSED) {
- @NotNull
- @Override
- public String getTextFor(Module value) {
- return value.getName() + versions.get(value);
- }
-
- @Override
- public String getIndexedString(Module value) {
- return value.getName();
- }
-
- @Override
- public boolean isSpeedSearchEnabled() {
- return true;
- }
-
- @Override
- public PopupStep onChosen(Module selectedValue, boolean finalChoice) {
- PropertiesComponent.getInstance(selectedValue.getProject()).setValue(GROOVY_SHELL_LAST_MODULE, selectedValue.getName());
- doRun(selectedValue);
- return null;
- }
- };
- for (int i = 0; i < modules.size(); i++) {
- Module module = modules.get(i);
- if (module.getName().equals(PropertiesComponent.getInstance(project).getValue(GROOVY_SHELL_LAST_MODULE))) {
- step.setDefaultOptionIndex(i);
- break;
- }
- }
- JBPopupFactory.getInstance().createListPopup(step).showCenteredInCurrentWindow(project);
- }
-
- private static void doRun(final Module module) {
- final GroovyShellRunner shellRunner = GroovyShellRunner.getAppropriateRunner(module);
- if (shellRunner == null) return;
-
- AbstractConsoleRunnerWithHistory<GroovyConsoleView> runner =
- new AbstractConsoleRunnerWithHistory<GroovyConsoleView>(module.getProject(), "Groovy Shell", shellRunner.getWorkingDirectory(module)) {
-
- @Override
- protected GroovyConsoleView createConsoleView() {
- GroovyConsoleView res = new GroovyConsoleView(getProject());
-
- GroovyFileImpl file = (GroovyFileImpl)res.getConsole().getFile();
- assert file.getContext() == null;
- file.putUserData(GROOVY_SHELL_FILE, Boolean.TRUE);
-
- file.setContext(shellRunner.getContext(module));
-
- return res;
- }
-
- @Override
- protected Process createProcess() throws ExecutionException {
- JavaParameters javaParameters = shellRunner.createJavaParameters(module);
-
- final Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
- assert sdk != null;
- SdkTypeId sdkType = sdk.getSdkType();
- assert sdkType instanceof JavaSdkType;
- final String exePath = ((JavaSdkType)sdkType).getVMExecutablePath(sdk);
-
- return JdkUtil.setupJVMCommandLine(exePath, javaParameters, true).createProcess();
- }
-
- @Override
- protected OSProcessHandler createProcessHandler(Process process) {
- return new OSProcessHandler(process);
- }
-
- @NotNull
- @Override
- protected ConsoleExecuteActionHandler createConsoleExecuteActionHandler() {
- ConsoleExecuteActionHandler handler = new ConsoleExecuteActionHandler(getProcessHandler(), false) {
+ public void run() {
+ final String key = "groovy.shell.is.really.groovy.shell";
+ if (!PropertiesComponent.getInstance().isTrueValue(key)) {
+ final Alarm alarm = new Alarm();
+ alarm.addRequest(new Runnable() {
@Override
- public void processLine(String line) {
- super.processLine(shellRunner.transformUserInput(line));
- }
+ public void run() {
+ GotItMessage.createMessage("Groovy Shell & Groovy Console", "<html><div align='left'>Use 'Groovy Console' action (Tools | Groovy Console...) to run <a href='http://'>Groovy Console</a><br>Use 'Groovy Shell' action (Tools | Groovy Shell...) to invoke <a href=\"http://groovy.codehaus.org/Groovy+Shell\">Groovy Shell</a></div></html>")
+ .setDisposable(console)
+ .show(new RelativePoint(console.getComponent(), new Point(10, 0)), Balloon.Position.above);
- @Override
- public String getEmptyExecuteAction() {
- return "Groovy.Shell.Execute";
+ PropertiesComponent.getInstance().setValue(key, String.valueOf(true));
+ Disposer.dispose(alarm);
}
- };
- new ConsoleHistoryController("Groovy Shell", null, getLanguageConsole(), handler.getConsoleHistoryModel()).install();
- return handler;
+ }, 2000);
}
- };
- try {
- runner.initAndRun();
- }
- catch (ExecutionException e1) {
- LOG.info(e1);
- Messages.showErrorDialog(module.getProject(), e1.getMessage(), "Cannot Run Groovy Shell");
- }
- }
- private static class GroovyConsoleView extends LanguageConsoleViewImpl {
- protected GroovyConsoleView(final Project project) {
- super(new GroovyShellConsoleImpl(project, "Groovy Console"));
- }
+ }
+ })*/;
+
+
+ return console;
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellActionBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellActionBase.java
new file mode 100644
index 0000000..54f8d51
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellActionBase.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.console;
+
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.JavaParameters;
+import com.intellij.execution.console.ConsoleHistoryController;
+import com.intellij.execution.console.LanguageConsoleImpl;
+import com.intellij.execution.console.LanguageConsoleView;
+import com.intellij.execution.console.LanguageConsoleViewImpl;
+import com.intellij.execution.process.OSProcessHandler;
+import com.intellij.execution.runners.AbstractConsoleRunnerWithHistory;
+import com.intellij.execution.runners.ConsoleExecuteActionHandler;
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileStatusNotification;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.JavaSdkType;
+import com.intellij.openapi.projectRoots.JdkUtil;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkTypeId;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.ui.configuration.ModulesAlphaComparator;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.ui.popup.PopupStep;
+import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
+import com.intellij.openapi.util.Key;
+import com.intellij.util.PlatformIcons;
+import icons.JetgroovyIcons;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFileImpl;
+import org.jetbrains.plugins.groovy.util.GroovyUtils;
+
+import java.util.*;
+
+/**
+ * Created by Max Medvedev on 9/20/13
+ */
+public abstract class GroovyShellActionBase extends DumbAwareAction {
+ private static final Logger LOG = Logger.getInstance(GroovyShellActionBase.class);
+
+ public static final Key<Boolean> GROOVY_SHELL_FILE = Key.create("GROOVY_SHELL_FILE");
+ private static final String GROOVY_SHELL_LAST_MODULE = "Groovy.Shell.LastModule";
+
+ private static List<Module> getGroovyCompatibleModules(Project project) {
+ ArrayList<Module> result = new ArrayList<Module>();
+ for (Module module : ModuleManager.getInstance(project).getModules()) {
+ if (GroovyUtils.isSuitableModule(module)) {
+ Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
+ if (sdk != null && sdk.getSdkType() instanceof JavaSdkType) {
+ result.add(module);
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ final Project project = e.getData(CommonDataKeys.PROJECT);
+
+ boolean enabled = project != null && !getGroovyCompatibleModules(project).isEmpty();
+
+ e.getPresentation().setEnabled(enabled);
+ e.getPresentation().setVisible(enabled);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final Project project = e.getData(CommonDataKeys.PROJECT);
+ assert project != null;
+
+ CompilerManager.getInstance(project).make(new CompileStatusNotification() {
+ @Override
+ public void finished(boolean aborted, int errors, int warnings, CompileContext compileContext) {
+ if (aborted) return;
+
+ final Project project = compileContext.getProject();
+
+ if (errors == 0 ||
+ Messages.showYesNoDialog(project, "Compilation failed with errors. Do you want to run " + getTitle() + " anyway?", getTitle(),
+ JetgroovyIcons.Groovy.Groovy_32x32) == Messages.YES) {
+ runGroovyShell(project);
+ }
+ }
+ });
+ }
+
+ private void runGroovyShell(Project project) {
+ List<Module> modules = new ArrayList<Module>();
+ final Map<Module, String> versions = new HashMap<Module, String>();
+
+ for (Module module : getGroovyCompatibleModules(project)) {
+ GroovyShellRunner runner = GroovyShellRunner.getAppropriateRunner(module);
+ if (runner != null) {
+ modules.add(module);
+ versions.put(module, runner.getTitle(module));
+ }
+ }
+
+ if (modules.size() == 1) {
+ doRun(modules.get(0));
+ return;
+ }
+
+ Collections.sort(modules, ModulesAlphaComparator.INSTANCE);
+
+ BaseListPopupStep<Module> step =
+ new BaseListPopupStep<Module>("Which module to use classpath of?", modules, PlatformIcons.CONTENT_ROOT_ICON_CLOSED) {
+ @NotNull
+ @Override
+ public String getTextFor(Module value) {
+ return value.getName() + versions.get(value);
+ }
+
+ @Override
+ public String getIndexedString(Module value) {
+ return value.getName();
+ }
+
+ @Override
+ public boolean isSpeedSearchEnabled() {
+ return true;
+ }
+
+ @Override
+ public PopupStep onChosen(Module selectedValue, boolean finalChoice) {
+ PropertiesComponent.getInstance(selectedValue.getProject()).setValue(GROOVY_SHELL_LAST_MODULE, selectedValue.getName());
+ doRun(selectedValue);
+ return null;
+ }
+ };
+
+ for (int i = 0; i < modules.size(); i++) {
+ Module module = modules.get(i);
+ if (module.getName().equals(PropertiesComponent.getInstance(project).getValue(GROOVY_SHELL_LAST_MODULE))) {
+ step.setDefaultOptionIndex(i);
+ break;
+ }
+ }
+ JBPopupFactory.getInstance().createListPopup(step).showCenteredInCurrentWindow(project);
+ }
+
+ protected void doRun(final Module module) {
+ final GroovyShellRunner shellRunner = getRunner(module);
+ if (shellRunner == null) return;
+
+ AbstractConsoleRunnerWithHistory<LanguageConsoleView> runner = new GroovyConsoleRunner(getTitle(), shellRunner, module, "Groovy.Shell.Execute");
+ try {
+ runner.initAndRun();
+ }
+ catch (ExecutionException e) {
+ LOG.info(e);
+ Messages.showErrorDialog(module.getProject(), e.getMessage(), "Cannot Run " + getTitle());
+ }
+ }
+
+ protected abstract GroovyShellRunner getRunner(Module module);
+
+ public abstract String getTitle();
+
+ protected abstract LanguageConsoleImpl createConsole(Project project, String title);
+
+ private class GroovyConsoleRunner extends AbstractConsoleRunnerWithHistory<LanguageConsoleView> {
+ private final String myEmptyExecuteAction;
+ private GroovyShellRunner myShellRunner;
+ private Module myModule;
+
+ private GroovyConsoleRunner(@NotNull String consoleTitle,
+ @NotNull GroovyShellRunner shellRunner,
+ @NotNull Module module,
+ @NotNull String emptyExecuteAction) {
+ super(module.getProject(), consoleTitle, shellRunner.getWorkingDirectory(module));
+ myShellRunner = shellRunner;
+ myModule = module;
+ myEmptyExecuteAction = emptyExecuteAction;
+ }
+
+ @Override
+ protected LanguageConsoleView createConsoleView() {
+ LanguageConsoleView res = new LanguageConsoleViewImpl(createConsole(getProject(), getConsoleTitle()));
+
+ GroovyFileImpl file = (GroovyFileImpl)res.getConsole().getFile();
+ assert file.getContext() == null;
+ file.putUserData(GROOVY_SHELL_FILE, Boolean.TRUE);
+
+ file.setContext(myShellRunner.getContext(myModule));
+
+ return res;
+ }
+
+ @Override
+ protected Process createProcess() throws ExecutionException {
+ JavaParameters javaParameters = myShellRunner.createJavaParameters(myModule);
+
+ final Sdk sdk = ModuleRootManager.getInstance(myModule).getSdk();
+ assert sdk != null;
+ SdkTypeId sdkType = sdk.getSdkType();
+ assert sdkType instanceof JavaSdkType;
+ final String exePath = ((JavaSdkType)sdkType).getVMExecutablePath(sdk);
+
+ return JdkUtil.setupJVMCommandLine(exePath, javaParameters, true).createProcess();
+ }
+
+ @Override
+ protected OSProcessHandler createProcessHandler(Process process) {
+ return new OSProcessHandler(process);
+ }
+
+ @NotNull
+ @Override
+ protected ConsoleExecuteActionHandler createConsoleExecuteActionHandler() {
+ ConsoleExecuteActionHandler handler = new ConsoleExecuteActionHandler(getProcessHandler(), false) {
+ @Override
+ public void processLine(String line) {
+ super.processLine(myShellRunner.transformUserInput(line));
+ }
+
+ @Override
+ public String getEmptyExecuteAction() {
+ return myEmptyExecuteAction;
+ }
+ };
+ new ConsoleHistoryController(getConsoleTitle(), null, getLanguageConsole(), handler.getConsoleHistoryModel()).install();
+ return handler;
+ }
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java
index 55286f6..c105fc6c 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java
@@ -526,7 +526,7 @@
if (myType2 == mSEMI) return;
if (typeDefinitionBody != null) { //check variable definitions only inside class body
- if ((myType1 == VARIABLE_DEFINITION || isSemiAfter(VARIABLE_DEFINITION)) && METHOD_DEFS.contains(myType2)) {
+ if ((myType1 == VARIABLE_DEFINITION || isSemiAfter(VARIABLE_DEFINITION)) && TokenSets.METHOD_DEFS.contains(myType2)) {
final int minBlankLines = Math.max(
isInterface ? mySettings.BLANK_LINES_AROUND_METHOD_IN_INTERFACE : mySettings.BLANK_LINES_AROUND_METHOD,
isInterface ? mySettings.BLANK_LINES_AROUND_FIELD_IN_INTERFACE : mySettings.BLANK_LINES_AROUND_FIELD
@@ -542,15 +542,30 @@
}
}
- if (METHOD_DEFS.contains(myType1) || isSemiAfter(METHOD_DEFS) || METHOD_DEFS.contains((myType2))) {
+ if (TokenSets.METHOD_DEFS.contains(myType1) || isSemiAfter(TokenSets.METHOD_DEFS) || TokenSets.METHOD_DEFS.contains((myType2))) {
if (myType1 == GROOVY_DOC_COMMENT) {
createLF(true);
+ return;
}
else {
final int minBlankLines = isInterface ? mySettings.BLANK_LINES_AROUND_METHOD_IN_INTERFACE : mySettings.BLANK_LINES_AROUND_METHOD;
myResult = Spacing.createSpacing(0, 0, minBlankLines + 1, mySettings.KEEP_LINE_BREAKS, keepBlankLines());
+ return;
}
}
+
+ if (TokenSets.TYPE_DEFINITIONS.contains(myType1) || isSemiAfter(TokenSets.TYPE_DEFINITIONS) || TokenSets.TYPE_DEFINITIONS.contains((myType2)) ) {
+ if (myType1 == GROOVY_DOC_COMMENT) {
+ createLF(true);
+ return;
+ }
+ else {
+ final int minBlankLines = mySettings.BLANK_LINES_AROUND_CLASS;
+ myResult = Spacing.createSpacing(0, 0, minBlankLines + 1, mySettings.KEEP_LINE_BREAKS, keepBlankLines());
+ return;
+ }
+
+ }
}
@Override
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovyWrappingProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovyWrappingProcessor.java
index 272540d..67281f0 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovyWrappingProcessor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovyWrappingProcessor.java
@@ -255,7 +255,7 @@
return mySettings.CLASS_ANNOTATION_WRAP;
}
- if (METHOD_DEFS.contains(containerType)) {
+ if (TokenSets.METHOD_DEFS.contains(containerType)) {
return mySettings.METHOD_ANNOTATION_WRAP;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonFramework.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonFramework.java
index 9808af8..0499c68 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonFramework.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonFramework.java
@@ -36,24 +36,25 @@
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.IgnoredBeanFactory;
-import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
+import com.intellij.util.containers.MultiMap;
import gnu.trove.TIntArrayList;
import icons.JetgroovyIcons;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import org.jetbrains.plugins.groovy.GroovyFileType;
import org.jetbrains.plugins.groovy.mvc.*;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -76,7 +77,7 @@
}
public boolean hasSupport(@NotNull Module module) {
- return getSdkRoot(module) != null && findAppRoot(module) != null && !isAuxModule(module);
+ return findAppRoot(module) != null && !isAuxModule(module) && getSdkRoot(module) != null;
}
@Override
@@ -417,6 +418,11 @@
}
private static class GriffonProjectStructure extends MvcProjectStructure {
+
+ public static final String[] TEST_DIRS = new String[]{"unit", "integration", "shared"};
+ public static final String[] SRC_DIR_SUBFOLDER = new String[]{"main", "cli"};
+ public static final String[] GRIFFON_APP_SOURCE_ROOTS = new String[]{"models", "views", "controllers", "services", "conf", "lifecycle"};
+
public GriffonProjectStructure(Module module, final boolean auxModule) {
super(module, auxModule, getUserHomeGriffon(), GriffonFramework.getInstance().getSdkWorkDir(module));
}
@@ -426,65 +432,51 @@
return GRIFFON_USER_LIBRARY;
}
- public String[] getSourceFolders() {
- List<String> sourceFolders = new ArrayList<String>();
+ public MultiMap<JpsModuleSourceRootType<?>, String> getSourceFolders() {
+ MultiMap<JpsModuleSourceRootType<?>, String> res = new MultiMap<JpsModuleSourceRootType<?>, String>();
- for (VirtualFile file : ModuleRootManager.getInstance(myModule).getContentRoots()) {
- handleSrc(file.findChild("src"), sourceFolders);
- VirtualFile griffonApp = file.findChild("griffon-app");
- handleGriffonApp(griffonApp, sourceFolders);
- List<GriffonSourceInspector.GriffonSource> sources =
- GriffonSourceInspector.processModuleMetadata(myModule);
- for (GriffonSourceInspector.GriffonSource source : sources) {
- sourceFolders.add(source.getPath());
+ for (VirtualFile root : ModuleRootManager.getInstance(myModule).getContentRoots()) {
+ VirtualFile srcDir = root.findChild("src");
+ if (srcDir != null) {
+ for (String child : SRC_DIR_SUBFOLDER) {
+ if (srcDir.findChild(child) != null) {
+ res.putValue(JavaSourceRootType.SOURCE, "src/" + child);
+ }
+ }
}
+
+ VirtualFile griffonApp = root.findChild("griffon-app");
if (griffonApp != null) {
- for (VirtualFile child : file.getChildren()) {
+ for (String child : GRIFFON_APP_SOURCE_ROOTS) {
+ if (griffonApp.findChild(child) != null) {
+ res.putValue(JavaSourceRootType.SOURCE, "griffon-app/" + child);
+ }
+ }
+
+ for (VirtualFile child : root.getChildren()) {
if (child.getNameWithoutExtension().endsWith("GriffonAddon")) {
- sourceFolders.add("");
+ res.putValue(JavaSourceRootType.SOURCE, "");
break;
}
}
}
- }
- return sourceFolders.toArray(new String[sourceFolders.size()]);
- }
- private void handleGriffonApp(VirtualFile griffonApp, List<String> sourceFolders) {
- if (griffonApp == null) return;
- // Add standard artifacts, i.e, models, views, controllers, services, conf, lifecycle
- for (String child : new String[]{"models", "views", "controllers", "services", "conf", "lifecycle"}) {
- if (griffonApp.findChild(child) != null) {
- sourceFolders.add("griffon-app/" + child);
+ List<GriffonSourceInspector.GriffonSource> sources = GriffonSourceInspector.processModuleMetadata(myModule);
+ for (GriffonSourceInspector.GriffonSource source : sources) {
+ res.putValue(JavaSourceRootType.SOURCE, source.getPath());
+ }
+
+ VirtualFile testDir = root.findChild("test");
+ if (testDir != null) {
+ for (String child : TEST_DIRS) {
+ if (testDir.findChild(child) != null) {
+ res.putValue(JavaSourceRootType.TEST_SOURCE, "test/" + child);
+ }
+ }
}
}
- }
- private void handleSrc(VirtualFile src, List<String> sourceFolders) {
- if (src == null) return;
- for (String child : new String[]{"main", "cli"}) {
- if (src.findChild(child) != null) {
- sourceFolders.add("src/" + child);
- }
- }
- }
-
- private void handleTest(VirtualFile test, List<String> sourceFolders) {
- if (test == null) return;
- for (String child : new String[]{"unit", "integration", "shared"}) {
- if (test.findChild(child) != null) {
- sourceFolders.add("test/" + child);
- }
- }
- }
-
- public String[] getTestFolders() {
- List<String> sourceFolders = new ArrayList<String>();
-
- for (VirtualFile file : ModuleRootManager.getInstance(myModule).getContentRoots()) {
- handleTest(file.findChild("test"), sourceFolders);
- }
- return sourceFolders.toArray(new String[sourceFolders.size()]);
+ return res;
}
public String[] getInvalidSourceFolders() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovySlashyStringLexer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovySlashyStringLexer.java
index 01e9127..65ec015 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovySlashyStringLexer.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovySlashyStringLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.StringEscapesTokenTypes;
import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
@@ -41,7 +42,7 @@
}
@Override
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
if (buffer.length()<endOffset) {
LogMessageEx.error(LOG, "buffer Length: " + buffer.length() + ", endOffset: " + endOffset, buffer.toString());
}
@@ -107,6 +108,7 @@
myTokenType = locateToken();
}
+ @NotNull
@Override
public CharSequence getBufferSequence() {
return myBuffer;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitElseIfIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitElseIfIntention.java
index 497b269..3773b97 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitElseIfIntention.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitElseIfIntention.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,8 +21,9 @@
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.intentions.base.Intention;
-import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils;
import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrBlockStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
@@ -33,11 +34,17 @@
return new SplitElseIfPredicate();
}
- public void processIntention(@NotNull PsiElement element, Project project, Editor editor)
- throws IncorrectOperationException {
+ public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException {
final GrIfStatement parentStatement = (GrIfStatement) element;
final GrStatement elseBranch = parentStatement.getElseBranch();
- IntentionUtils.replaceStatement("if(" + parentStatement.getCondition().getText()+ ")"+ parentStatement.getThenBranch().getText() +
- "else{\n" + elseBranch.getText() +"\n}", parentStatement);
+
+ GrIfStatement ifStatement = (GrIfStatement)parentStatement.copy();
+
+ GrBlockStatement blockStatement = GroovyPsiElementFactory.getInstance(project).createBlockStatementFromText("{\nabc()\n}", null);
+ GrBlockStatement newBlock = ifStatement.replaceElseBranch(blockStatement);
+
+ newBlock.getBlock().getStatements()[0].replace(elseBranch);
+
+ parentStatement.replaceWithStatement(ifStatement);
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionConfidence.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionConfidence.java
index bae24c8..2a178ea 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionConfidence.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionConfidence.java
@@ -1,9 +1,12 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.
@@ -12,6 +15,7 @@
*/
package org.jetbrains.plugins.groovy.lang.completion;
+import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.completion.CompletionConfidence;
import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.patterns.ElementPattern;
@@ -21,6 +25,7 @@
import com.intellij.util.ThreeState;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.console.GroovyShellAction;
+import org.jetbrains.plugins.groovy.console.GroovyShellActionBase;
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector;
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
@@ -70,7 +75,7 @@
final GrExpression qualifier = ref.getQualifierExpression();
if (qualifier == null) {
if (isPossibleClosureParameter(ref)) return ThreeState.NO;
- if (parameters.getOriginalFile().getUserData(GroovyShellAction.GROOVY_SHELL_FILE) == Boolean.TRUE) {
+ if (parameters.getOriginalFile().getUserData(GroovyShellActionBase.GROOVY_SHELL_FILE) == Boolean.TRUE) {
return ThreeState.NO;
}
@@ -93,6 +98,10 @@
@NotNull
@Override
public ThreeState shouldSkipAutopopup(@NotNull PsiElement contextElement, @NotNull PsiFile psiFile, int offset) {
+ if (CodeInsightSettings.getInstance().SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS && psiFile.getUserData(GroovyShellAction.GROOVY_SHELL_FILE) == Boolean.TRUE) {
+ return ThreeState.YES;
+ }
+
if (com.intellij.psi.impl.PsiImplUtil.isLeafElementOfType(contextElement, TokenSets.STRING_LITERALS)) {
@SuppressWarnings("ConstantConditions")
PsiElement parent = contextElement.getParent();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/lexer/GroovyDocLexer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/lexer/GroovyDocLexer.java
index 6bfba48..b60cce1 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/lexer/GroovyDocLexer.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/lexer/GroovyDocLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.text.CharArrayUtil;
+import org.jetbrains.annotations.NotNull;
import java.io.IOException;
@@ -87,7 +88,7 @@
myFlexLexer = lexer;
}
- public final void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public final void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
myBuffer = buffer;
myBufferIndex = startOffset;
myBufferEndOffset = endOffset;
@@ -100,6 +101,7 @@
return myState;
}
+ @NotNull
public CharSequence getBufferSequence() {
return myBuffer;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java
index d2505b9..1285548 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java
@@ -74,7 +74,7 @@
mDOLLAR_SLASH_REGEX_LITERAL
);
- public static final TokenSet BUILT_IN_TYPE = TokenSet.create(
+ public static final TokenSet BUILT_IN_TYPES = TokenSet.create(
kVOID,
kBOOLEAN,
kBYTE,
@@ -217,4 +217,10 @@
public static final TokenSet CODE_REFERENCE_ELEMENT_NAME_TOKENS = TokenSet.create(mIDENT, kDEF, kIN, kAS);
public static final TokenSet BLOCK_SET = TokenSet.create(CLOSABLE_BLOCK, BLOCK_STATEMENT, CONSTRUCTOR_BODY, OPEN_BLOCK, ENUM_BODY, CLASS_BODY);
+ public static final TokenSet METHOD_DEFS = TokenSet.create(METHOD_DEFINITION, CONSTRUCTOR_DEFINITION, ANNOTATION_METHOD);
+ public static final TokenSet VARIABLES = TokenSet.create(VARIABLE, FIELD);
+ public static final TokenSet TYPE_ELEMENTS = TokenSet.create(CLASS_TYPE_ELEMENT, ARRAY_TYPE, BUILT_IN_TYPE, TYPE_ARGUMENT, DISJUNCTION_TYPE_ELEMENT);
+
+
+ public static final TokenSet TYPE_DEFINITIONS = TokenSet.create(CLASS_DEFINITION, ENUM_DEFINITION, INTERFACE_DEFINITION, ANNOTATION_DEFINITION);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java
index cbf640c..699393b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java
@@ -18,7 +18,6 @@
import com.intellij.lang.ASTNode;
import com.intellij.psi.stubs.*;
-import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.io.StringRef;
import org.jetbrains.annotations.NotNull;
@@ -420,7 +419,6 @@
return new GrVariableDeclarationImpl(stub);
}
};
- IElementType MULTIPLE_VARIABLE_DEFINITION = new GroovyElementType("multivariable definition");
GroovyElementType TUPLE_DECLARATION = new GroovyElementType("tuple declaration");
GroovyElementType TUPLE_EXPRESSION = new GroovyElementType("tuple expression");
@@ -433,9 +431,4 @@
//types
GroovyElementType CLASS_TYPE_ELEMENT = new GroovyElementType("class type element"); //node
-
- TokenSet METHOD_DEFS = TokenSet.create(METHOD_DEFINITION, CONSTRUCTOR_DEFINITION, ANNOTATION_METHOD);
- TokenSet VARIABLES = TokenSet.create(VARIABLE, FIELD);
- TokenSet TYPE_ELEMENTS = TokenSet.create(CLASS_TYPE_ELEMENT, ARRAY_TYPE, BUILT_IN_TYPE, TYPE_ARGUMENT, DISJUNCTION_TYPE_ELEMENT);
-
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParserDefinition.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParserDefinition.java
index bcde7ee..bb1ba34 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParserDefinition.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParserDefinition.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -99,6 +99,8 @@
if (lType == mNLS || lType == mGDOC_COMMENT_START) {
return MAY;
}
+ if (lType == mGT) return MUST;
+ if (rType == mLT) return MUST;
final IElementType parentType = left.getTreeParent().getElementType();
if (parentType == GSTRING ||
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.java
index 16328d8f..5fb6053 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -68,7 +68,7 @@
Modifiers.parse(builder, parser);
- boolean isBuiltInType = TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType());
+ boolean isBuiltInType = TokenSets.BUILT_IN_TYPES.contains(builder.getTokenType());
PsiBuilder.Marker typeSpec = builder.mark();
TypeSpec.parseStrict(builder, false);
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/Declaration.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/Declaration.java
index 7642ef0..195a58a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/Declaration.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/Declaration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -134,7 +134,7 @@
private static boolean isCall(@NotNull PsiBuilder builder) {
if (builder.eof()) return false;
- if (TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType())) return false;
+ if (TokenSets.BUILT_IN_TYPES.contains(builder.getTokenType())) return false;
final String text = builder.getTokenText();
if (StringUtil.isEmpty(text)) return false;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/UnaryExpressionNotPlusMinus.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/UnaryExpressionNotPlusMinus.java
index 44f9fa6..c4dc86f 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/UnaryExpressionNotPlusMinus.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/UnaryExpressionNotPlusMinus.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -69,7 +69,7 @@
marker.rollbackTo();
return FAIL;
}
- if (TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType()) || mIDENT.equals(builder.getTokenType())) {
+ if (TokenSets.BUILT_IN_TYPES.contains(builder.getTokenType()) || mIDENT.equals(builder.getTokenType())) {
final ReferenceElement.ReferenceElementResult result = TypeSpec.parseStrict(builder, true);
if (result == FAIL) {
marker.rollbackTo();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java
index 59ff837..f785fe6 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java
@@ -43,7 +43,7 @@
public static IElementType parsePrimaryExpression(PsiBuilder builder, GroovyParser parser, boolean literalsAsRefExprs) {
final IElementType tokenType = builder.getTokenType();
- if (TokenSets.BUILT_IN_TYPE.contains(tokenType)) {
+ if (TokenSets.BUILT_IN_TYPES.contains(tokenType)) {
ParserUtils.eatElement(builder, BUILT_IN_TYPE_EXPRESSION);
return BUILT_IN_TYPE_EXPRESSION;
}
@@ -110,7 +110,7 @@
ParserUtils.getToken(builder, mNLS);
PsiBuilder.Marker rb = builder.mark();
TypeArguments.parseTypeArguments(builder, false);
- if (!TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType()) && mIDENT != builder.getTokenType()) {
+ if (!TokenSets.BUILT_IN_TYPES.contains(builder.getTokenType()) && mIDENT != builder.getTokenType()) {
rb.rollbackTo();
}
else {
@@ -119,7 +119,7 @@
PsiBuilder.Marker anonymousMarker = builder.mark();
String name = null;
- if (TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType())) {
+ if (TokenSets.BUILT_IN_TYPES.contains(builder.getTokenType())) {
ParserUtils.eatElement(builder, BUILT_IN_TYPE);
}
else if (TokenSets.CODE_REFERENCE_ELEMENT_NAME_TOKENS.contains(builder.getTokenType())) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeSpec.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeSpec.java
index ff293ed..3f936b1 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeSpec.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeSpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@
}
public static ReferenceElementResult parse(PsiBuilder builder, boolean isUpper, final boolean expressionPossible) {
- if (TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType())) {
+ if (TokenSets.BUILT_IN_TYPES.contains(builder.getTokenType())) {
return parseBuiltInType(builder);
}
if (builder.getTokenType() == mIDENT) {
@@ -117,7 +117,7 @@
* @return
*/
public static ReferenceElementResult parseStrict(PsiBuilder builder, boolean expressionPossible) {
- if (TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType())) {
+ if (TokenSets.BUILT_IN_TYPES.contains(builder.getTokenType())) {
return parseBuiltInTypeStrict(builder);
}
else if (builder.getTokenType() == mIDENT) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrQualifiedReference.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrQualifiedReference.java
index 5d0369d..bb48e12 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrQualifiedReference.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrQualifiedReference.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package org.jetbrains.plugins.groovy.lang.psi;
import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiQualifiedReference;
import com.intellij.psi.PsiQualifiedReferenceElement;
import org.jetbrains.annotations.Nullable;
@@ -31,4 +30,6 @@
@Nullable
PsiElement getReferenceNameElement();
+
+ boolean isQualified();
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyFileBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyFileBase.java
index 9162723..7bbd22b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyFileBase.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyFileBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,7 +53,7 @@
GrTopLevelDefinition[] getTopLevelDefinitions();
- GrMethod[] getTopLevelMethods();
+ GrMethod[] getCodeMethods();
GrMethod[] getMethods();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrReferenceExpression.java
index 0781a02..91c4c31 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrReferenceExpression.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrReferenceExpression.java
@@ -32,8 +32,6 @@
@Nullable
GrExpression getQualifierExpression();
- boolean isQualified();
-
@Nullable
IElementType getDotTokenType();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrSuperReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrSuperReferenceExpression.java
deleted file mode 100644
index e140a96..0000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrSuperReferenceExpression.java
+++ /dev/null
@@ -1,8 +0,0 @@
-
-package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions;
-
-/**
- * @author ilyas
- */
-public interface GrSuperReferenceExpression extends GrThisSuperReferenceExpression {
-}
\ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisReferenceExpression.java
deleted file mode 100644
index 7e6f3f7..0000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisReferenceExpression.java
+++ /dev/null
@@ -1,8 +0,0 @@
-
-package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions;
-
-/**
- * @author ilyas
- */
-public interface GrThisReferenceExpression extends GrThisSuperReferenceExpression {
-}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java
deleted file mode 100644
index 3284a9c..0000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2000-2010 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions;
-
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiPolyVariantReference;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference;
-
-/**
- * @author Maxim.Medvedev
- */
-public interface GrThisSuperReferenceExpression extends GrExpression, PsiPolyVariantReference, GrQualifiedReference<GrReferenceExpression> {
- @NotNull
- @Override
- PsiElement getReferenceNameElement();
-
- @NotNull
- @Override
- String getReferenceName();
-}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrReferenceElementImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrReferenceElementImpl.java
index 5295cf3..ada7e75 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrReferenceElementImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrReferenceElementImpl.java
@@ -86,7 +86,7 @@
newNameNode = factory.createLiteralFromValue(newElementName).getFirstChild().getNode();
}
assert newNameNode != null && node != null;
- node.getTreeParent().replaceChild(node, newNameNode);
+ getNode().replaceChild(node, newNameNode);
}
return this;
@@ -191,4 +191,7 @@
return whiteSpaceAndComments;
}
+ public boolean isQualified() {
+ return getQualifier() != null;
+ }
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileBaseImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileBaseImpl.java
index eae43a0..9641abf 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileBaseImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileBaseImpl.java
@@ -104,7 +104,7 @@
return findChildrenByClass(GrTopLevelDefinition.class);
}
- public GrMethod[] getTopLevelMethods() {
+ public GrMethod[] getCodeMethods() {
final StubElement<?> stub = getStub();
if (stub != null) {
return stub.getChildrenByType(GroovyElementTypes.METHOD_DEFINITION, GrMethod.ARRAY_FACTORY);
@@ -118,7 +118,7 @@
if (myMethods == null) {
List<GrMethod> result = new ArrayList<GrMethod>();
- GrMethod[] methods = getTopLevelMethods();
+ GrMethod[] methods = getCodeMethods();
for (GrMethod method : methods) {
final GrReflectedMethod[] reflectedMethods = method.getReflectedMethods();
if (reflectedMethods.length > 0) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java
index 2084a80..c482aea 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java
@@ -194,6 +194,14 @@
}
}
+ if (owner instanceof GrMethod && owner.getParent() instanceof GrTypeDefinitionBody) {
+ PsiElement parent = owner.getParent().getParent();
+ if (parent instanceof PsiClass && ((PsiClass)parent).isInterface()) {
+ if (GrModifier.ABSTRACT.equals(modifier)) return true;
+ if (GrModifier.PUBLIC.equals(modifier)) return true;
+ }
+ }
+
if (modifierList.hasExplicitModifier(modifier)) {
return true;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java
index 688fad5..1ab1a1a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java
@@ -30,6 +30,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
+import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
@@ -184,7 +185,7 @@
@NotNull
public GrVariable[] getVariables() {
- return getStubOrPsiChildren(GroovyElementTypes.VARIABLES, GrVariable.ARRAY_FACTORY);
+ return getStubOrPsiChildren(TokenSets.VARIABLES, GrVariable.ARRAY_FACTORY);
}
public boolean processDeclarations(@NotNull PsiScopeProcessor processor,
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java
index 7bfdf31..583ba9b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java
@@ -857,10 +857,6 @@
return findExpressionChild(this);
}
- public boolean isQualified() {
- return getQualifierExpression() != null;
- }
-
@Nullable
public PsiElement getDotToken() {
return findChildByType(TokenSets.DOTS);
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java
deleted file mode 100644
index 61365ae..0000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java
+++ /dev/null
@@ -1,118 +0,0 @@
-
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
-
-import com.intellij.lang.ASTNode;
-import com.intellij.psi.*;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.util.NullableFunction;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
-import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
-import org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil;
-
-/**
- * @author ilyas
- */
-public class GrSuperReferenceExpressionImpl extends GrThisSuperReferenceExpressionBase implements GrSuperReferenceExpression {
-
- private static final NullableFunction<GrSuperReferenceExpressionImpl, PsiType> TYPE_CALCULATOR =
- new NullableFunction<GrSuperReferenceExpressionImpl, PsiType>() {
- @Override
- public PsiType fun(GrSuperReferenceExpressionImpl ref) {
- final GrReferenceExpression qualifier = ref.getQualifier();
- if (qualifier == null) {
- GroovyPsiElement context = PsiTreeUtil.getParentOfType(ref, GrTypeDefinition.class, GroovyFileBase.class);
- if (context instanceof GrTypeDefinition) {
- final PsiClass superClass = ((GrTypeDefinition)context).getSuperClass();
- if (superClass != null) {
- return JavaPsiFacade.getInstance(ref.getProject()).getElementFactory().createType(superClass);
- }
- }
- else if (context instanceof GroovyFileBase) {
- PsiClass scriptClass = ((GroovyFileBase)context).getScriptClass();
- if (scriptClass != null) {
- PsiClass superClass = scriptClass.getSuperClass();
- if (superClass != null) {
- return JavaPsiFacade.getInstance(ref.getProject()).getElementFactory().createType(superClass);
- }
- }
- return GrClassImplUtil.getGroovyObjectType(ref);
- }
- }
- else {
- final PsiElement resolved = qualifier.resolve();
- if (resolved instanceof PsiClass) {
- return ref.getSuperType((PsiClass)resolved);
- }
- }
- return null;
- }
- };
-
- public GrSuperReferenceExpressionImpl(@NotNull ASTNode node) {
- super(node);
- }
-
- public void accept(GroovyElementVisitor visitor) {
- }
-
- public String toString() {
- return "'super' reference expression";
- }
-
- public PsiType getType() {
- return TypeInferenceHelper.getCurrentContext().getExpressionType(this, TYPE_CALCULATOR);
-
- }
-
- @Nullable
- private PsiType getSuperType(PsiClass aClass) {
- if (aClass.isInterface()) {
- return PsiType.getJavaLangObject(getManager(), getResolveScope());
- }
- if (aClass instanceof GrAnonymousClassDefinition) {
- final PsiClassType baseClassType = ((GrAnonymousClassDefinition)aClass).getBaseClassType();
- final PsiClass psiClass = baseClassType.resolve();
- if (psiClass != null && !psiClass.isInterface()) {
- return baseClassType;
- }
-
- return PsiType.getJavaLangObject(getManager(), getResolveScope());
- }
-
- if (CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) return null;
- PsiClassType[] superTypes = aClass.getExtendsListTypes();
- if (superTypes.length == 0) {
- return PsiType.getJavaLangObject(getManager(), getResolveScope());
- }
-
- return superTypes[0];
- }
-
- @Override
- public String getReferenceName() {
- return "super";
- }
-}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java
deleted file mode 100644
index 88ab149..0000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
-* Copyright 2000-2011 JetBrains s.r.o.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
-
-import com.intellij.lang.ASTNode;
-import com.intellij.psi.*;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.NullableFunction;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
-import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
-import org.jetbrains.plugins.groovy.lang.psi.util.StaticChecker;
-
-/**
- * @author ilyas
- */
-public class GrThisReferenceExpressionImpl extends GrThisSuperReferenceExpressionBase implements GrThisReferenceExpression {
-
- private static final NullableFunction<GrThisReferenceExpressionImpl, PsiType> TYPE_CALCULATOR =
- new NullableFunction<GrThisReferenceExpressionImpl, PsiType>() {
- @Override
- public PsiType fun(GrThisReferenceExpressionImpl ref) {
- if (ref.getQualifier() == null) {
- return resolveNonQualified(ref);
- }
- else {
- return resolveQualified(ref);
- }
- }
-
- @Nullable
- private PsiType resolveQualified(GrThisReferenceExpressionImpl ref) {
- GrReferenceExpression qualifier = ref.getQualifier();
- assert qualifier != null;
- final PsiElement resolved = qualifier.resolve();
- try {
- PsiElementFactory factory = JavaPsiFacade.getElementFactory(ref.getProject());
- if (resolved instanceof PsiClass) {
- return factory.createType((PsiClass)resolved);
- }
- else {
- return factory.createTypeFromText(qualifier.getText(), ref);
- }
- }
- catch (IncorrectOperationException e) {
- return null;
- }
- }
-
- @Nullable
- private PsiType resolveNonQualified(GrThisReferenceExpressionImpl ref) {
- PsiClass context = PsiUtil.getContextClass(ref);
- if (context != null) {
- return ref.createType(context);
- }
- else {
- return null;
- }
- }
- };
-
- public GrThisReferenceExpressionImpl(@NotNull ASTNode node) {
- super(node);
- }
-
- public void accept(GroovyElementVisitor visitor) {
- }
-
- public String toString() {
- return "'this' reference expression";
- }
-
- public PsiType getType() {
- return TypeInferenceHelper.getCurrentContext().getExpressionType(this, TYPE_CALCULATOR);
- }
-
- private PsiType createType(@NotNull PsiClass context) {
- final JavaPsiFacade facade = JavaPsiFacade.getInstance(context.getProject());
- PsiElementFactory elementFactory = facade.getElementFactory();
-
- if (!StaticChecker.isInStaticContext(this)) return elementFactory.createType(context);
-
- //create instance of java.lang.Class<CurrentClass>
- if (context instanceof PsiAnonymousClass) {
- final PsiClassType type = ((PsiAnonymousClass)context).getBaseClassType();
- final PsiClass aClass = facade.findClass(CommonClassNames.JAVA_LANG_CLASS, context.getResolveScope());
- if (aClass != null) {
- return elementFactory.createType(aClass, type);
- }
- else {
- return elementFactory.createTypeFromText(CommonClassNames.JAVA_LANG_CLASS + "<" + type.getCanonicalText() + ">", this);
- }
- }
- return elementFactory.createTypeFromText(CommonClassNames.JAVA_LANG_CLASS + "<" + context.getName() + ">", this);
- }
-
- @NotNull
- @Override
- public String getReferenceName() {
- return "this";
- }
-
- @Override
- protected PsiElement resolveInner() {
- final PsiElement resolved = super.resolveInner();
- if (resolved != null) return resolved;
- final GrReferenceExpression qualifier = getQualifier();
- if (qualifier != null) {
- return qualifier.resolve();
- }
-
- return PsiUtil.getContextClass(this);
- }
-}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java
deleted file mode 100644
index 15e0ea7..0000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
-
-import com.intellij.lang.ASTNode;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiReference;
-import com.intellij.psi.ResolveResult;
-import com.intellij.psi.impl.source.resolve.ResolveCache;
-import com.intellij.psi.tree.TokenSet;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.IncorrectOperationException;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
-import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
-import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
-import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
-import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
-
-/**
- * @author Maxim.Medvedev
- */
-public abstract class GrThisSuperReferenceExpressionBase extends GrExpressionImpl implements GrThisSuperReferenceExpression {
- private static final OurResolver OUR_RESOLVER = new OurResolver();
-
- public GrThisSuperReferenceExpressionBase(ASTNode node) {
- super(node);
- }
-
- @Nullable
- public GrReferenceExpression getQualifier() {
- return (GrReferenceExpression)findChildByType(GroovyElementTypes.REFERENCE_EXPRESSION);
- }
-
- @Override
- public void setQualifier(@Nullable GrReferenceExpression newQualifier) {
- PsiImplUtil.setQualifier(this, newQualifier);
- }
-
- @NotNull
- @Override
- public PsiElement getReferenceNameElement() {
- return getLastChild();
- }
-
- @Override
- public PsiElement getElement() {
- return this;
- }
-
- @Override
- public TextRange getRangeInElement() {
- final PsiElement token = findNotNullChildByType(TokenSet.create(GroovyTokenTypes.kTHIS, GroovyTokenTypes.kSUPER));
- return TextRange.from(token.getStartOffsetInParent(), token.getTextLength());
- }
-
- @Override
- public PsiElement resolve() {
- final ResolveResult[] results = TypeInferenceHelper.getCurrentContext().multiResolve(this, false, OUR_RESOLVER);
- if (results.length == 1) return results[0].getElement();
- return null;
- }
-
- @Nullable
- protected PsiElement resolveInner() {
- final PsiElement parent = getParent();
- if (parent instanceof GrConstructorInvocation) {
- return ((GrConstructorInvocation)parent).resolveMethod();
- }
- return null;
- }
-
- public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
- return this;
- }
-
- public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
- return this;
- }
-
- public boolean isReferenceTo(PsiElement element) {
- return getManager().areElementsEquivalent(element, resolve());
- }
-
- @NotNull
- public Object[] getVariants() {
- return ArrayUtil.EMPTY_OBJECT_ARRAY;
- }
-
- public boolean isSoft() {
- return false;
- }
-
- @Override
- public PsiReference getReference() {
- return this;
- }
-
- @NotNull
- public ResolveResult[] multiResolve(boolean incompleteCode) {
- final PsiElement parent = getParent();
- if (parent instanceof GrConstructorInvocation) {
- return ((GrConstructorInvocation)parent).multiResolve(incompleteCode);
- }
- return ResolveResult.EMPTY_ARRAY;
- }
-
- @NotNull
- @Override
- public String getCanonicalText() {
- return getReferenceName();
- }
-
- static class OurResolver implements ResolveCache.PolyVariantResolver<GrThisSuperReferenceExpressionBase> {
- @NotNull
- @Override
- public ResolveResult[] resolve(@NotNull GrThisSuperReferenceExpressionBase ref, boolean incompleteCode) {
- final PsiElement resolved = ref.resolveInner();
- if (resolved == null) return ResolveResult.EMPTY_ARRAY;
- return new GroovyResolveResult[]{new GroovyResolveResultImpl(resolved, true)};
- }
- }
-}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrReferenceListImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrReferenceListImpl.java
index e6b26f3..0b3f95b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrReferenceListImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrReferenceListImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef;
import com.intellij.lang.ASTNode;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.StubBasedPsiElement;
@@ -23,6 +24,7 @@
import com.intellij.psi.tree.IElementType;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList;
@@ -38,7 +40,8 @@
* @author Maxim.Medvedev
*/
public abstract class GrReferenceListImpl extends GrStubElementBase<GrReferenceListStub> implements StubBasedPsiElement<GrReferenceListStub>, GrReferenceList {
-
+ private static final Logger LOG = Logger.getInstance(GrReferenceListImpl.class);
+
private PsiClassType[] cachedTypes = null;
public GrReferenceListImpl(@NotNull ASTNode node) {
@@ -46,6 +49,41 @@
}
@Override
+ public void deleteChildInternal(@NotNull ASTNode child) {
+ PsiElement psi = child.getPsi();
+
+ if (psi instanceof GrCodeReferenceElement) {
+
+ GrCodeReferenceElement[] refs = getReferenceElements();
+ if (refs.length == 1) {
+ PsiElement keyword = getKeyword();
+ LOG.assertTrue(keyword != null);
+ keyword.delete();
+ }
+ else {
+ PsiElement comma = PsiUtil.skipWhitespacesAndComments(psi, refs[0] == psi, true);
+ if (comma != null && comma.getNode().getElementType() == GroovyTokenTypes.mCOMMA) {
+ comma.delete();
+ }
+ }
+
+ super.deleteChildInternal(child);
+ }
+ else {
+ super.deleteChildInternal(child);
+ }
+ }
+
+ @Nullable
+ private PsiElement getKeyword() {
+ PsiElement firstChild = getFirstChild();
+ if (firstChild != null && firstChild.getNode().getElementType() == getKeywordType()) {
+ return firstChild;
+ }
+ return null;
+ }
+
+ @Override
public PsiElement getParent() {
return getParentByStub();
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionBodyBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionBodyBase.java
index 400be53..ea18c1b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionBodyBase.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionBodyBase.java
@@ -25,6 +25,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
+import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
@@ -94,7 +95,7 @@
}
public GrMethod[] getMethods() {
- return getStubOrPsiChildren(GroovyElementTypes.METHOD_DEFS, GrMethod.ARRAY_FACTORY);
+ return getStubOrPsiChildren(TokenSets.METHOD_DEFS, GrMethod.ARRAY_FACTORY);
}
public GrMembersDeclaration[] getMemberDeclarations() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java
index ce4e6a1..9fac306 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java
@@ -144,7 +144,7 @@
}
}
- return (GrTypeElement)findChildByType(GroovyElementTypes.TYPE_ELEMENTS);
+ return (GrTypeElement)findChildByType(TokenSets.TYPE_ELEMENTS);
}
public PsiType getInferredReturnType() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightClassReferenceElement.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightClassReferenceElement.java
index 3fa5a21..9939742 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightClassReferenceElement.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightClassReferenceElement.java
@@ -125,6 +125,11 @@
}
@Override
+ public boolean isQualified() {
+ return false;
+ }
+
+ @Override
public void accept(GroovyElementVisitor visitor) {
//todo ???
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java
index 04b1c88..a29e9d3 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,17 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.jetbrains.plugins.groovy.mvc;
import com.intellij.ProjectTopics;
import com.intellij.codeInsight.actions.ReformatCodeProcessor;
+import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.ModuleAdapter;
import com.intellij.openapi.project.Project;
@@ -246,12 +246,18 @@
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() {
@Override
public void run() {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- runActions();
- }
- }, ModalityState.NON_MODAL);
+ Application app = ApplicationManager.getApplication();
+ if (!app.isUnitTestMode()) {
+ app.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ runActions();
+ }
+ }, ModalityState.NON_MODAL);
+ }
+ else {
+ runActions();
+ }
}
});
}
@@ -270,7 +276,7 @@
if (o instanceof VirtualFile) {
final VirtualFile file = (VirtualFile)o;
if (file.isValid()) {
- final Module module = ModuleUtil.findModuleForFile(file, myProject);
+ final Module module = ModuleUtilCore.findModuleForFile(file, myProject);
if (module == null) {
return Collections.emptyList();
}
@@ -296,7 +302,7 @@
return;
}
- Pair<Object, SyncAction>[] actions = myActions.toArray(new Pair[myActions.size()]);
+ @SuppressWarnings("unchecked") Pair<Object, SyncAction>[] actions = myActions.toArray(new Pair[myActions.size()]);
//get module by object and kill duplicates
final Set<Trinity<Module, SyncAction, MvcFramework>> rawActions = new LinkedHashSet<Trinity<Module, SyncAction, MvcFramework>>();
@@ -379,7 +385,7 @@
@Override
void doAction(Module module, MvcFramework framework) {
final Project project = module.getProject();
- final MvcModuleStructureSynchronizer mvcModuleStructureSynchronizer = MvcModuleStructureSynchronizer.getInstance(project);
+ final MvcModuleStructureSynchronizer mvcModuleStructureSynchronizer = getInstance(project);
if (mvcModuleStructureSynchronizer.myOutOfModuleDirectoryCreatedActionAdded) {
mvcModuleStructureSynchronizer.myOutOfModuleDirectoryCreatedActionAdded = false;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java
index 67d1c37..7e71010 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java
@@ -49,6 +49,11 @@
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.JpsElementFactory;
+import org.jetbrains.jps.model.JpsSimpleElement;
+import org.jetbrains.jps.model.java.JavaSourceRootProperties;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import java.io.File;
import java.io.IOException;
@@ -82,10 +87,10 @@
final MvcProjectStructure structure) {
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(structure.myModule);
- Map<VirtualFile, Boolean> sourceRoots = new HashMap<VirtualFile, Boolean>();
+ Map<VirtualFile, JpsModuleSourceRootType> sourceRoots = new HashMap<VirtualFile, JpsModuleSourceRootType>();
for (ContentEntry entry : moduleRootManager.getContentEntries()) {
for (SourceFolder folder : entry.getSourceFolders()) {
- sourceRoots.put(folder.getFile(), folder.isTestSource());
+ sourceRoots.put(folder.getFile(), folder.getRootType());
}
}
@@ -93,12 +98,14 @@
final List<Consumer<ContentEntry>> actions = ContainerUtil.newArrayList();
- for (final String src : structure.getSourceFolders()) {
- addSourceFolder(root, src, false, actions, sourceRoots);
+ for (Map.Entry<JpsModuleSourceRootType<?>, Collection<String>> entry : structure.getSourceFolders().entrySet()) {
+ JpsModuleSourceRootType rootType = entry.getKey();
+
+ for (String src : entry.getValue()) {
+ addSourceFolder(root, src, rootType, actions, sourceRoots);
+ }
}
- for (final String src : structure.getTestFolders()) {
- addSourceFolder(root, src, true, actions, sourceRoots);
- }
+
for (final String src : structure.getInvalidSourceFolders()) {
removeSrcFolderFromRoots(root.findFileByRelativePath(src), actions, sourceRoots);
}
@@ -138,7 +145,7 @@
public static void removeSrcFolderFromRoots(final VirtualFile file,
List<Consumer<ContentEntry>> actions,
- Map<VirtualFile, Boolean> sourceRoots) {
+ Map<VirtualFile, JpsModuleSourceRootType> sourceRoots) {
if (sourceRoots.containsKey(file)) {
actions.add(new Consumer<ContentEntry>() {
public void consume(ContentEntry contentEntry) {
@@ -199,37 +206,37 @@
public static void addSourceFolder(@NotNull VirtualFile root,
@NotNull String relativePath,
- final boolean isTest,
+ final JpsModuleSourceRootType rootType,
List<Consumer<ContentEntry>> actions,
- Map<VirtualFile, Boolean> sourceRoots) {
+ Map<VirtualFile, JpsModuleSourceRootType> sourceRoots) {
final VirtualFile src = root.findFileByRelativePath(relativePath);
if (src == null) {
return;
}
- Boolean existingFolderIsTest = sourceRoots.get(src);
+ JpsModuleSourceRootType existingRootType = sourceRoots.get(src);
- if (existingFolderIsTest != null) {
- if (isTest && !existingFolderIsTest) { // see http://youtrack.jetbrains.net/issue/IDEA-70642
- actions.add(new Consumer<ContentEntry>() {
- @Override
- public void consume(ContentEntry entry) {
- for (SourceFolder folder : entry.getSourceFolders()) {
- if (Comparing.equal(folder.getFile(), src)) {
- entry.removeSourceFolder(folder);
- entry.addSourceFolder(src, isTest, "");
- break;
- }
+ if (rootType == JavaSourceRootType.TEST_SOURCE && (existingRootType != null && existingRootType != JavaSourceRootType.TEST_SOURCE)) { // see http://youtrack.jetbrains.net/issue/IDEA-70642
+ actions.add(new Consumer<ContentEntry>() {
+ @Override
+ public void consume(ContentEntry entry) {
+ for (SourceFolder folder : entry.getSourceFolders()) {
+ if (Comparing.equal(folder.getFile(), src)) {
+ entry.removeSourceFolder(folder);
+ JpsSimpleElement<JavaSourceRootProperties> properties = JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties(""));
+ entry.addSourceFolder(src, rootType, properties);
+ break;
}
}
- });
- }
+ }
+ });
return;
}
actions.add(new Consumer<ContentEntry>() {
public void consume(ContentEntry contentEntry) {
- contentEntry.addSourceFolder(src, isTest, "");
+ JpsSimpleElement<JavaSourceRootProperties> properties = JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties(""));
+ contentEntry.addSourceFolder(src, rootType, properties);
}
});
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcProjectStructure.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcProjectStructure.java
index 112f82f..e13c50e 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcProjectStructure.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcProjectStructure.java
@@ -18,7 +18,9 @@
import com.intellij.openapi.module.Module;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import java.io.File;
import java.util.ArrayList;
@@ -57,8 +59,8 @@
@NotNull
public abstract String getUserLibraryName();
- public abstract String[] getSourceFolders();
- public abstract String[] getTestFolders();
+ public abstract MultiMap<JpsModuleSourceRootType<?>, String> getSourceFolders();
+
public abstract String[] getInvalidSourceFolders();
public abstract String[] getExcludedFolders();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java
index 422b557..0dd6b2c 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java
@@ -18,6 +18,7 @@
import com.intellij.openapi.util.Key;
import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
@@ -114,6 +115,7 @@
final PsiElement qualifier = refExpr.getQualifier();
if (!(qualifier instanceof GrReferenceExpression)) {
refExpr.setQualifier(factory.createReferenceExpressionFromText(memberClass.getQualifiedName()));
+ JavaCodeStyleManager.getInstance(manager.getProject()).shortenClassReferences(refExpr.getQualifier());
return;
}
}
@@ -140,4 +142,13 @@
}
}
}
+
+ public static void clearContextInfo(PsiElement scope) {
+ scope.putCopyableUserData(QUALIFIER_CLASS_KEY, null);
+ scope.putCopyableUserData(REF_TO_CLASS, null);
+ scope.putCopyableUserData(REF_TO_MEMBER, null);
+ for (PsiElement child = scope.getFirstChild(); child != null; child = child.getNextSibling()) {
+ clearContextInfo(child);
+ }
+ }
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java
index 5e2e2af..b8b2857 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java
@@ -41,6 +41,7 @@
import org.jetbrains.plugins.groovy.refactoring.introduce.field.GrIntroduceFieldHandler;
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GrIntroduceParameterHandler;
import org.jetbrains.plugins.groovy.refactoring.introduce.variable.GrIntroduceVariableHandler;
+import org.jetbrains.plugins.groovy.refactoring.memberPullUp.GrPullUpHandler;
/**
* @author ilyas
@@ -129,4 +130,17 @@
public RefactoringActionHandler getIntroduceConstantHandler() {
return new GrIntroduceConstantHandler();
}
+
+ @Nullable
+ @Override
+ public RefactoringActionHandler getPullUpHandler() {
+ return new GrPullUpHandler();
+ }
+
+ @Nullable
+ @Override
+ public RefactoringActionHandler getExtractInterfaceHandler() {
+ //return new ExtractInterfaceHandler();
+ return null;
+ }
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrClassMemberReferenceVisitor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrClassMemberReferenceVisitor.java
new file mode 100644
index 0000000..92a0735
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrClassMemberReferenceVisitor.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.refactoring.classMembers;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
+import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
+
+/**
+ * @author Max Medvedev
+ */
+public abstract class GrClassMemberReferenceVisitor extends GroovyRecursiveElementVisitor {
+ private final PsiClass myClass;
+
+ public GrClassMemberReferenceVisitor(@NotNull PsiClass aClass) {
+ myClass = aClass;
+ }
+
+ @Override
+ public void visitReferenceExpression(GrReferenceExpression ref) {
+ GrExpression qualifier = ref.getQualifier();
+
+ if (qualifier != null && !(PsiUtil.isThisOrSuperRef(qualifier))) {
+ qualifier.accept(this);
+
+ if (!(qualifier instanceof GrReferenceExpression) || !(((GrReferenceExpression) qualifier).resolve() instanceof PsiClass)) {
+ return;
+ }
+ }
+
+ PsiElement resolved = ref.resolve();
+ if (resolved instanceof GrMember) {
+ PsiClass containingClass = ((GrMember)resolved).getContainingClass();
+ if (isPartOf(myClass, containingClass)) {
+ visitClassMemberReferenceElement((GrMember)resolved, ref);
+ }
+ }
+ }
+
+ @Override
+ public void visitCodeReferenceElement(GrCodeReferenceElement reference) {
+ PsiElement referencedElement = reference.resolve();
+ if (referencedElement instanceof GrTypeDefinition) {
+ final GrTypeDefinition referencedClass = (GrTypeDefinition)referencedElement;
+ if (PsiTreeUtil.isAncestor(myClass, referencedElement, true) ||
+ isPartOf(myClass, referencedClass.getContainingClass())) {
+ visitClassMemberReferenceElement((GrMember)referencedElement, reference);
+ }
+ }
+ }
+
+ private static boolean isPartOf(@NotNull PsiClass aClass, @Nullable PsiClass containingClass) {
+ if (containingClass == null) return false;
+ return aClass.equals(containingClass) || aClass.isInheritor(containingClass, true);
+ }
+
+ protected abstract void visitClassMemberReferenceElement(GrMember resolved, GrReferenceElement ref);
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrDependantMembersCollector.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrDependantMembersCollector.java
new file mode 100644
index 0000000..1159e2e8
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrDependantMembersCollector.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.refactoring.classMembers;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.PsiMethod;
+import com.intellij.refactoring.classMembers.DependentMembersCollectorBase;
+import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+
+/**
+ * @author Max Medvedev
+ */
+public class GrDependantMembersCollector extends DependentMembersCollectorBase<GrMember, PsiClass> {
+ public GrDependantMembersCollector(PsiClass clazz, PsiClass superClass) {
+ super(clazz, superClass);
+ }
+
+ @Override
+ public void collect(GrMember member) {
+ member.accept(new GrClassMemberReferenceVisitor(getClazz()) {
+ @Override
+ protected void visitClassMemberReferenceElement(GrMember classMember, GrReferenceElement ref) {
+ if (!existsInSuperClass(classMember)) {
+ myCollection.add(classMember);
+ }
+ }
+ });
+ }
+
+ private boolean existsInSuperClass(PsiMember classMember) {
+ if (getSuperClass() == null) return false;
+ if (!(classMember instanceof PsiMethod)) return false;
+ final PsiMethod method = ((PsiMethod)classMember);
+ final PsiMethod methodBySignature = (getSuperClass()).findMethodBySignature(method, true);
+ return methodBySignature != null;
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberInfo.java
new file mode 100644
index 0000000..e1caae8
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberInfo.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.refactoring.classMembers;
+
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Max Medvedev
+ */
+public class GrMemberInfo extends MemberInfoBase<GrMember> {
+ public GrMemberInfo(GrMember member) {
+ this(member, false, null);
+ }
+
+ public GrMemberInfo(GrMember member, boolean isSuperClass, GrReferenceList sourceReferenceList) {
+ super(member);
+ LOG.assertTrue(member.isValid());
+ mySourceReferenceList = sourceReferenceList;
+ if (member instanceof GrMethod) {
+ GrMethod method = (GrMethod)member;
+ displayName = PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER | PsiFormatUtil.SHOW_PARAMETERS,
+ PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER);
+ PsiMethod[] superMethods = method.findSuperMethods();
+ if (superMethods.length > 0) {
+ overrides = !superMethods[0].hasModifierProperty(PsiModifier.ABSTRACT) ? Boolean.TRUE : Boolean.FALSE;
+ }
+ else {
+ overrides = null;
+ }
+
+ isStatic = method.hasModifierProperty(PsiModifier.STATIC);
+ }
+ else if (member instanceof GrField) {
+ GrField field = (GrField)member;
+ displayName = PsiFormatUtil
+ .formatVariable(field, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER, PsiSubstitutor.EMPTY);
+ isStatic = field.hasModifierProperty(PsiModifier.STATIC);
+ overrides = null;
+ }
+ else if (member instanceof GrTypeDefinition) {
+ GrTypeDefinition aClass = (GrTypeDefinition)member;
+
+ if (isSuperClass) {
+ if (aClass.isInterface()) {
+ displayName = RefactoringBundle.message("member.info.implements.0", aClass.getName());
+ overrides = Boolean.FALSE;
+ }
+ else {
+ displayName = RefactoringBundle.message("member.info.extends.0", aClass.getName());
+ overrides = Boolean.TRUE;
+ }
+ }
+ else {
+ displayName = aClass.getName();
+ overrides = null;
+ }
+
+ isStatic = aClass.hasModifierProperty(PsiModifier.STATIC);
+ }
+ else {
+ LOG.assertTrue(false);
+ isStatic = false;
+ displayName = "";
+ overrides = null;
+ }
+ }
+
+ public GrReferenceList getSourceReferenceList() {
+ return mySourceReferenceList;
+ }
+
+ public static List<GrMemberInfo> extractClassMembers(GrTypeDefinition subclass, Filter<GrMember> filter, boolean extractInterfacesDeep) {
+ List<GrMemberInfo> members = new ArrayList<GrMemberInfo>();
+ extractClassMembers(subclass, members, filter, extractInterfacesDeep);
+ return members;
+ }
+
+ public static void extractClassMembers(PsiClass subclass,
+ List<GrMemberInfo> result,
+ Filter<GrMember> filter,
+ final boolean extractInterfacesDeep) {
+
+ if (!(subclass instanceof GrTypeDefinition)) return;
+
+
+ if (extractInterfacesDeep) {
+ extractSuperInterfaces(subclass, filter, result, ContainerUtil.<PsiClass>newHashSet());
+ }
+ else {
+ PsiClass[] interfaces = subclass.getInterfaces();
+ GrReferenceList sourceRefList = subclass.isInterface()
+ ? ((GrTypeDefinition)subclass).getExtendsClause()
+ : ((GrTypeDefinition)subclass).getImplementsClause();
+ for (PsiClass anInterface : interfaces) {
+ if (anInterface instanceof GrTypeDefinition && filter.includeMember((GrMember)anInterface)) {
+ result.add(new GrMemberInfo((GrMember)anInterface, true, sourceRefList));
+ }
+ }
+ }
+
+
+ PsiClass[] innerClasses = subclass.getInnerClasses();
+ for (PsiClass innerClass : innerClasses) {
+ if (innerClass instanceof GrTypeDefinition && filter.includeMember((GrMember)innerClass)) {
+ result.add(new GrMemberInfo((GrMember)innerClass));
+ }
+ }
+
+ GrMethod[] methods = ((GrTypeDefinition)subclass).getCodeMethods();
+ for (GrMethod method : methods) {
+ if (!method.isConstructor() && filter.includeMember(method)) {
+ result.add(new GrMemberInfo(method));
+ }
+ }
+
+ GrField[] fields = ((GrTypeDefinition)subclass).getCodeFields();
+ for (final GrField field : fields) {
+ if (filter.includeMember(field)) {
+ result.add(new GrMemberInfo(field));
+ }
+ }
+ }
+
+ private static void extractSuperInterfaces(final PsiClass subclass,
+ final Filter<GrMember> filter,
+ final List<GrMemberInfo> result,
+ Set<PsiClass> processed) {
+ if (!processed.contains(subclass)) {
+ processed.add(subclass);
+ if (subclass instanceof GrTypeDefinition) {
+ extractSuperInterfacesFromReferenceList(((GrTypeDefinition)subclass).getExtendsClause(), filter, result, processed);
+ extractSuperInterfacesFromReferenceList(((GrTypeDefinition)subclass).getImplementsClause(), filter, result, processed);
+ }
+ }
+ }
+
+ private static void extractSuperInterfacesFromReferenceList(final GrReferenceList referenceList,
+ final Filter<GrMember> filter,
+ final List<GrMemberInfo> result,
+ final Set<PsiClass> processed) {
+ if (referenceList != null) {
+ final PsiClassType[] extendsListTypes = referenceList.getReferenceTypes();
+ for (PsiClassType extendsListType : extendsListTypes) {
+ final PsiClass aSuper = extendsListType.resolve();
+ if (aSuper instanceof GrTypeDefinition) {
+ if (aSuper.isInterface()) {
+ if (filter.includeMember((GrMember)aSuper)) {
+ result.add(new GrMemberInfo((GrMember)aSuper, true, referenceList));
+ }
+ }
+ else {
+ extractSuperInterfaces(aSuper, filter, result, processed);
+ }
+ }
+ }
+ }
+ }
+
+ private final GrReferenceList mySourceReferenceList;
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberInfoStorage.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberInfoStorage.java
new file mode 100644
index 0000000..e2ad586
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberInfoStorage.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.refactoring.classMembers;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiClassType;
+import com.intellij.psi.util.MethodSignatureUtil;
+import com.intellij.refactoring.classMembers.AbstractMemberInfoStorage;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrExtendsClause;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrImplementsClause;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
+
+import java.util.ArrayList;
+
+/**
+ * @author Max Medvedev
+ */
+public class GrMemberInfoStorage extends AbstractMemberInfoStorage<GrMember, PsiClass, GrMemberInfo> {
+ public GrMemberInfoStorage(GrTypeDefinition aClass, MemberInfoBase.Filter<GrMember> memberInfoFilter) {
+ super(aClass, memberInfoFilter);
+ }
+
+ @Override
+ protected boolean isInheritor(PsiClass baseClass, PsiClass aClass) {
+ return aClass.isInheritor(baseClass, true);
+ }
+
+ @Override
+ protected void extractClassMembers(PsiClass aClass, ArrayList<GrMemberInfo> temp) {
+ GrMemberInfo.extractClassMembers(aClass, temp, myFilter, false);
+ }
+
+ @Override
+ protected boolean memberConflict(GrMember member1, GrMember member) {
+ if (member instanceof GrMethod && member1 instanceof GrMethod) {
+ return MethodSignatureUtil.areSignaturesEqual((GrMethod)member, (GrMethod)member1);
+ }
+ else if (member instanceof GrField && member1 instanceof GrField ||
+ member instanceof GrTypeDefinition && member1 instanceof GrTypeDefinition) {
+ return member.getName().equals(member1.getName());
+ }
+
+ return false;
+ }
+
+ @Override
+ protected void buildSubClassesMap(PsiClass aClass) {
+ if (aClass instanceof GrTypeDefinition) {
+ final GrExtendsClause extendsList = ((GrTypeDefinition)aClass).getExtendsClause();
+ if (extendsList != null) {
+ buildSubClassesMapForList(extendsList.getReferenceTypes(), (GrTypeDefinition)aClass);
+ }
+
+ final GrImplementsClause implementsList = ((GrTypeDefinition)aClass).getImplementsClause();
+ if (implementsList != null) {
+ buildSubClassesMapForList(implementsList.getReferenceTypes(), (GrTypeDefinition)aClass);
+ }
+ }
+ }
+
+ private void buildSubClassesMapForList(final PsiClassType[] classesList, GrTypeDefinition aClass) {
+ for (int i = 0; i < classesList.length; i++) {
+ PsiClassType element = classesList[i];
+ PsiClass resolved = element.resolve();
+ if (resolved instanceof GrTypeDefinition) {
+ GrTypeDefinition superClass = (GrTypeDefinition)resolved;
+ getSubclasses(superClass).add(aClass);
+ buildSubClassesMap(superClass);
+ }
+ }
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberSelectionTable.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberSelectionTable.java
new file mode 100644
index 0000000..e508284
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GrMemberSelectionTable.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.refactoring.classMembers;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiModifier;
+import com.intellij.psi.PsiModifierList;
+import com.intellij.refactoring.classMembers.MemberInfoModel;
+import com.intellij.refactoring.ui.AbstractMemberSelectionTable;
+import com.intellij.ui.RowIcon;
+import com.intellij.util.IconUtil;
+import com.intellij.util.VisibilityIcons;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+
+import javax.swing.*;
+import java.util.List;
+
+/**
+ * @author Max Medvedev
+ */
+public class GrMemberSelectionTable extends AbstractMemberSelectionTable<GrMember, GrMemberInfo> {
+
+ public GrMemberSelectionTable(final List<GrMemberInfo> memberInfos, String abstractColumnHeader) {
+ this(memberInfos, null, abstractColumnHeader);
+ }
+
+ public GrMemberSelectionTable(final List<GrMemberInfo> memberInfos, MemberInfoModel<GrMember, GrMemberInfo> memberInfoModel, String abstractColumnHeader) {
+ super(memberInfos, memberInfoModel, abstractColumnHeader);
+ }
+
+ @Nullable
+ @Override
+ protected Object getAbstractColumnValue(GrMemberInfo memberInfo) {
+ if (!(memberInfo.getMember() instanceof PsiMethod)) return null;
+ if (memberInfo.isStatic()) return null;
+
+ PsiMethod method = (PsiMethod)memberInfo.getMember();
+ if (method.hasModifierProperty(PsiModifier.ABSTRACT)) {
+ final Boolean fixedAbstract = myMemberInfoModel.isFixedAbstract(memberInfo);
+ if (fixedAbstract != null) return fixedAbstract;
+ }
+
+ if (!myMemberInfoModel.isAbstractEnabled(memberInfo)) {
+ return myMemberInfoModel.isAbstractWhenDisabled(memberInfo);
+ }
+ else {
+ return memberInfo.isToAbstract() ? Boolean.TRUE : Boolean.FALSE;
+ }
+ }
+
+ @Override
+ protected boolean isAbstractColumnEditable(int rowIndex) {
+ GrMemberInfo info = myMemberInfos.get(rowIndex);
+ if (!(info.getMember() instanceof PsiMethod)) return false;
+ if (info.isStatic()) return false;
+
+ PsiMethod method = (PsiMethod)info.getMember();
+ if (method.hasModifierProperty(PsiModifier.ABSTRACT)) {
+ if (myMemberInfoModel.isFixedAbstract(info) != null) {
+ return false;
+ }
+ }
+
+ return info.isChecked() && myMemberInfoModel.isAbstractEnabled(info);
+ }
+
+
+ @Override
+ protected void setVisibilityIcon(GrMemberInfo memberInfo, RowIcon icon) {
+ PsiMember member = memberInfo.getMember();
+ PsiModifierList modifiers = member != null ? member.getModifierList() : null;
+ if (modifiers != null) {
+ VisibilityIcons.setVisibilityIcon(modifiers, icon);
+ }
+ else {
+ icon.setIcon(IconUtil.getEmptyIcon(true), VISIBILITY_ICON_POSITION);
+ }
+ }
+
+ @Override
+ protected Icon getOverrideIcon(GrMemberInfo memberInfo) {
+ PsiMember member = memberInfo.getMember();
+ Icon overrideIcon = EMPTY_OVERRIDE_ICON;
+ if (member instanceof PsiMethod) {
+ if (Boolean.TRUE.equals(memberInfo.getOverrides())) {
+ overrideIcon = AllIcons.General.OverridingMethod;
+ }
+ else if (Boolean.FALSE.equals(memberInfo.getOverrides())) {
+ overrideIcon = AllIcons.General.ImplementingMethod;
+ }
+ else {
+ overrideIcon = EMPTY_OVERRIDE_ICON;
+ }
+ }
+ return overrideIcon;
+ }
+}
+
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GroovyClassMembersRefactoringSupport.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GroovyClassMembersRefactoringSupport.java
new file mode 100644
index 0000000..46d9b72
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/classMembers/GroovyClassMembersRefactoringSupport.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.refactoring.classMembers;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.refactoring.classMembers.ClassMembersRefactoringSupport;
+import com.intellij.refactoring.classMembers.DependentMembersCollectorBase;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+
+/**
+ * @author Max Medvedev
+ */
+public class GroovyClassMembersRefactoringSupport implements ClassMembersRefactoringSupport {
+ @Override
+ public DependentMembersCollectorBase createDependentMembersCollector(Object clazz, Object superClass) {
+ return new GrDependantMembersCollector((PsiClass)clazz, (PsiClass)superClass);
+ }
+
+ @Override
+ public boolean isProperMember(MemberInfoBase member) {
+ return member instanceof GrMemberInfo;
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java
index bc6882b..0846039 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java
@@ -107,7 +107,7 @@
String name = method.getName();
- boolean isAbstract = GenerationUtil.isAbstractInJava(method);
+ boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
PsiModifierList modifierList = method.getModifierList();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java
index 8179b12..7b0769c 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java
@@ -269,15 +269,6 @@
return curClass;
}
- static boolean isAbstractInJava(PsiMethod method) {
- if (method.hasModifierProperty(PsiModifier.ABSTRACT)) {
- return true;
- }
-
- final PsiClass psiClass = method.getContainingClass();
- return psiClass != null && psiClass.isInterface();
- }
-
static void writeTypeParameters(StringBuilder text,
PsiTypeParameterListOwner typeParameterListOwner,
final ClassNameProvider classNameProvider) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.java
index 3c6d2d4..1ac17ed6 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -229,7 +229,7 @@
return; //does not have a java image
}
- boolean isAbstract = GenerationUtil.isAbstractInJava(method);
+ boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
PsiModifierList modifierList = method.getModifierList();
@@ -342,7 +342,7 @@
if (baseClass == null) continue;
final String qname = baseClass.getQualifiedName();
if (DEFAULT_BASE_CLASS_NAME.equals(qname) || GROOVY_OBJECT_SUPPORT.equals(qname) ||
- GenerationUtil.isAbstractInJava(method) && typeDefinition.isInheritor(baseClass, true)) {
+ method.hasModifierProperty(PsiModifier.ABSTRACT) && typeDefinition.isInheritor(baseClass, true)) {
if (method.isConstructor()) continue;
methods.add(mirrorMethod(typeDefinition, method, baseClass, signature.getSubstitutor()));
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extractInterface/GrExtractInterfaceHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extractInterface/GrExtractInterfaceHandler.java
new file mode 100644
index 0000000..1b7a112
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extractInterface/GrExtractInterfaceHandler.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.refactoring.extractInterface;
+
+import com.intellij.history.LocalHistory;
+import com.intellij.history.LocalHistoryAction;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.ScrollType;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.refactoring.HelpID;
+import com.intellij.refactoring.RefactoringActionHandler;
+import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.extractInterface.ExtractClassUtil;
+import com.intellij.refactoring.extractSuperclass.ExtractSuperClassUtil;
+import com.intellij.refactoring.lang.ElementsHandler;
+import com.intellij.refactoring.memberPullUp.PullUpHelper;
+import com.intellij.refactoring.util.CommonRefactoringUtil;
+import com.intellij.refactoring.util.DocCommentPolicy;
+import com.intellij.refactoring.util.classMembers.MemberInfo;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+
+import javax.swing.*;
+
+/**
+ * @author Max Medvedev
+ */
+public class GrExtractInterfaceHandler implements RefactoringActionHandler, ElementsHandler {
+ public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
+ int offset = editor.getCaretModel().getOffset();
+ editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
+ PsiElement element = file.findElementAt(offset);
+ while (true) {
+ if (element == null || element instanceof PsiFile) {
+ String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("error.wrong.caret.position.class"));
+ CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.EXTRACT_INTERFACE);
+ return;
+ }
+
+ if (element instanceof GrTypeDefinition && !(element instanceof GrAnonymousClassDefinition)) {
+ invoke(project, new PsiElement[]{element}, dataContext);
+ return;
+ }
+
+ element = element.getParent();
+ }
+ }
+
+ public void invoke(@NotNull final Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
+ if (elements.length != 1) return;
+
+
+ myProject = project;
+ myClass = (PsiClass)elements[0];
+
+
+ if (!CommonRefactoringUtil.checkReadOnlyStatus(project, myClass)) return;
+
+/* todo
+ final JavaExtractSuperBaseDialog dialog = new ExtractInterfaceDialog(myProject, myClass);
+ dialog.show();
+ if (!dialog.isOK() || !dialog.isExtractSuperclass()) return;
+
+ final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
+ ExtractSuperClassUtil.checkSuperAccessible(dialog.getTargetDirectory(), conflicts, myClass);
+ if (!ExtractSuperClassUtil.showConflicts(dialog, conflicts, myProject)) return;
+
+ CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ public void run() {
+ myInterfaceName = dialog.getExtractedSuperName();
+ mySelectedMembers = ArrayUtil.toObjectArray(dialog.getSelectedMemberInfos(), MemberInfo.class);
+ myTargetDir = dialog.getTargetDirectory();
+ myJavaDocPolicy = new DocCommentPolicy(dialog.getDocCommentPolicy());
+ try {
+ doRefactoring();
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+ });
+ }
+ }, REFACTORING_NAME, null);*/
+ }
+
+ private void doRefactoring() throws IncorrectOperationException {
+ LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName());
+ final PsiClass anInterface;
+ try {
+ anInterface = extractInterface(myTargetDir, myClass, myInterfaceName, mySelectedMembers, myJavaDocPolicy);
+ }
+ finally {
+ a.finish();
+ }
+
+
+ if (anInterface != null) {
+ final SmartPsiElementPointer<PsiClass> classPointer =
+ SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(myClass);
+ final SmartPsiElementPointer<PsiClass> interfacePointer =
+ SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(anInterface);
+ final Runnable turnRefsToSuperRunnable = new Runnable() {
+ @Override
+ public void run() {
+ ExtractClassUtil.askAndTurnRefsToSuper(myProject, classPointer, interfacePointer);
+ }
+ };
+ SwingUtilities.invokeLater(turnRefsToSuperRunnable);
+ }
+ }
+
+ public static PsiClass extractInterface(PsiDirectory targetDir,
+ PsiClass aClass,
+ String interfaceName,
+ MemberInfo[] selectedMembers,
+ DocCommentPolicy javaDocPolicy) throws IncorrectOperationException {
+ PsiClass anInterface = JavaDirectoryService.getInstance().createInterface(targetDir, interfaceName);
+ PsiJavaCodeReferenceElement ref = ExtractSuperClassUtil.createExtendingReference(anInterface, aClass, selectedMembers);
+ final PsiReferenceList referenceList = aClass.isInterface() ? aClass.getExtendsList() : aClass.getImplementsList();
+ assert referenceList != null;
+ referenceList.add(ref);
+ PullUpHelper pullUpHelper = new PullUpHelper(aClass, anInterface, selectedMembers, javaDocPolicy);
+ pullUpHelper.moveMembersToBase();
+ return anInterface;
+ }
+
+ private String getCommandName() {
+ return RefactoringBundle.message("extract.interface.command.name", myInterfaceName, DescriptiveNameUtil.getDescriptiveName(myClass));
+ }
+
+ public boolean isEnabledOnElements(PsiElement[] elements) {
+ return elements.length == 1 && elements[0] instanceof PsiClass;
+ }
+
+ private static final Logger LOG = Logger.getInstance(GrExtractInterfaceHandler.class);
+ public static final String REFACTORING_NAME = RefactoringBundle.message("extract.interface.title");
+ private Project myProject;
+ private PsiClass myClass;
+ private String myInterfaceName;
+ private MemberInfo[] mySelectedMembers;
+ private PsiDirectory myTargetDir;
+ private DocCommentPolicy myJavaDocPolicy;
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpDialog.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpDialog.java
new file mode 100644
index 0000000..5fc3aa9
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpDialog.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.refactoring.memberPullUp;
+
+import com.intellij.openapi.help.HelpManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiDocCommentOwner;
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.statistics.StatisticsInfo;
+import com.intellij.psi.statistics.StatisticsManager;
+import com.intellij.refactoring.HelpID;
+import com.intellij.refactoring.JavaRefactoringSettings;
+import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.classMembers.AbstractUsesDependencyMemberInfoModel;
+import com.intellij.refactoring.classMembers.MemberInfoModel;
+import com.intellij.refactoring.memberPullUp.PullUpDialogBase;
+import com.intellij.refactoring.memberPullUp.PullUpHelper;
+import com.intellij.refactoring.ui.AbstractMemberSelectionTable;
+import com.intellij.refactoring.ui.ClassCellRenderer;
+import com.intellij.refactoring.ui.DocCommentPanel;
+import com.intellij.refactoring.util.DocCommentPolicy;
+import com.intellij.refactoring.util.RefactoringHierarchyUtil;
+import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfo;
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfoStorage;
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberSelectionTable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.util.List;
+
+/**
+ * @author Max Medvedev
+ */
+class GrPullUpDialog extends PullUpDialogBase<GrMemberInfoStorage, GrMemberInfo, GrMember, PsiClass> {
+ private final Callback myCallback;
+ private DocCommentPanel myJavaDocPanel;
+
+ private final InterfaceContainmentVerifier myInterfaceContainmentVerifier = new InterfaceContainmentVerifier() {
+ public boolean checkedInterfacesContain(PsiMethod psiMethod) {
+ return PullUpHelper.checkedInterfacesContain(myMemberInfos, psiMethod);
+ }
+ };
+
+ private static final String PULL_UP_STATISTICS_KEY = "pull.up##";
+
+ public interface Callback {
+ boolean checkConflicts(GrPullUpDialog dialog);
+ }
+
+ public GrPullUpDialog(Project project,
+ PsiClass typeDefinition,
+ List<PsiClass> superClasses,
+ GrMemberInfoStorage storage,
+ GrPullUpHandler handler) {
+ super(project, typeDefinition, superClasses, storage, GrPullUpHandler.REFACTORING_NAME);
+
+ myCallback = handler;
+
+ init();
+ }
+
+ public int getJavaDocPolicy() {
+ return myJavaDocPanel.getPolicy();
+ }
+
+ protected String getDimensionServiceKey() {
+ return "#com.intellij.refactoring.memberPullUp.PullUpDialog";
+ }
+
+ InterfaceContainmentVerifier getContainmentVerifier() {
+ return myInterfaceContainmentVerifier;
+ }
+
+ @Override
+ protected void initClassCombo(JComboBox classCombo) {
+ classCombo.setRenderer(new ClassCellRenderer(classCombo.getRenderer()));
+ classCombo.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ if (e.getStateChange() == ItemEvent.SELECTED) {
+ if (myMemberSelectionPanel != null) {
+ // ((MyMemberInfoModel)myMemberInfoModel).setSuperClass(getSuperClass());
+ myMemberSelectionPanel.getTable().setMemberInfos(myMemberInfos);
+ myMemberSelectionPanel.getTable().fireExternalDataChange();
+ }
+ }
+ }
+ });
+ }
+
+ protected PsiClass getPreselection() {
+ PsiClass preselection = RefactoringHierarchyUtil.getNearestBaseClass(myClass, false);
+
+ final String statKey = PULL_UP_STATISTICS_KEY + myClass.getQualifiedName();
+ for (StatisticsInfo info : StatisticsManager.getInstance().getAllValues(statKey)) {
+ final String superClassName = info.getValue();
+ PsiClass superClass = null;
+ for (PsiClass aClass : mySuperClasses) {
+ if (Comparing.strEqual(superClassName, aClass.getQualifiedName())) {
+ superClass = aClass;
+ break;
+ }
+ }
+ if (superClass != null && StatisticsManager.getInstance().getUseCount(info) > 0) {
+ preselection = superClass;
+ break;
+ }
+ }
+ return preselection;
+ }
+
+ protected void doHelpAction() {
+ HelpManager.getInstance().invokeHelp(HelpID.MEMBERS_PULL_UP);
+ }
+
+ protected void doAction() {
+ if (!myCallback.checkConflicts(this)) return;
+ JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC = myJavaDocPanel.getPolicy();
+ final PsiClass superClass = getSuperClass();
+ String name = superClass.getQualifiedName();
+ if (name != null) {
+ StatisticsManager
+ .getInstance().incUseCount(new StatisticsInfo(PULL_UP_STATISTICS_KEY + myClass.getQualifiedName(), name));
+ }
+
+ List<GrMemberInfo> infos = getSelectedMemberInfos();
+ GrPullUpHelper processor =
+ new GrPullUpHelper(myClass, superClass, infos.toArray(new GrMemberInfo[infos.size()]), new DocCommentPolicy(getJavaDocPolicy()));
+ invokeRefactoring(processor);
+ close(OK_EXIT_CODE);
+ }
+
+ @Override
+ protected void addCustomElementsToCentralPanel(JPanel panel) {
+ myJavaDocPanel = new DocCommentPanel(RefactoringBundle.message("javadoc.for.abstracts"));
+ myJavaDocPanel.setPolicy(JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC);
+ boolean hasJavadoc = false;
+ for (GrMemberInfo info : myMemberInfos) {
+ final PsiMember member = info.getMember();
+ if (myMemberInfoModel.isAbstractEnabled(info) &&
+ member instanceof PsiDocCommentOwner &&
+ ((PsiDocCommentOwner)member).getDocComment() != null) {
+ hasJavadoc = true;
+ break;
+ }
+ }
+ UIUtil.setEnabled(myJavaDocPanel, hasJavadoc, true);
+ panel.add(myJavaDocPanel, BorderLayout.EAST);
+ }
+
+ @Override
+ protected AbstractMemberSelectionTable<GrMember, GrMemberInfo> createMemberSelectionTable(List<GrMemberInfo> infos) {
+ return new GrMemberSelectionTable(infos, RefactoringBundle.message("make.abstract"));
+ }
+
+ @Override
+ protected MemberInfoModel<GrMember, GrMemberInfo> createMemberInfoModel() {
+ //return new UsedByDependencyMemberInfoModel<PyElement, PyClass, PyMemberInfo>(myClass);
+ return new MyMemberInfoModel(myClass, getSuperClass(), false);
+ }
+
+ private static class MyMemberInfoModel extends AbstractUsesDependencyMemberInfoModel<GrMember, PsiClass, GrMemberInfo> {
+ public MyMemberInfoModel(PsiClass aClass, PsiClass superClass, boolean recursive) {
+ super(aClass, superClass, recursive);
+ }
+
+ @Override
+ protected int doCheck(@NotNull GrMemberInfo memberInfo, int problem) {
+ if (problem == ERROR && memberInfo.isStatic()) {
+ return WARNING;
+ }
+ return problem;
+ }
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHandler.java
new file mode 100644
index 0000000..5336150
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHandler.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.refactoring.memberPullUp;
+
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.ScrollType;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.psi.*;
+import com.intellij.refactoring.HelpID;
+import com.intellij.refactoring.RefactoringActionHandler;
+import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+import com.intellij.refactoring.lang.ElementsHandler;
+import com.intellij.refactoring.memberPullUp.PullUpConflictsUtil;
+import com.intellij.refactoring.ui.ConflictsDialog;
+import com.intellij.refactoring.util.CommonRefactoringUtil;
+import com.intellij.refactoring.util.RefactoringHierarchyUtil;
+import com.intellij.util.containers.MultiMap;
+import org.codehaus.groovy.runtime.DefaultGroovyMethods;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfo;
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfoStorage;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Max Medvedev
+ */
+public class GrPullUpHandler implements RefactoringActionHandler, GrPullUpDialog.Callback, ElementsHandler {
+ private static final Logger LOG = Logger.getInstance(GrPullUpHandler.class);
+ public static final String REFACTORING_NAME = RefactoringBundle.message("pull.members.up.title");
+
+ private PsiClass mySubclass;
+ private Project myProject;
+
+ public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
+ int offset = editor.getCaretModel().getOffset();
+ editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
+ PsiElement element = file.findElementAt(offset);
+
+ while (true) {
+ if (element == null || element instanceof PsiFile) {
+ String message = RefactoringBundle
+ .getCannotRefactorMessage(RefactoringBundle.message("the.caret.should.be.positioned.inside.a.class.to.pull.members.from"));
+ CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PULL_UP);
+ return;
+ }
+
+
+ if (!CommonRefactoringUtil.checkReadOnlyStatus(project, element)) return;
+
+
+ if (element instanceof GrTypeDefinition || element instanceof GrField || element instanceof GrMethod) {
+ invoke(project, new PsiElement[]{element}, dataContext);
+ return;
+ }
+
+ element = element.getParent();
+ }
+ }
+
+ public void invoke(@NotNull final Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
+ if (elements.length != 1) return;
+
+ myProject = project;
+
+ PsiElement element = elements[0];
+ GrTypeDefinition aClass;
+ PsiElement aMember = null;
+
+ if (element instanceof GrTypeDefinition) {
+ aClass = (GrTypeDefinition)element;
+ }
+ else if (element instanceof GrMethod) {
+ aClass = DefaultGroovyMethods.asType(((GrMethod)element).getContainingClass(), GrTypeDefinition.class);
+ aMember = element;
+ }
+ else if (element instanceof GrField) {
+ aClass = DefaultGroovyMethods.asType(((GrField)element).getContainingClass(), GrTypeDefinition.class);
+ aMember = element;
+ }
+ else {
+ return;
+ }
+
+
+ invokeImpl(project, dataContext, aClass, aMember);
+ }
+
+ private void invokeImpl(Project project, DataContext dataContext, GrTypeDefinition aClass, PsiElement aMember) {
+ final Editor editor = dataContext != null ? PlatformDataKeys.EDITOR.getData(dataContext) : null;
+ if (aClass == null) {
+ String message =
+ RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("is.not.supported.in.the.current.context", REFACTORING_NAME));
+ CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PULL_UP);
+ return;
+ }
+
+
+ ArrayList<PsiClass> bases = RefactoringHierarchyUtil.createBasesList(aClass, false, true);
+
+ if (bases.isEmpty()) {
+ final GrTypeDefinition containingClass = DefaultGroovyMethods.asType(aClass.getContainingClass(), GrTypeDefinition.class);
+ if (containingClass != null) {
+ invokeImpl(project, dataContext, containingClass, aClass);
+ return;
+ }
+
+ String message = RefactoringBundle.getCannotRefactorMessage(
+ RefactoringBundle.message("class.does.not.have.base.classes.interfaces.in.current.project", aClass.getQualifiedName()));
+ CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PULL_UP);
+ return;
+ }
+
+
+ mySubclass = aClass;
+ GrMemberInfoStorage memberInfoStorage = new GrMemberInfoStorage((GrTypeDefinition)mySubclass, new MemberInfoBase.Filter<GrMember>() {
+ public boolean includeMember(GrMember element) {
+ return true;
+ }
+ });
+ List<GrMemberInfo> members = memberInfoStorage.getClassMemberInfos(mySubclass);
+ PsiManager manager = mySubclass.getManager();
+
+ for (GrMemberInfo member : members) {
+ if (manager.areElementsEquivalent(member.getMember(), aMember)) {
+ member.setChecked(true);
+ break;
+ }
+ }
+
+
+ final GrPullUpDialog dialog = new GrPullUpDialog(project, aClass, bases, memberInfoStorage, this);
+ dialog.show();
+ }
+
+ public boolean checkConflicts(final GrPullUpDialog dialog) {
+ /* todo */
+ List<GrMemberInfo> _infos = dialog.getSelectedMemberInfos();
+ final GrMemberInfo[] infos = _infos.toArray(new GrMemberInfo[_infos.size()]);
+ final PsiClass superClass = dialog.getSuperClass();
+ if (!checkWritable(superClass, infos)) return false;
+ final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
+ if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
+ public void run() {
+ final PsiDirectory targetDirectory = superClass.getContainingFile().getContainingDirectory();
+ final PsiPackage targetPackage = targetDirectory != null ? JavaDirectoryService.getInstance().getPackage(targetDirectory) : null;
+ conflicts.putAllValues(PullUpConflictsUtil.checkConflicts(infos, mySubclass, superClass, targetPackage, targetDirectory,
+ dialog.getContainmentVerifier()));
+ }
+ }, RefactoringBundle.message("detecting.possible.conflicts"), true, myProject)) {
+ return false;
+ }
+ if (!conflicts.isEmpty()) {
+ ConflictsDialog conflictsDialog = new ConflictsDialog(myProject, conflicts);
+ conflictsDialog.show();
+ final boolean ok = conflictsDialog.isOK();
+ if (!ok && conflictsDialog.isShowConflicts()) dialog.close(DialogWrapper.CANCEL_EXIT_CODE);
+ return ok;
+ }
+
+ return true;
+ }
+
+ private boolean checkWritable(PsiClass superClass, GrMemberInfo[] infos) {
+ if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, superClass)) return false;
+ for (GrMemberInfo info : infos) {
+ if (info.getMember() instanceof PsiClass && info.getOverrides() != null) continue;
+ if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, info.getMember())) return false;
+ }
+
+ return true;
+ }
+
+ public boolean isEnabledOnElements(PsiElement[] elements) {
+ return elements.length == 1 && elements[0] instanceof PsiClass;
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelper.java
new file mode 100644
index 0000000..028e613
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelper.java
@@ -0,0 +1,730 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.refactoring.memberPullUp;
+
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.codeInsight.intention.AddAnnotationFix;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.psi.search.searches.OverridingMethodsSearch;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.MethodSignatureUtil;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.refactoring.BaseRefactoringProcessor;
+import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.listeners.JavaRefactoringListenerManager;
+import com.intellij.refactoring.listeners.impl.JavaRefactoringListenerManagerImpl;
+import com.intellij.refactoring.util.DocCommentPolicy;
+import com.intellij.refactoring.util.RefactoringHierarchyUtil;
+import com.intellij.refactoring.util.RefactoringUIUtil;
+import com.intellij.refactoring.util.RefactoringUtil;
+import com.intellij.usageView.UsageInfo;
+import com.intellij.usageView.UsageViewDescriptor;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.ContainerUtil;
+import org.codehaus.groovy.runtime.DefaultGroovyMethods;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrExtendsClause;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrImplementsClause;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
+import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
+import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
+import org.jetbrains.plugins.groovy.refactoring.GroovyChangeContextUtil;
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrClassMemberReferenceVisitor;
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfo;
+
+import java.util.*;
+
+/**
+ * @author Max Medvedev
+ */
+public class GrPullUpHelper extends BaseRefactoringProcessor {
+ private static final Logger LOG = Logger.getInstance(GrPullUpHelper.class);
+ private static final Key<Boolean> SUPER_REF = Key.create("SUPER_REF");
+ private static final Key<Boolean> THIS_REF = Key.create("THIS_REF");
+ private static final Key<Boolean> PRESERVE_QUALIFIER = Key.create("PRESERVE_QUALIFIER");
+
+ private PsiClass mySourceClass;
+ private GrTypeDefinition myTargetSuperClass;
+ private GrMemberInfo[] myMembersToMove;
+ private DocCommentPolicy myDocCommentPolicy;
+ private Set<PsiMember> myMembersAfterMove;
+
+
+ public GrPullUpHelper(PsiClass aClass, PsiClass superClass, GrMemberInfo[] infos, DocCommentPolicy policy) {
+ super(aClass.getProject());
+
+ mySourceClass = aClass;
+ myTargetSuperClass = (GrTypeDefinition)superClass;
+ myMembersToMove = infos;
+ myDocCommentPolicy = policy;
+ }
+
+ @NotNull
+ @Override
+ protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) {
+ return new UsageViewDescriptor() {
+ public String getProcessedElementsHeader() {
+ return "Pull up members from";
+ }
+
+ @NotNull
+ public PsiElement[] getElements() {
+ return new PsiClass[]{mySourceClass};
+ }
+
+ public String getCodeReferencesText(int usagesCount, int filesCount) {
+ return "Class to pull up members to \"" + RefactoringUIUtil.getDescription(myTargetSuperClass, true) + "\"";
+ }
+
+ public String getCommentReferencesText(int usagesCount, int filesCount) {
+ return null;
+ }
+ };
+ }
+
+ @NotNull
+ @Override
+ protected UsageInfo[] findUsages() {
+ final List<UsageInfo> result = new ArrayList<UsageInfo>();
+ for (GrMemberInfo info : myMembersToMove) {
+ final PsiMember member = info.getMember();
+ if (member.hasModifierProperty(PsiModifier.STATIC)) {
+ for (PsiReference reference : ReferencesSearch.search(member)) {
+ result.add(new UsageInfo(reference));
+ }
+ }
+ }
+
+ return DefaultGroovyMethods.asType(result, UsageInfo[].class);
+ }
+
+ @Override
+ protected void performRefactoring(UsageInfo[] usages) {
+ moveMembersToBase();
+ //moveFieldInitializations(); todo
+ for (UsageInfo usage : usages) {
+ PsiElement element = usage.getElement();
+ if (element instanceof GrReferenceExpression) {
+ GrExpression qualifier = ((GrReferenceExpression)element).getQualifier();
+ if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).resolve().equals(mySourceClass)) {
+ ((GrReferenceExpression)qualifier).bindToElement(myTargetSuperClass);
+ }
+ }
+ }
+
+ /*
+ todo
+ ApplicationManager.application.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ processMethodsDuplicates();
+ }
+ }, ModalityState.NON_MODAL, myProject.getDisposed());*/
+
+ }
+
+ @Override
+ protected String getCommandName() {
+ return RefactoringBundle.message("pullUp.command", DescriptiveNameUtil.getDescriptiveName(mySourceClass));
+ }
+
+ public void moveMembersToBase() throws IncorrectOperationException {
+ final HashSet<PsiMember> movedMembers = ContainerUtil.newHashSet();
+ myMembersAfterMove = ContainerUtil.newHashSet();
+
+ // build aux sets
+ for (GrMemberInfo info : myMembersToMove) {
+ movedMembers.add(info.getMember());
+ }
+
+
+ // correct private member visibility
+ for (GrMemberInfo info : myMembersToMove) {
+ if (info.getMember() instanceof PsiClass && info.getOverrides() != null) continue;
+ setCorrectVisibility(movedMembers, info);
+ GroovyChangeContextUtil.encodeContextInfo(info.getMember());
+ info.getMember().accept(new QualifiedThisSuperSearcher());
+ fixReferencesToStatic(info.getMember(), movedMembers);
+ }
+
+
+
+
+ final PsiSubstitutor substitutor = upDownSuperClassSubstitutor();
+
+ // do actual move
+ for (GrMemberInfo info : myMembersToMove) {
+ if (info.getMember() instanceof PsiMethod) {
+ doMoveMethod(movedMembers, substitutor, info);
+ }
+ else if (info.getMember() instanceof GrField) {
+ doMoveField(movedMembers, substitutor, info);
+ }
+ else if (info.getMember() instanceof PsiClass) {
+ doMoveClass(movedMembers, substitutor, info);
+ }
+ }
+
+
+ ExplicitSuperDeleter explicitSuperDeleter = new ExplicitSuperDeleter();
+ for (PsiMember member : myMembersAfterMove) {
+ ((GrMember)member).accept(explicitSuperDeleter);
+ }
+ explicitSuperDeleter.fixSupers();
+
+ final QualifiedThisSuperAdjuster qualifiedThisSuperAdjuster = new QualifiedThisSuperAdjuster();
+ for (PsiMember member : myMembersAfterMove) {
+ ((GrMember)member).accept(qualifiedThisSuperAdjuster);
+ }
+
+ for (PsiMember member : myMembersAfterMove) {
+ GroovyChangeContextUtil.decodeContextInfo(member, null, null);
+ }
+
+
+ final JavaRefactoringListenerManagerImpl listenerManager = (JavaRefactoringListenerManagerImpl)JavaRefactoringListenerManager.getInstance(myProject);
+ for (final PsiMember movedMember : myMembersAfterMove) {
+ ((GroovyPsiElement)movedMember).accept(new GroovyRecursiveElementVisitor() {
+ @Override
+ public void visitReferenceExpression(GrReferenceExpression referenceExpression) {
+ if (processRef(referenceExpression)) return;
+ super.visitReferenceExpression(referenceExpression);
+ }
+
+ @Override
+ public void visitCodeReferenceElement(GrCodeReferenceElement refElement) {
+ if (processRef(refElement)) return;
+ super.visitCodeReferenceElement(refElement);
+ }
+
+ private boolean processRef(@NotNull GrReferenceElement<? extends GroovyPsiElement> refElement) {
+ final PsiElement qualifier = refElement.getQualifier();
+ if (qualifier != null) {
+ final Boolean preserveQualifier = qualifier.getCopyableUserData(PRESERVE_QUALIFIER);
+ if (preserveQualifier != null && !preserveQualifier) {
+ refElement.setQualifier(null);
+ return true;
+ }
+ }
+ return false;
+ }
+ });
+ listenerManager.fireMemberMoved(mySourceClass, movedMember);
+ }
+ }
+
+ private PsiSubstitutor upDownSuperClassSubstitutor() {
+ PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
+ for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(mySourceClass)) {
+ substitutor = substitutor.put(parameter, null);
+ }
+
+ final Map<PsiTypeParameter, PsiType> substitutionMap =
+ TypeConversionUtil.getSuperClassSubstitutor(myTargetSuperClass, mySourceClass, PsiSubstitutor.EMPTY).getSubstitutionMap();
+ for (PsiTypeParameter parameter : substitutionMap.keySet()) {
+ final PsiType type = substitutionMap.get(parameter);
+ final PsiClass resolvedClass = PsiUtil.resolveClassInType(type);
+ if (resolvedClass instanceof PsiTypeParameter) {
+ substitutor = substitutor.put((PsiTypeParameter)resolvedClass, JavaPsiFacade.getElementFactory(myProject).createType(parameter));
+ }
+ }
+
+ return substitutor;
+ }
+
+ public void setCorrectVisibility(final HashSet<PsiMember> movedMembers, GrMemberInfo info) {
+ PsiModifierListOwner modifierListOwner = info.getMember();
+ if (myTargetSuperClass.isInterface()) {
+ PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PUBLIC, true);
+ }
+ else if (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE)) {
+ if (info.isToAbstract() || willBeUsedInSubclass(modifierListOwner, movedMembers, myTargetSuperClass, mySourceClass)) {
+ PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PROTECTED, true);
+ }
+
+ if (modifierListOwner instanceof GrTypeDefinition) {
+ ((GrTypeDefinition)modifierListOwner).accept(new GroovyRecursiveElementVisitor() {
+ @Override
+ public void visitMethod(GrMethod method) {
+ check(method);
+ }
+
+ @Override
+ public void visitField(GrField field) {
+ check(field);
+ }
+
+ @Override
+ public void visitTypeDefinition(GrTypeDefinition typeDefinition) {
+ check(typeDefinition);
+ super.visitTypeDefinition(typeDefinition);
+ }
+
+ private void check(PsiMember member) {
+ if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
+ if (willBeUsedInSubclass(member, movedMembers, myTargetSuperClass, mySourceClass)) {
+ PsiUtil.setModifierProperty(member, PsiModifier.PROTECTED, true);
+ }
+ }
+ }
+ });
+ }
+ }
+ }
+
+ private static boolean willBeUsedInSubclass(PsiElement member, Set<PsiMember> movedMembers, PsiClass superclass, PsiClass subclass) {
+ for (PsiReference ref : ReferencesSearch.search(member, new LocalSearchScope(subclass), false)) {
+ PsiElement element = ref.getElement();
+ if (!RefactoringHierarchyUtil.willBeInTargetClass(element, movedMembers, superclass, false)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private void doMoveMethod(Set<PsiMember> movedMembers, PsiSubstitutor substitutor, GrMemberInfo info) {
+ GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject);
+ GrMethod method = (GrMethod)info.getMember();
+ PsiMethod sibling = method;
+ PsiMethod anchor = null;
+ while (sibling != null) {
+ sibling = PsiTreeUtil.getNextSiblingOfType(sibling, PsiMethod.class);
+ if (sibling != null) {
+ anchor = MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(method.getContainingClass(), myTargetSuperClass,
+ sibling.getSignature(PsiSubstitutor.EMPTY), false);
+ if (anchor != null) {
+ break;
+ }
+ }
+ }
+
+ GrMethod methodCopy = (GrMethod)method.copy();
+ if (method.findSuperMethods(myTargetSuperClass).length == 0) {
+ deleteOverrideAnnotationIfFound(methodCopy);
+ }
+
+ final boolean isOriginalMethodAbstract =
+ method.hasModifierProperty(PsiModifier.ABSTRACT) || method.hasModifierProperty(PsiModifier.DEFAULT);
+ if (myTargetSuperClass.isInterface() || info.isToAbstract()) {
+ GroovyChangeContextUtil.clearContextInfo(method);
+ RefactoringUtil.makeMethodAbstract(myTargetSuperClass, methodCopy);
+ if (myTargetSuperClass.isInterface()) {
+ PsiUtil.setModifierProperty(methodCopy, PsiModifier.ABSTRACT, false);
+ }
+ replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+
+ myDocCommentPolicy.processCopiedJavaDoc(methodCopy.getDocComment(), method.getDocComment(), isOriginalMethodAbstract);
+
+ final PsiMember movedElement =
+ anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy);
+ CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(method.getProject());
+ if (styleSettings.INSERT_OVERRIDE_ANNOTATION) {
+ if (PsiUtil.isLanguageLevel5OrHigher(mySourceClass) && !myTargetSuperClass.isInterface() ||
+ PsiUtil.isLanguageLevel6OrHigher(mySourceClass)) {
+ new AddAnnotationFix(CommonClassNames.JAVA_LANG_OVERRIDE, method)
+ .invoke(method.getProject(), null, mySourceClass.getContainingFile());
+ }
+ }
+
+ if (!PsiUtil.isLanguageLevel6OrHigher(mySourceClass) && myTargetSuperClass.isInterface()) {
+ if (isOriginalMethodAbstract) {
+ for (PsiMethod oMethod : OverridingMethodsSearch.search(method)) {
+ deleteOverrideAnnotationIfFound(oMethod);
+ }
+ }
+
+ deleteOverrideAnnotationIfFound(method);
+ }
+
+ myMembersAfterMove.add(movedElement);
+ if (isOriginalMethodAbstract) {
+ method.delete();
+ }
+ }
+ else {
+ if (isOriginalMethodAbstract) {
+ PsiUtil.setModifierProperty(myTargetSuperClass, PsiModifier.ABSTRACT, true);
+ }
+
+ //fixReferencesToStatic(methodCopy, movedMembers);
+ replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+ final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(methodCopy, false);
+ if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) {
+ superClassMethod.replace(methodCopy);
+ }
+ else {
+ final PsiMember movedElement =
+ anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy);
+ myMembersAfterMove.add(movedElement);
+ }
+
+ method.delete();
+ }
+ }
+
+ private static void deleteOverrideAnnotationIfFound(PsiMethod oMethod) {
+ final PsiAnnotation annotation = AnnotationUtil.findAnnotation(oMethod, CommonClassNames.JAVA_LANG_OVERRIDE);
+ if (annotation != null) {
+ PsiElement prev = annotation.getPrevSibling();
+ PsiElement next = annotation.getNextSibling();
+ if ((prev == null || org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isLineFeed(prev)) &&
+ org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isLineFeed(next)) {
+ next.delete();
+ }
+ annotation.delete();
+ }
+ }
+
+ public static void replaceMovedMemberTypeParameters(final PsiElement member,
+ final Iterable<PsiTypeParameter> parametersIterable,
+ final PsiSubstitutor substitutor,
+ final GroovyPsiElementFactory factory) {
+ final Map<PsiElement, PsiElement> replacement = new LinkedHashMap<PsiElement, PsiElement>();
+ for (PsiTypeParameter parameter : parametersIterable) {
+ PsiType substitutedType = substitutor.substitute(parameter);
+ if (substitutedType == null) {
+ substitutedType = TypeConversionUtil.erasure(factory.createType(parameter));
+ }
+
+ PsiElement scopeElement = member instanceof GrField ? member.getParent() : member;
+ for (PsiReference reference : ReferencesSearch.search(parameter, new LocalSearchScope(scopeElement))) {
+ final PsiElement element = reference.getElement();
+ final PsiElement parent = element.getParent();
+ if (parent instanceof PsiTypeElement) {
+ replacement.put(parent, factory.createTypeElement(substitutedType));
+ }
+ else if (element instanceof GrCodeReferenceElement && substitutedType instanceof PsiClassType) {
+ replacement.put(element, factory.createReferenceElementByType((PsiClassType)substitutedType));
+ }
+ }
+ }
+
+ for (PsiElement element : replacement.keySet()) {
+ if (element.isValid()) {
+ element.replace(replacement.get(element));
+ }
+ }
+ }
+
+ private void fixReferencesToStatic(GroovyPsiElement classMember, Set<PsiMember> movedMembers) throws IncorrectOperationException {
+ final StaticReferencesCollector collector = new StaticReferencesCollector(movedMembers);
+ classMember.accept(collector);
+ ArrayList<GrReferenceElement> refs = collector.getReferences();
+ ArrayList<PsiElement> members = collector.getReferees();
+ ArrayList<PsiClass> classes = collector.getRefereeClasses();
+ GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
+
+ for (int i = 0; i < refs.size(); i++) {
+ GrReferenceElement ref = refs.get(i);
+ PsiElement namedElement = members.get(i);
+ PsiClass aClass = classes.get(i);
+
+ if (namedElement instanceof PsiNamedElement) {
+ GrReferenceExpression newRef = (GrReferenceExpression)factory.createExpressionFromText("a." + ((PsiNamedElement)namedElement).getName(), null);
+ GrExpression qualifier = newRef.getQualifierExpression();
+ assert qualifier != null;
+ qualifier = (GrExpression)qualifier.replace(factory.createReferenceExpressionFromText(aClass.getQualifiedName()));
+ qualifier.putCopyableUserData(PRESERVE_QUALIFIER, ref.isQualified());
+ PsiElement replaced = ref.replace(newRef);
+ JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(replaced);
+ }
+ }
+ }
+
+
+ private class StaticReferencesCollector extends GrClassMemberReferenceVisitor {
+ private final ArrayList<GrReferenceElement> myReferences = new ArrayList<GrReferenceElement>();
+ private final ArrayList<PsiElement> myReferees = new ArrayList<PsiElement>();
+ private final ArrayList<PsiClass> myRefereeClasses = new ArrayList<PsiClass>();
+ private final Set<PsiMember> myMovedMembers;
+
+ private StaticReferencesCollector(Set<PsiMember> movedMembers) {
+ super(mySourceClass);
+ myMovedMembers = movedMembers;
+ }
+
+ public ArrayList<PsiElement> getReferees() {
+ return myReferees;
+ }
+
+ public ArrayList<PsiClass> getRefereeClasses() {
+ return myRefereeClasses;
+ }
+
+ public ArrayList<GrReferenceElement> getReferences() {
+ return myReferences;
+ }
+
+ @Override
+ protected void visitClassMemberReferenceElement(GrMember classMember, GrReferenceElement classMemberReference) {
+ if (classMember.hasModifierProperty(PsiModifier.STATIC) /*&& classMemberReference.isQualified()*/) {
+ if (!myMovedMembers.contains(classMember) &&
+ RefactoringHierarchyUtil.isMemberBetween(myTargetSuperClass, mySourceClass, classMember)) {
+ myReferences.add(classMemberReference);
+ myReferees.add(classMember);
+ myRefereeClasses.add(classMember.getContainingClass());
+ }
+ else if (myMovedMembers.contains(classMember) || myMembersAfterMove.contains(classMember)) {
+ myReferences.add(classMemberReference);
+ myReferees.add(classMember);
+ myRefereeClasses.add(myTargetSuperClass);
+ }
+ }
+ }
+ }
+
+ private class ExplicitSuperDeleter extends GroovyRecursiveElementVisitor {
+ private final ArrayList<GrExpression> mySupersToDelete = ContainerUtil.newArrayList();
+ private final ArrayList<GrReferenceExpression> mySupersToChangeToThis = ContainerUtil.newArrayList();
+
+ @Override
+ public void visitReferenceExpression(GrReferenceExpression expression) {
+ super.visitReferenceExpression(expression);
+ if(org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(expression.getQualifierExpression())) {
+ PsiElement resolved = expression.resolve();
+ if (resolved == null || resolved instanceof PsiMethod && shouldFixSuper((PsiMethod) resolved)) {
+ mySupersToDelete.add(expression.getQualifierExpression());
+ }
+ }
+ else if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(expression)) {
+ mySupersToChangeToThis.add(expression);
+ }
+ }
+
+ @Override
+ public void visitTypeDefinition(GrTypeDefinition typeDefinition) {
+ //do nothing
+ }
+
+ private boolean shouldFixSuper(PsiMethod method) {
+ for (PsiMember element : myMembersAfterMove) {
+ if (element instanceof PsiMethod) {
+ PsiMethod member = (PsiMethod)element;
+ // if there is such member among moved members, super qualifier
+ // should not be removed
+ final PsiManager manager = method.getManager();
+ if (manager.areElementsEquivalent(member.getContainingClass(), method.getContainingClass()) &&
+ MethodSignatureUtil.areSignaturesEqual(member, method)) {
+ return false;
+ }
+ }
+ }
+
+ final PsiMethod methodFromSuper = myTargetSuperClass.findMethodBySignature(method, false);
+ return methodFromSuper == null;
+ }
+
+ public void fixSupers() throws IncorrectOperationException {
+ final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
+ GrReferenceExpression thisExpression = (GrReferenceExpression) factory.createExpressionFromText("this", null);
+ for (GrExpression expression : mySupersToDelete) {
+ expression.delete();
+ }
+
+ for (GrReferenceExpression superExpression : mySupersToChangeToThis) {
+ superExpression.replace(thisExpression);
+ }
+ }
+ }
+
+ private class QualifiedThisSuperAdjuster extends GroovyRecursiveElementVisitor {
+ @Override
+ public void visitReferenceExpression(GrReferenceExpression expression) {
+ super.visitReferenceExpression(expression);
+ if (expression.getCopyableUserData(SUPER_REF) != null) {
+ expression.putCopyableUserData(SUPER_REF, null);
+ final GrExpression qualifier = expression.getQualifier();
+ if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).isReferenceTo(mySourceClass)) {
+ try {
+ GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
+ GrExpression newExpr = factory.createExpressionFromText(myTargetSuperClass.getName() + ".this", null);
+ expression.replace(newExpr);
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+ }
+ else if (expression.getCopyableUserData(THIS_REF) != null) {
+ expression.putCopyableUserData(THIS_REF, null);
+ final GrExpression qualifier = expression.getQualifier();
+ if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).isReferenceTo(mySourceClass)) {
+ try {
+ ((GrReferenceExpression)qualifier).bindToElement(myTargetSuperClass);
+ GroovyChangeContextUtil.clearContextInfo(qualifier);
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+ }
+ }
+ }
+
+ private void doMoveField(Set<PsiMember> movedMembers, PsiSubstitutor substitutor, GrMemberInfo info) {
+ GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject);
+ GrField field = (GrField)info.getMember();
+ field.normalizeDeclaration();
+ replaceMovedMemberTypeParameters(field, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+ //fixReferencesToStatic(field, movedMembers);
+ if (myTargetSuperClass.isInterface()) {
+ PsiUtil.setModifierProperty(field, PsiModifier.PUBLIC, true);
+ }
+ final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(field);
+ myMembersAfterMove.add(movedElement);
+ field.delete();
+ }
+
+ private void doMoveClass(Set<PsiMember> movedMembers, PsiSubstitutor substitutor, GrMemberInfo info) {
+ GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject);
+ GrTypeDefinition aClass = (GrTypeDefinition)info.getMember();
+ if (Boolean.FALSE.equals(info.getOverrides())) {
+ final GrReferenceList sourceReferenceList = info.getSourceReferenceList();
+ LOG.assertTrue(sourceReferenceList != null);
+ GrCodeReferenceElement ref = mySourceClass.equals(sourceReferenceList.getParent()) ?
+ removeFromReferenceList(sourceReferenceList, aClass) :
+ findReferenceToClass(sourceReferenceList, aClass);
+ if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) {
+ replaceMovedMemberTypeParameters(ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+ GrReferenceList referenceList;
+ if (myTargetSuperClass.isInterface()) {
+ referenceList = myTargetSuperClass.getExtendsClause();
+ if (referenceList == null) {
+ GrExtendsClause newClause = GroovyPsiElementFactory.getInstance(myProject).createExtendsClause();
+ PsiElement anchor = myTargetSuperClass.getTypeParameterList() != null ? myTargetSuperClass.getTypeParameterList():
+ myTargetSuperClass.getNameIdentifierGroovy();
+ referenceList = (GrReferenceList)myTargetSuperClass.addAfter(newClause, anchor);
+ addSpacesAround(referenceList);
+ }
+ }
+ else {
+ referenceList = myTargetSuperClass.getImplementsClause();
+
+ if (referenceList == null) {
+ GrImplementsClause newClause = GroovyPsiElementFactory.getInstance(myProject).createImplementsClause();
+ PsiElement anchor = myTargetSuperClass.getExtendsClause() != null ? myTargetSuperClass.getExtendsClause() :
+ myTargetSuperClass.getTypeParameterList() != null ? myTargetSuperClass.getTypeParameterList() :
+ myTargetSuperClass.getNameIdentifierGroovy();
+ referenceList = (GrReferenceList)myTargetSuperClass.addAfter(newClause, anchor);
+ addSpacesAround(referenceList);
+ }
+
+ }
+
+ assert referenceList != null;
+ referenceList.add(ref);
+ }
+ }
+ else {
+ replaceMovedMemberTypeParameters(aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
+ //fixReferencesToStatic(aClass, movedMembers);
+ PsiMember movedElement = (PsiMember)myTargetSuperClass.addAfter(aClass, null);
+ //movedElement = (PsiMember)CodeStyleManager.getInstance(myProject).reformat(movedElement);
+ myMembersAfterMove.add(movedElement);
+ aClass.delete();
+ }
+ }
+
+ private static void addSpacesAround(@NotNull GrReferenceList list) {
+ PsiElement prev = list.getPrevSibling();
+ if (!PsiImplUtil.isWhiteSpace(prev)) {
+ list.getParent().getNode().addLeaf(TokenType.WHITE_SPACE, " ", list.getNode());
+ }
+
+ PsiElement next = list.getNextSibling();
+ if (!PsiImplUtil.isWhiteSpace(next)) {
+ list.getParent().getNode().addLeaf(TokenType.WHITE_SPACE, " ", list.getNode().getTreeNext());
+ }
+ }
+
+ public static GrCodeReferenceElement findReferenceToClass(GrReferenceList refList, PsiClass aClass) {
+ GrCodeReferenceElement[] refs = refList.getReferenceElements();
+ for (GrCodeReferenceElement ref : refs) {
+ if (ref.isReferenceTo(aClass)) {
+ return ref;
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * removes a reference to the specified class from the reference list given
+ *
+ * @return if removed - a reference to the class or null if there were no references to this class in the reference list
+ */
+ public static GrCodeReferenceElement removeFromReferenceList(GrReferenceList refList, PsiClass aClass) throws IncorrectOperationException {
+ GrCodeReferenceElement[] refs = refList.getReferenceElements();
+ for (GrCodeReferenceElement ref : refs) {
+ if (ref.isReferenceTo(aClass)) {
+ GrCodeReferenceElement refCopy = (GrCodeReferenceElement)ref.copy();
+ ref.delete();
+ return refCopy;
+ }
+ }
+ return null;
+ }
+
+ private class QualifiedThisSuperSearcher extends GroovyRecursiveElementVisitor {
+ @Override
+ public void visitReferenceExpression(GrReferenceExpression expression) {
+ super.visitReferenceExpression(expression);
+ if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(expression)) {
+ final GrExpression qualifier = expression.getQualifier();
+ if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).isReferenceTo(mySourceClass)) {
+ try {
+ expression.putCopyableUserData(SUPER_REF, Boolean.TRUE);
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+ }
+ else if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isThisReference(expression)) {
+ final GrExpression qualifier = expression.getQualifier();
+ if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).isReferenceTo(mySourceClass)) {
+ try {
+ expression.putCopyableUserData(THIS_REF, Boolean.TRUE);
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+ }
+
+ }
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java
index acac929..5b989fa 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java
@@ -105,6 +105,11 @@
return inClass;
}
+ @Override
+ public char getMnemonic() {
+ return 'G';
+ }
+
@NotNull
@Override
public String getName() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/GroovyIndexPatternBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/GroovyIndexPatternBuilder.java
index 06e1513..d03fd8a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/GroovyIndexPatternBuilder.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/GroovyIndexPatternBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
import com.intellij.psi.impl.search.IndexPatternBuilder;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyLexer;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
@@ -30,14 +31,14 @@
* Date: 16.07.2008
*/
public class GroovyIndexPatternBuilder implements IndexPatternBuilder {
- public Lexer getIndexingLexer(PsiFile file) {
+ public Lexer getIndexingLexer(@NotNull PsiFile file) {
if (file instanceof GroovyFile) {
return new GroovyLexer();
}
return null;
}
- public TokenSet getCommentTokenSet(PsiFile file) {
+ public TokenSet getCommentTokenSet(@NotNull PsiFile file) {
return TokenSets.ALL_COMMENT_TOKENS;
}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy
index 06dd772..316de96 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy
@@ -1,29 +1,28 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * 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
+ * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package org.jetbrains.plugins.groovy.compiler
import com.intellij.compiler.CompilerConfiguration
-import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.compiler.CompilerConfigurationImpl
import com.intellij.compiler.server.BuildManager
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.testFramework.PsiTestUtil
import org.jetbrains.plugins.groovy.util.TestUtils
-
/**
* @author peter
*/
@@ -46,35 +45,6 @@
super.tearDown()
}
- public void testTraitStubs() throws Throwable {
- myFixture.addFileToProject("A.groovy", """
-@Trait
-abstract class SomeTrait {
- abstract def some()
- def concrete() {}
-}
-
-@Trait
-abstract class AnotherTrait extends SomeTrait {
- abstract def another()
-}
-
-class Goo implements SomeTrait {
- def some() {}
-}
-class Bar implements AnotherTrait {
- def some() {}
- def another() {}
-}
-""");
- myFixture.addClass("""
-class Foo implements SomeTrait {
- public Object some() { return null; }
- public Object concrete() { return null; }
-}""")
- assertEmpty(make());
- }
-
public void testRecompileDependentGroovyClasses() throws Exception {
def a = myFixture.addFileToProject("A.gpp", """
class A {
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy
index 92331f6..e18c4ee 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy
@@ -1600,4 +1600,52 @@
""")
}
+
+ void testAnnotationAsAnnotationValue() {
+ testHighlighting('''\
+@interface A {}
+@interface B {
+ A[] foo()
+}
+@interface C {
+ A foo()
+}
+
+@B(foo = @A)
+@B(foo = [@A])
+@C(foo = @A)
+@C(foo = <error descr="Cannot assign 'Integer' to 'A'">2</error>)
+def foo
+''')
+ }
+
+ void testSameNameMethodWithDifferentAccessModifiers() {
+ testHighlighting('''
+
+class A {
+ def foo(){}
+ def foo(int x) {}
+}
+
+class B {
+ <error descr="Mixing private and public/protected methods of the same name">private def foo()</error>{}
+ <error descr="Mixing private and public/protected methods of the same name">public def foo(int x)</error> {}
+}
+
+class C {
+ private foo(){}
+ private foo(int x) {}
+}
+
+class D {
+ <error>private foo()</error>{}
+ <error>protected foo(int x)</error> {}
+}
+
+class E {
+ <error>private foo()</error>{}
+ <error>def foo(int x)</error> {}
+}
+''')
+ }
}
\ No newline at end of file
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.groovy
index f78896c..1536309 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.groovy
@@ -239,7 +239,7 @@
doTest(new SimpleInfo('optional', -1, null, '1', 'int'));
}
catch (ConflictsInTestsException e) {
- assertEquals('Method foo(int) is already defined in the class <b><code>Test</code></b>.', e.message)
+ assertEquals('Method foo(int) is already defined in the class <b><code>Test</code></b>', e.message)
return
}
assertFalse('conflicts are not detected!', true);
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy
index 4fdb080..6c7f1b5 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy
@@ -238,7 +238,7 @@
}
public void testSuperInExpression() {
- doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class.");
+ doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class");
}
public void testWeirdQualifierAndParameter() {
@@ -262,7 +262,7 @@
}*/
public void testSuperWithSideEffect() {
- doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class.");
+ doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class");
}
public void testConflictingField() {
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/IntroduceParameterTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/IntroduceParameterTest.groovy
index 970eed4..fe8cfe0 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/IntroduceParameterTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/IntroduceParameterTest.groovy
@@ -1,17 +1,17 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * 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
+ * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package org.jetbrains.plugins.groovy.refactoring.introduceParameter
@@ -184,7 +184,7 @@
}
public void testSuperInExpression() {
- doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class.");
+ doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class");
}
public void testWeirdQualifierAndParameter() {
@@ -208,7 +208,7 @@
}*/
public void testSuperWithSideEffect() {
- doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class.");
+ doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class");
}
public void testConflictingField() {
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpTest.groovy
new file mode 100644
index 0000000..e3d95a7
--- /dev/null
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpTest.groovy
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.refactoring.memberPullUp
+
+import com.intellij.psi.*
+import com.intellij.psi.util.PsiTreeUtil
+import com.intellij.refactoring.listeners.JavaRefactoringListenerManager
+import com.intellij.refactoring.listeners.MoveMemberListener
+import com.intellij.refactoring.util.DocCommentPolicy
+import com.intellij.util.ui.UIUtil
+import junit.framework.Assert
+import org.jetbrains.plugins.groovy.LightGroovyTestCase
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember
+import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfo
+import org.jetbrains.plugins.groovy.util.TestUtils
+/**
+ * Created by Max Medvedev on 8/17/13
+ */
+class GrPullUpTest extends LightGroovyTestCase {
+ @Override
+ protected String getBasePath() {
+ TestUtils.testDataPath + 'refactoring/pullUp'
+ }
+
+ public void testQualifiedThis() {
+ doTest(new MemberDescriptor("Inner", PsiClass));
+ }
+
+ public void testQualifiedSuper() {
+ doTest(new MemberDescriptor("Inner", PsiClass));
+ }
+
+ public void testQualifiedReference() { // IDEADEV-25008
+ doTest(new MemberDescriptor("x", PsiField),
+ new MemberDescriptor("getX", PsiMethod),
+ new MemberDescriptor("setX", PsiMethod));
+ }
+
+ public void testPullUpInheritedStaticClasses() {
+ doTest(new MemberDescriptor("C", PsiClass),
+ new MemberDescriptor("D", PsiClass));
+ }
+
+ public void testPullUpPrivateInnerClassWithPrivateConstructor() {
+ doTest(new MemberDescriptor("C", PsiClass));
+ }
+
+ public void testPullUpAndMakeAbstract() {
+ doTest(new MemberDescriptor("a", PsiMethod),
+ new MemberDescriptor("b", PsiMethod, true));
+ }
+
+ public void _testTryCatchFieldInitializer() {
+ doTest(new MemberDescriptor("field", PsiField));
+ }
+
+ public void testIfFieldInitializationWithNonMovedField() {
+ doTest(new MemberDescriptor("f", PsiField));
+ }
+
+ public void _testIfFieldMovedInitialization() {
+ doTest(new MemberDescriptor("f", PsiField));
+ }
+
+ public void _testMultipleConstructorsFieldInitialization() {
+ doTest(new MemberDescriptor("f", PsiField));
+ }
+
+ public void _testMultipleConstructorsFieldInitializationNoGood() {
+ doTest(new MemberDescriptor("f", PsiField));
+ }
+
+ public void _testRemoveOverride() {
+ doTest(new MemberDescriptor("get", PsiMethod));
+ }
+
+ public void testTypeParamErasure() {
+ doTest(new MemberDescriptor("f", PsiField));
+ }
+
+ public void testTypeParamSubst() {
+ doTest(new MemberDescriptor("f", PsiField));
+ }
+
+ public void testTypeArgument() {
+ doTest(new MemberDescriptor("f", PsiField));
+ }
+
+ public void testGenericsInAbstractMethod() {
+ doTest(new MemberDescriptor("method", PsiMethod, true));
+ }
+
+ public void _testReplaceDuplicatesInInheritors() {
+ doTest(new MemberDescriptor("foo", PsiMethod, false));
+ }
+
+ public void testGenericsInImplements() {
+ doTest(false, new MemberDescriptor("I", PsiClass));
+ }
+
+ public void testUpdateStaticRefs() {
+ doTest(false, new MemberDescriptor("foo", PsiMethod));
+ }
+
+ public void testRemoveOverrideFromPulledMethod() {
+ doTest(false, new MemberDescriptor("foo", PsiMethod));
+ }
+
+ public void testPreserveOverrideInPulledMethod() {
+ doTest(false, new MemberDescriptor("foo", PsiMethod));
+ }
+
+ public void testMergeInterfaces() {
+ doTest(false, new MemberDescriptor("I", PsiClass));
+ }
+
+ public void testTypeParamsConflictingNames() {
+ doTest(false, new MemberDescriptor("foo", PsiMethod));
+ }
+
+ public void testEscalateVisibility() {
+ doTest(false, new MemberDescriptor("foo", PsiMethod));
+ }
+
+ public void _testExtensionMethod() {
+ doTest(false, new MemberDescriptor("foo", PsiMethod));
+ }
+
+ public void testPreserveOverride() {
+ doTest(false, new MemberDescriptor("foo", PsiMethod));
+ }
+
+ private void doTest(MemberDescriptor... membersToFind) {
+ doTest(true, membersToFind);
+ }
+
+ private void doTest(final boolean checkMembersMovedCount, MemberDescriptor... membersToFind) {
+ myFixture.configureByFile(getTestName(false) + ".groovy");
+ PsiElement elementAt = myFixture.getFile().findElementAt(myFixture.getEditor().getCaretModel().getOffset());
+ final PsiClass sourceClass = PsiTreeUtil.getParentOfType(elementAt, PsiClass);
+ assertNotNull(sourceClass);
+
+ PsiClass targetClass = sourceClass.getSuperClass();
+ assertNotNull(targetClass);
+ if (!targetClass.isWritable()) {
+ final PsiClass[] interfaces = sourceClass.getInterfaces();
+ assertEquals(2, interfaces.length);
+ assertTrue(interfaces[0].isWritable());
+ targetClass = interfaces[0];
+ }
+ GrMemberInfo[] infos = findMembers(sourceClass, membersToFind);
+
+ final int[] countMoved = [0];
+ final MoveMemberListener listener = new MoveMemberListener() {
+ @Override
+ public void memberMoved(PsiClass aClass, PsiMember member) {
+ assertEquals(sourceClass, aClass);
+ countMoved[0]++;
+ }
+ };
+ JavaRefactoringListenerManager.getInstance(getProject()).addMoveMembersListener(listener);
+ final GrPullUpHelper helper = new GrPullUpHelper(sourceClass, targetClass, infos, new DocCommentPolicy(DocCommentPolicy.ASIS));
+ helper.run();
+ UIUtil.dispatchAllInvocationEvents();
+ JavaRefactoringListenerManager.getInstance(getProject()).removeMoveMembersListener(listener);
+ if (checkMembersMovedCount) {
+ assertEquals(countMoved[0], membersToFind.length);
+ }
+ myFixture.checkResultByFile(getTestName(false) + "_after.groovy");
+ }
+
+ public static class MemberDescriptor {
+ private String myName;
+ private Class<? extends PsiMember> myClass;
+ private boolean myAbstract;
+
+ public MemberDescriptor(String name, Class<? extends PsiMember> aClass, boolean isAbstract) {
+ myName = name;
+ myClass = aClass;
+ myAbstract = isAbstract;
+ }
+
+
+ public MemberDescriptor(String name, Class<? extends PsiMember> aClass) {
+ this(name, aClass, false);
+ }
+ }
+
+ public static GrMemberInfo[] findMembers(final PsiClass sourceClass, final MemberDescriptor... membersToFind) {
+ GrMemberInfo[] infos = new GrMemberInfo[membersToFind.length]
+ for (int i = 0; i < membersToFind.length; i++) {
+ final Class<? extends PsiMember> clazz = membersToFind[i].myClass
+ final String name = membersToFind[i].myName
+ PsiMember member = null
+ boolean overrides = false
+ GrReferenceList refList = null
+ if (PsiClass.isAssignableFrom(clazz)) {
+ member = sourceClass.findInnerClassByName(name, false)
+ if (member == null) {
+ final PsiClass[] supers = sourceClass.getSupers()
+ for (PsiClass superTypeClass : supers) {
+ if (superTypeClass.getName().equals(name)) {
+ member = superTypeClass
+ overrides = true
+ refList = superTypeClass.isInterface() ?
+ (sourceClass as GrTypeDefinition).getImplementsClause() :
+ (sourceClass as GrTypeDefinition).getExtendsClause()
+ break
+ }
+ }
+ }
+
+ } else if (PsiMethod.class.isAssignableFrom(clazz)) {
+ final PsiMethod[] methods = sourceClass.findMethodsByName(name, false)
+ Assert.assertEquals(1, methods.length)
+ member = methods[0]
+ } else if (PsiField.class.isAssignableFrom(clazz)) {
+ member = sourceClass.findFieldByName(name, false)
+ }
+
+ assertNotNull(member)
+ assertInstanceOf(member, GrMember)
+ infos[i] = new GrMemberInfo(member as GrMember, overrides, refList)
+ infos[i].setToAbstract(membersToFind[i].myAbstract)
+ }
+ return infos
+ }
+}
diff --git a/plugins/groovy/testdata/groovy/stubGenerator/delegateAnno.test b/plugins/groovy/testdata/groovy/stubGenerator/delegateAnno.test
index 2f202cd..ee1acc0 100644
--- a/plugins/groovy/testdata/groovy/stubGenerator/delegateAnno.test
+++ b/plugins/groovy/testdata/groovy/stubGenerator/delegateAnno.test
@@ -15,7 +15,7 @@
}
-----
public interface DelegateFoo {
-public java.lang.Object foo() ;
+public abstract java.lang.Object foo() ;
}
---
diff --git a/plugins/groovy/testdata/groovy/stubGenerator/delegationGenerics.test b/plugins/groovy/testdata/groovy/stubGenerator/delegationGenerics.test
index 1d44095..342580f 100644
--- a/plugins/groovy/testdata/groovy/stubGenerator/delegationGenerics.test
+++ b/plugins/groovy/testdata/groovy/stubGenerator/delegationGenerics.test
@@ -7,7 +7,7 @@
}
-----
public interface DelegationGenerics<K, V> {
-public V get(K k) ;
+public abstract V get(K k) ;
}
---
diff --git a/plugins/groovy/testdata/groovy/stubGenerator/methodWithItsOwnTypeParams.test b/plugins/groovy/testdata/groovy/stubGenerator/methodWithItsOwnTypeParams.test
index 98b17da..4621b10 100644
--- a/plugins/groovy/testdata/groovy/stubGenerator/methodWithItsOwnTypeParams.test
+++ b/plugins/groovy/testdata/groovy/stubGenerator/methodWithItsOwnTypeParams.test
@@ -7,7 +7,7 @@
}
-----
public interface I<S> {
-public <T> void foo(java.util.List<T> a) ;
+public abstract <T> void foo(java.util.List<T> a) ;
}
---
diff --git a/plugins/groovy/testdata/groovy/stubGenerator/rawReturnTypeInImplementation.test b/plugins/groovy/testdata/groovy/stubGenerator/rawReturnTypeInImplementation.test
index 07de458..53b639f 100644
--- a/plugins/groovy/testdata/groovy/stubGenerator/rawReturnTypeInImplementation.test
+++ b/plugins/groovy/testdata/groovy/stubGenerator/rawReturnTypeInImplementation.test
@@ -8,7 +8,7 @@
-----
public interface Callable<V> {
-public V call() throws java.lang.Exception ;
+public abstract V call() throws java.lang.Exception ;
}
---
diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno.java
index b6732ac..6dd2d67 100644
--- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno.java
+++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno.java
@@ -1,6 +1,6 @@
public @interface Inter {
-public java.lang.String foo() ;
-public int de() default 4;
-public java.lang.String[] bar() default "1, 2, 3";
-public java.lang.String[] strings() ;
+public abstract java.lang.String foo() ;
+public abstract int de() default 4;
+public abstract java.lang.String[] bar() default "1, 2, 3";
+public abstract java.lang.String[] strings() ;
}
diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno1.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno1.java
index a6f9da97..12dfa62 100644
--- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno1.java
+++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/anno1.java
@@ -2,10 +2,10 @@
A,B;
}
public @interface Inter {
-public I[] bar() default {@I(2), @I(a = 5)};
-public java.lang.String[] strings() default {"a"};
-public E foo() default E.A;
+public abstract I[] bar() default {@I(2), @I(a = 5)};
+public abstract java.lang.String[] strings() default {"a"};
+public abstract E foo() default E.A;
}
public @interface I {
-public int a() default 4;
+public abstract int a() default 4;
}
diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/useAnno.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/useAnno.java
index 6e32f6b..4905f4a 100644
--- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/useAnno.java
+++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/useAnno.java
@@ -1,7 +1,7 @@
@p.I package p;
public @interface I {
-public int x() ;
+public abstract int x() ;
}
@p.I public class A {
@p.I public A() {}
diff --git a/plugins/groovy/testdata/refactoring/move/moveClassToInner/moveMultiple1/after/pack2/A.groovy b/plugins/groovy/testdata/refactoring/move/moveClassToInner/moveMultiple1/after/pack2/A.groovy
index 4a3031b..307452b 100644
--- a/plugins/groovy/testdata/refactoring/move/moveClassToInner/moveMultiple1/after/pack2/A.groovy
+++ b/plugins/groovy/testdata/refactoring/move/moveClassToInner/moveMultiple1/after/pack2/A.groovy
@@ -5,6 +5,7 @@
Class2 a;
Class2 b;
}
+
public static class Class2 {
}
}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/EscalateVisibility.groovy b/plugins/groovy/testdata/refactoring/pullUp/EscalateVisibility.groovy
new file mode 100644
index 0000000..6f50634
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/EscalateVisibility.groovy
@@ -0,0 +1,10 @@
+class Foo {
+
+}
+
+class FooImpl extends Foo {
+ private void fo<caret>o(){}
+ void bar() {
+ foo();
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/EscalateVisibility_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/EscalateVisibility_after.groovy
new file mode 100644
index 0000000..725e5c5
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/EscalateVisibility_after.groovy
@@ -0,0 +1,10 @@
+class Foo {
+
+ protected void foo(){}
+}
+
+class FooImpl extends Foo {
+ void bar() {
+ foo();
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/ExtensionMethod.groovy b/plugins/groovy/testdata/refactoring/pullUp/ExtensionMethod.groovy
new file mode 100644
index 0000000..4a59e1e
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/ExtensionMethod.groovy
@@ -0,0 +1,8 @@
+interface Base {
+}
+
+interface I2 extends Base {
+ default void foo<caret>() {
+ System.out.println("Hi there.");
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/ExtensionMethod_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/ExtensionMethod_after.groovy
new file mode 100644
index 0000000..469ee86
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/ExtensionMethod_after.groovy
@@ -0,0 +1,8 @@
+interface Base {
+ default void foo() {
+ System.out.println("Hi there.");
+ }
+}
+
+interface I2 extends Base {
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/GenericsInAbstractMethod.groovy b/plugins/groovy/testdata/refactoring/pullUp/GenericsInAbstractMethod.groovy
new file mode 100644
index 0000000..bd2f499
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/GenericsInAbstractMethod.groovy
@@ -0,0 +1,5 @@
+public abstract class Parent<S> {}
+
+class Child<T> extends Parent<T> {
+ void <caret>method(T t){}
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/GenericsInAbstractMethod_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/GenericsInAbstractMethod_after.groovy
new file mode 100644
index 0000000..353201f
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/GenericsInAbstractMethod_after.groovy
@@ -0,0 +1,8 @@
+public abstract class Parent<S> {
+ abstract void method(S t)
+}
+
+class Child<T> extends Parent<T> {
+ @Override
+ void method(T t){}
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/GenericsInImplements.groovy b/plugins/groovy/testdata/refactoring/pullUp/GenericsInImplements.groovy
new file mode 100644
index 0000000..07e1f89a
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/GenericsInImplements.groovy
@@ -0,0 +1,10 @@
+public class Parent<S> {}
+
+interface I<IT> {
+ void method(IT t);
+}
+
+class Child<T> extends Parent<T> implements I<T>{
+ <caret>
+ public void method(T t){}
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/GenericsInImplements_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/GenericsInImplements_after.groovy
new file mode 100644
index 0000000..3aca9f8
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/GenericsInImplements_after.groovy
@@ -0,0 +1,10 @@
+public class Parent<S> implements I<S> {}
+
+interface I<IT> {
+ void method(IT t);
+}
+
+class Child<T> extends Parent<T> {
+
+ public void method(T t){}
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/IfFieldInitializationWithNonMovedField.groovy b/plugins/groovy/testdata/refactoring/pullUp/IfFieldInitializationWithNonMovedField.groovy
new file mode 100644
index 0000000..ba3609d
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/IfFieldInitializationWithNonMovedField.groovy
@@ -0,0 +1,18 @@
+public class A {
+}
+
+class B extends A {
+ final String <caret>f;
+ final String foo;
+
+ B(String fi, String foo) {
+ this.foo = foo;
+ if (fi == this.foo) {
+ f = foo;
+ } else {
+ f = "";
+ }
+ }
+
+
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/IfFieldInitializationWithNonMovedField_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/IfFieldInitializationWithNonMovedField_after.groovy
new file mode 100644
index 0000000..8d52600
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/IfFieldInitializationWithNonMovedField_after.groovy
@@ -0,0 +1,18 @@
+public class A {
+ protected final String f
+}
+
+class B extends A {
+ final String foo;
+
+ B(String fi, String foo) {
+ this.foo = foo;
+ if (fi == this.foo) {
+ f = foo;
+ } else {
+ f = "";
+ }
+ }
+
+
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/IfFieldMovedInitialization.groovy b/plugins/groovy/testdata/refactoring/pullUp/IfFieldMovedInitialization.groovy
new file mode 100644
index 0000000..f541f0e
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/IfFieldMovedInitialization.groovy
@@ -0,0 +1,18 @@
+public class A {
+}
+
+class B extends A {
+ final String <caret>f;
+ final String foo;
+
+ B(String fi, String foo) {
+ this.foo = foo;
+ if (fi == foo) {
+ f = foo;
+ } else {
+ f = "";
+ }
+ }
+
+
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/IfFieldMovedInitialization_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/IfFieldMovedInitialization_after.groovy
new file mode 100644
index 0000000..4000fdc
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/IfFieldMovedInitialization_after.groovy
@@ -0,0 +1,22 @@
+public class A {
+ final String f;
+
+ public A(String fi, String foo) {
+ if (fi == foo) {
+ f = foo;
+ } else {
+ f = "";
+ }
+ }
+}
+
+class B extends A {
+ final String foo;
+
+ B(String fi, String foo) {
+ super(fi, foo);
+ this.foo = foo;
+ }
+
+
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/MergeInterfaces.groovy b/plugins/groovy/testdata/refactoring/pullUp/MergeInterfaces.groovy
new file mode 100644
index 0000000..5376e86
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/MergeInterfaces.groovy
@@ -0,0 +1,3 @@
+class Base implements I<String> {}
+class Te<caret>st extends Base implements I<String> {}
+interface I<T>{}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/MergeInterfaces_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/MergeInterfaces_after.groovy
new file mode 100644
index 0000000..ea7fffc
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/MergeInterfaces_after.groovy
@@ -0,0 +1,3 @@
+class Base implements I<String> {}
+class Test extends Base {}
+interface I<T>{}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitialization.groovy b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitialization.groovy
new file mode 100644
index 0000000..f884f48
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitialization.groovy
@@ -0,0 +1,17 @@
+public class A {
+}
+
+class B extends A {
+ final String <caret>f;
+ final String foo;
+
+ B(String fi, String foo) {
+ this.foo = foo;
+ f = "";
+ }
+
+ B(String foo) {
+ this.foo = foo;
+ f = "";
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitializationNoGood.groovy b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitializationNoGood.groovy
new file mode 100644
index 0000000..25117fc
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitializationNoGood.groovy
@@ -0,0 +1,21 @@
+public class A {
+}
+
+class B extends A {
+ final String <caret>f;
+ final String foo;
+
+ B(String fi, String foo) {
+ this.foo = foo;
+ if (fi == this.foo) {
+ f = foo;
+ } else {
+ f = "";
+ }
+ }
+
+ B(String f) {
+ this.f = f;
+ foo = "";
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitializationNoGood_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitializationNoGood_after.groovy
new file mode 100644
index 0000000..b66ba0b
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitializationNoGood_after.groovy
@@ -0,0 +1,21 @@
+public class A {
+ final String f;
+}
+
+class B extends A {
+ final String foo;
+
+ B(String fi, String foo) {
+ this.foo = foo;
+ if (fi == this.foo) {
+ f = foo;
+ } else {
+ f = "";
+ }
+ }
+
+ B(String f) {
+ this.f = f;
+ foo = "";
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitialization_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitialization_after.groovy
new file mode 100644
index 0000000..7c19de1
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/MultipleConstructorsFieldInitialization_after.groovy
@@ -0,0 +1,21 @@
+public class A {
+ final String f;
+
+ public A() {
+ f = "";
+ }
+}
+
+class B extends A {
+ final String foo;
+
+ B(String fi, String foo) {
+ super();
+ this.foo = foo;
+ }
+
+ B(String foo) {
+ super();
+ this.foo = foo;
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PreserveOverride.groovy b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverride.groovy
new file mode 100644
index 0000000..84f2f18
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverride.groovy
@@ -0,0 +1,12 @@
+abstract class Bazz {
+ public abstract void foo();
+}
+
+abstract class Foo extends Bazz {}
+
+class Bar extends Foo {
+ @Override
+ public void f<caret>oo() {
+ }
+}
+
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PreserveOverrideInPulledMethod.groovy b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverrideInPulledMethod.groovy
new file mode 100644
index 0000000..61e9da2
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverrideInPulledMethod.groovy
@@ -0,0 +1,12 @@
+public class Test {
+ abstract class Base extends IntImpl {
+ @Override
+ public abstract String<caret> foo();
+ }
+
+ class IntImpl extends Int {}
+
+ class Int {
+ public abstract String foo();
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PreserveOverrideInPulledMethod_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverrideInPulledMethod_after.groovy
new file mode 100644
index 0000000..206a5b4
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverrideInPulledMethod_after.groovy
@@ -0,0 +1,13 @@
+public class Test {
+ abstract class Base extends IntImpl {
+ }
+
+ abstract class IntImpl extends Int {
+ @Override
+ public abstract String foo()
+ }
+
+ class Int {
+ public abstract String foo();
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PreserveOverride_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverride_after.groovy
new file mode 100644
index 0000000..ea553c1
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PreserveOverride_after.groovy
@@ -0,0 +1,13 @@
+abstract class Bazz {
+ public abstract void foo();
+}
+
+abstract class Foo extends Bazz {
+ @Override
+ public void foo() {
+ }
+}
+
+class Bar extends Foo {
+}
+
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PullUpAndMakeAbstract.groovy b/plugins/groovy/testdata/refactoring/pullUp/PullUpAndMakeAbstract.groovy
new file mode 100644
index 0000000..111cfbe
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PullUpAndMakeAbstract.groovy
@@ -0,0 +1,11 @@
+public class A2 {
+}
+
+class B2 extends A2 {
+ public void <caret>a() {
+ b();
+ }
+
+ private void b() {
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PullUpAndMakeAbstract_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/PullUpAndMakeAbstract_after.groovy
new file mode 100644
index 0000000..312788c
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PullUpAndMakeAbstract_after.groovy
@@ -0,0 +1,14 @@
+public abstract class A2 {
+ public void a() {
+ b();
+ }
+
+ protected abstract void b()
+}
+
+class B2 extends A2 {
+
+ @Override
+ protected void b() {
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PullUpInheritedStaticClasses.groovy b/plugins/groovy/testdata/refactoring/pullUp/PullUpInheritedStaticClasses.groovy
new file mode 100644
index 0000000..e0faaba
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PullUpInheritedStaticClasses.groovy
@@ -0,0 +1,8 @@
+public class A extends AA {
+ <caret>
+ static class C extends D {}
+ static class D extends B {}
+ static class B {}
+}
+
+class AA {}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PullUpInheritedStaticClasses_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/PullUpInheritedStaticClasses_after.groovy
new file mode 100644
index 0000000..cc948e7
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PullUpInheritedStaticClasses_after.groovy
@@ -0,0 +1,10 @@
+public class A extends AA {
+
+ static class B {}
+}
+
+class AA {
+ static class C extends D {}
+
+ static class D extends A.B {}
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PullUpPrivateInnerClassWithPrivateConstructor.groovy b/plugins/groovy/testdata/refactoring/pullUp/PullUpPrivateInnerClassWithPrivateConstructor.groovy
new file mode 100644
index 0000000..a5fbc56
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PullUpPrivateInnerClassWithPrivateConstructor.groovy
@@ -0,0 +1,15 @@
+public class B extends A {
+ private void f(){
+ new C();
+ }
+ <caret>
+ private static class C{
+ private C(){
+
+ }
+ }
+}
+
+//A.java
+class A {
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/PullUpPrivateInnerClassWithPrivateConstructor_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/PullUpPrivateInnerClassWithPrivateConstructor_after.groovy
new file mode 100644
index 0000000..a1cc2b8
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/PullUpPrivateInnerClassWithPrivateConstructor_after.groovy
@@ -0,0 +1,15 @@
+public class B extends A {
+ private void f(){
+ new C();
+ }
+
+}
+
+//A.java
+class A {
+ protected static class C{
+ protected C(){
+
+ }
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/QualifiedReference.groovy b/plugins/groovy/testdata/refactoring/pullUp/QualifiedReference.groovy
new file mode 100644
index 0000000..cf557dd
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/QualifiedReference.groovy
@@ -0,0 +1,13 @@
+class X {}
+
+class <caret>Y extends X {
+ private static int x = 0;
+
+ public static int getX() {
+ return x;
+ }
+
+ public static void setX(int x) {
+ Y.x = x;
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/QualifiedReference_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/QualifiedReference_after.groovy
new file mode 100644
index 0000000..2ee9526
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/QualifiedReference_after.groovy
@@ -0,0 +1,16 @@
+class X {
+ private static int x = 0
+
+ public static int getX() {
+ return x;
+ }
+
+ public static void setX(int x) {
+ X.x = x;
+ }
+}
+
+class Y extends X {
+
+
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/QualifiedSuper.groovy b/plugins/groovy/testdata/refactoring/pullUp/QualifiedSuper.groovy
new file mode 100644
index 0000000..6c58661
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/QualifiedSuper.groovy
@@ -0,0 +1,12 @@
+class <caret>QualifiedSuper extends Base {
+ class Inner {
+ void goo() {
+ QualifiedSuper.super.toString();
+ }
+ }
+}
+
+class Base {
+
+
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/QualifiedSuper_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/QualifiedSuper_after.groovy
new file mode 100644
index 0000000..08e7250
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/QualifiedSuper_after.groovy
@@ -0,0 +1,12 @@
+class QualifiedSuper extends Base {
+}
+
+class Base {
+
+
+ class Inner {
+ void goo() {
+ Base.this.toString();
+ }
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/QualifiedThis.groovy b/plugins/groovy/testdata/refactoring/pullUp/QualifiedThis.groovy
new file mode 100644
index 0000000..ae04288
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/QualifiedThis.groovy
@@ -0,0 +1,15 @@
+class Base {
+ void foo() {
+ }
+}
+
+public class <caret>QualifiedThis extends Base {
+ void foo() {
+ }
+
+ class Inner {
+ void bar() {
+ QualifiedThis.this.foo();
+ }
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/QualifiedThis_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/QualifiedThis_after.groovy
new file mode 100644
index 0000000..c097c66b
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/QualifiedThis_after.groovy
@@ -0,0 +1,16 @@
+class Base {
+ void foo() {
+ }
+
+ class Inner {
+ void bar() {
+ Base.this.foo();
+ }
+ }
+}
+
+public class QualifiedThis extends Base {
+ void foo() {
+ }
+
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/RemoveOverride.groovy b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverride.groovy
new file mode 100644
index 0000000..8c3d05f
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverride.groovy
@@ -0,0 +1,16 @@
+public class Test {
+ class Impl extends Base {
+ @Override
+ public String get() {
+ return "239";
+ }
+ }
+
+ abstract class Base implements Int {
+ public abstract String <caret>get();
+
+ }
+
+ interface Int {
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/RemoveOverrideFromPulledMethod.groovy b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverrideFromPulledMethod.groovy
new file mode 100644
index 0000000..f298edc
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverrideFromPulledMethod.groovy
@@ -0,0 +1,9 @@
+public class Test {
+ abstract class Base extends Int {
+ @Override
+ public abstract String<caret> foo();
+ }
+
+ class Int {
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/RemoveOverrideFromPulledMethod_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverrideFromPulledMethod_after.groovy
new file mode 100644
index 0000000..79ff76e
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverrideFromPulledMethod_after.groovy
@@ -0,0 +1,8 @@
+public class Test {
+ abstract class Base extends Int {
+ }
+
+ abstract class Int {
+ public abstract String foo()
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/RemoveOverride_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverride_after.groovy
new file mode 100644
index 0000000..94aef6d
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/RemoveOverride_after.groovy
@@ -0,0 +1,15 @@
+public class Test {
+ class Impl extends Base {
+ public String get() {
+ return "239";
+ }
+ }
+
+ abstract class Base implements Int {
+
+ }
+
+ interface Int {
+ String get();
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/ReplaceDuplicatesInInheritors.groovy b/plugins/groovy/testdata/refactoring/pullUp/ReplaceDuplicatesInInheritors.groovy
new file mode 100644
index 0000000..0f8c6a1
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/ReplaceDuplicatesInInheritors.groovy
@@ -0,0 +1,18 @@
+class A {}
+class AImpl1 extends A{
+ void f<caret>oo() {
+ System.out.println("hello");
+ System.out.println("hello");
+ System.out.println("hello");
+ System.out.println("hello");
+ }
+}
+
+class AImpl2 extends A {
+ void bar() {
+ System.out.println("hello");
+ System.out.println("hello");
+ System.out.println("hello");
+ System.out.println("hello");
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/ReplaceDuplicatesInInheritors_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/ReplaceDuplicatesInInheritors_after.groovy
new file mode 100644
index 0000000..47b655c
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/ReplaceDuplicatesInInheritors_after.groovy
@@ -0,0 +1,16 @@
+class A {
+ void foo() {
+ System.out.println("hello");
+ System.out.println("hello");
+ System.out.println("hello");
+ System.out.println("hello");
+ }
+}
+class AImpl1 extends A{
+}
+
+class AImpl2 extends A {
+ void bar() {
+ foo();
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TryCatchFieldInitializer.groovy b/plugins/groovy/testdata/refactoring/pullUp/TryCatchFieldInitializer.groovy
new file mode 100644
index 0000000..64675e4
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TryCatchFieldInitializer.groovy
@@ -0,0 +1,19 @@
+public class Sup {
+
+}
+
+class ExtractSuperClass extends Sup {
+
+ private final String <caret>field;
+
+ public ExtractSuperClass() {
+
+
+ try {
+ field = (String)"text";
+ }
+ catch (RuntimeException e) {
+ throw new RuntimeException();
+ }
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TryCatchFieldInitializer_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/TryCatchFieldInitializer_after.groovy
new file mode 100644
index 0000000..600247f
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TryCatchFieldInitializer_after.groovy
@@ -0,0 +1,22 @@
+public class Sup {
+
+ protected final String field
+
+ public Sup() {
+ try {
+ field = (String)"text";
+ }
+ catch (RuntimeException e) {
+ throw new RuntimeException();
+ }
+ }
+}
+
+class ExtractSuperClass extends Sup {
+
+ public ExtractSuperClass() {
+ super();
+
+
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeArgument.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeArgument.groovy
new file mode 100644
index 0000000..21140c8
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeArgument.groovy
@@ -0,0 +1,5 @@
+public class Parent<S> {}
+
+class Child extends Parent<String> {
+ String <caret>f;
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeArgument_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeArgument_after.groovy
new file mode 100644
index 0000000..3eb9010
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeArgument_after.groovy
@@ -0,0 +1,6 @@
+public class Parent<S> {
+ String f
+}
+
+class Child extends Parent<String> {
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeParamErasure.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeParamErasure.groovy
new file mode 100644
index 0000000..0dbc24f
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeParamErasure.groovy
@@ -0,0 +1,5 @@
+public class Parent {}
+
+class Child<T> extends Parent {
+ T <caret>f;
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeParamErasure_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeParamErasure_after.groovy
new file mode 100644
index 0000000..ab94d54
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeParamErasure_after.groovy
@@ -0,0 +1,6 @@
+public class Parent {
+ Object f
+}
+
+class Child<T> extends Parent {
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeParamSubst.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeParamSubst.groovy
new file mode 100644
index 0000000..f2ad0c7
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeParamSubst.groovy
@@ -0,0 +1,5 @@
+public class Parent<S> {}
+
+class Child<T> extends Parent<T> {
+ T <caret>f;
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeParamSubst_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeParamSubst_after.groovy
new file mode 100644
index 0000000..7034451
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeParamSubst_after.groovy
@@ -0,0 +1,6 @@
+public class Parent<S> {
+ S f
+}
+
+class Child<T> extends Parent<T> {
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeParamsConflictingNames.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeParamsConflictingNames.groovy
new file mode 100644
index 0000000..b0d7366
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeParamsConflictingNames.groovy
@@ -0,0 +1,7 @@
+interface Bar<T> { }
+
+interface Base<T> { }
+
+class Foo<T,U> implements Base<U> {
+ void fo<caret>o(Bar<U> bar) { }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/TypeParamsConflictingNames_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/TypeParamsConflictingNames_after.groovy
new file mode 100644
index 0000000..97b65ab
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/TypeParamsConflictingNames_after.groovy
@@ -0,0 +1,10 @@
+interface Bar<T> { }
+
+interface Base<T> {
+ void foo(Bar<T> bar)
+}
+
+class Foo<T,U> implements Base<U> {
+ @Override
+ void foo(Bar<U> bar) { }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/UpdateStaticRefs.groovy b/plugins/groovy/testdata/refactoring/pullUp/UpdateStaticRefs.groovy
new file mode 100644
index 0000000..7ad6fb6
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/UpdateStaticRefs.groovy
@@ -0,0 +1,10 @@
+class Foo {}
+class FooImpl extends Foo {
+ public static void foo(){}
+ <caret>
+}
+class U {
+ public static void main(String[] args) {
+ FooImpl.foo();
+ }
+}
diff --git a/plugins/groovy/testdata/refactoring/pullUp/UpdateStaticRefs_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/UpdateStaticRefs_after.groovy
new file mode 100644
index 0000000..dc797f7
--- /dev/null
+++ b/plugins/groovy/testdata/refactoring/pullUp/UpdateStaticRefs_after.groovy
@@ -0,0 +1,11 @@
+class Foo {
+ public static void foo(){}
+}
+class FooImpl extends Foo {
+
+}
+class U {
+ public static void main(String[] args) {
+ Foo.foo();
+ }
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotationProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotationProvider.java
index eaad2b9..5592151 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotationProvider.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotationProvider.java
@@ -29,6 +29,7 @@
import org.zmlx.hg4idea.command.HgLogCommand;
import org.zmlx.hg4idea.command.HgWorkingCopyRevisionsCommand;
import org.zmlx.hg4idea.execution.HgCommandException;
+import org.zmlx.hg4idea.util.HgUtil;
import java.util.List;
@@ -52,10 +53,12 @@
throw new VcsException("vcs root is null for " + file);
}
final HgFile hgFile = new HgFile(vcsRoot, VfsUtilCore.virtualToIoFile(file));
- final List<HgAnnotationLine> annotationResult = (new HgAnnotateCommand(myProject)).execute(hgFile, revision);
+ HgFile fileToAnnotate = revision instanceof HgFileRevision ? HgUtil
+ .getFileNameInTargetRevision(myProject, ((HgFileRevision)revision).getRevisionNumber(), hgFile) : hgFile;
+ final List<HgAnnotationLine> annotationResult = (new HgAnnotateCommand(myProject)).execute(fileToAnnotate, revision);
final List<HgFileRevision> logResult;
try {
- logResult = (new HgLogCommand(myProject)).execute(hgFile, DEFAULT_LIMIT, false);
+ logResult = (new HgLogCommand(myProject)).execute(fileToAnnotate, DEFAULT_LIMIT, false);
}
catch (HgCommandException e) {
throw new VcsException("Can not annotate, " + HgVcsMessages.message("hg4idea.error.log.command.execution"), e);
@@ -69,5 +72,4 @@
public boolean isAnnotationValid(VcsFileRevision rev) {
return true;
}
-
}
diff --git a/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/JpsJavaFxApplicationArtifactType.java b/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/JpsJavaFxApplicationArtifactType.java
index 3d1df6e..fbad37a 100644
--- a/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/JpsJavaFxApplicationArtifactType.java
+++ b/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/JpsJavaFxApplicationArtifactType.java
@@ -1,11 +1,12 @@
package org.jetbrains.plugins.javaFX;
import org.jetbrains.jps.model.artifact.JpsArtifactType;
+import org.jetbrains.jps.model.ex.JpsElementTypeBase;
/**
* User: anna
* Date: 3/13/13
*/
-public class JpsJavaFxApplicationArtifactType extends JpsArtifactType<JpsJavaFxArtifactProperties> {
+public class JpsJavaFxApplicationArtifactType extends JpsElementTypeBase<JpsJavaFxArtifactProperties> implements JpsArtifactType<JpsJavaFxArtifactProperties> {
public static final JpsJavaFxApplicationArtifactType INSTANCE = new JpsJavaFxApplicationArtifactType();
}
diff --git a/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/preloader/JpsJavaFxPreloaderArtifactType.java b/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/preloader/JpsJavaFxPreloaderArtifactType.java
index ab0440dc9..d05fed5 100644
--- a/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/preloader/JpsJavaFxPreloaderArtifactType.java
+++ b/plugins/javaFX/javaFX-jps-plugin/src/org/jetbrains/plugins/javaFX/preloader/JpsJavaFxPreloaderArtifactType.java
@@ -16,11 +16,12 @@
package org.jetbrains.plugins.javaFX.preloader;
import org.jetbrains.jps.model.artifact.JpsArtifactType;
+import org.jetbrains.jps.model.ex.JpsElementTypeBase;
/**
* User: anna
* Date: 3/13/13
*/
-public class JpsJavaFxPreloaderArtifactType extends JpsArtifactType<JpsJavaFxPreloaderArtifactProperties> {
+public class JpsJavaFxPreloaderArtifactType extends JpsElementTypeBase<JpsJavaFxPreloaderArtifactProperties> implements JpsArtifactType<JpsJavaFxPreloaderArtifactProperties> {
public static final JpsJavaFxPreloaderArtifactType INSTANCE = new JpsJavaFxPreloaderArtifactType();
}
diff --git a/plugins/javaFX/javaFX.iml b/plugins/javaFX/javaFX.iml
index 3513259..3abff64 100644
--- a/plugins/javaFX/javaFX.iml
+++ b/plugins/javaFX/javaFX.iml
@@ -22,6 +22,7 @@
<orderEntry type="module" module-name="compiler-impl" />
<orderEntry type="module" module-name="common-javaFX-plugin" />
<orderEntry type="module" module-name="manifest" />
+ <orderEntry type="module" module-name="idea-ui" />
</component>
</module>
diff --git a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml
index df18ddf..af48a12 100644
--- a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml
+++ b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml
@@ -50,6 +50,9 @@
<renamePsiElementProcessor implementation="org.jetbrains.plugins.javaFX.JavaFxRenameAttributeProcessor" order="before xmlAttribute"/>
<completion.contributor implementationClass="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxCompletionContributor" language="XML" order="before xmlNonFirst"/>
<manifest.parser.provider implementation="org.jetbrains.plugins.javaFX.manifest.JavaFxManifestHeaderParsers"/>
+ <!--
+ <projectWizard.projectCategory implementation="org.jetbrains.plugins.javaFX.JavaFxProjectType"/>
+ -->
</extensions>
<actions>
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxProjectType.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxProjectType.java
new file mode 100644
index 0000000..653c573
--- /dev/null
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxProjectType.java
@@ -0,0 +1,19 @@
+package org.jetbrains.plugins.javaFX;
+
+import com.intellij.ide.projectWizard.TemplateBasedProjectType;
+
+/**
+ * @author Dmitry Avdeev
+ * Date: 20.09.13
+ */
+public class JavaFxProjectType extends TemplateBasedProjectType {
+
+ public JavaFxProjectType() {
+ super("/resources/projectTemplates/Java/JavaFX Application.zip");
+ }
+
+ @Override
+ public String getId() {
+ return "JavaFX";
+ }
+}
diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java b/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java
index 21828ec..dcbff35 100644
--- a/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java
+++ b/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java
@@ -33,6 +33,11 @@
return "JUnit3";
}
+ @Override
+ public char getMnemonic() {
+ return '3';
+ }
+
@NotNull
@Override
public Icon getIcon() {
diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnit4Framework.java b/plugins/junit/src/com/intellij/execution/junit/JUnit4Framework.java
index 3f724c4..bcb3678 100644
--- a/plugins/junit/src/com/intellij/execution/junit/JUnit4Framework.java
+++ b/plugins/junit/src/com/intellij/execution/junit/JUnit4Framework.java
@@ -146,6 +146,11 @@
}
@Override
+ public char getMnemonic() {
+ return '4';
+ }
+
+ @Override
public boolean isParameterized(PsiClass clazz) {
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(clazz, JUnitUtil.RUN_WITH);
if (annotation != null) {
diff --git a/plugins/junit/src/com/intellij/execution/junit/TestClassFilter.java b/plugins/junit/src/com/intellij/execution/junit/TestClassFilter.java
index 84b5e3b..cc58990 100644
--- a/plugins/junit/src/com/intellij/execution/junit/TestClassFilter.java
+++ b/plugins/junit/src/com/intellij/execution/junit/TestClassFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,7 +27,6 @@
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.util.PsiUtilBase;
import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.NotNull;
@@ -55,7 +54,8 @@
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
- return ConfigurationUtil.PUBLIC_INSTANTIATABLE_CLASS.value(aClass) &&
+ return aClass.getQualifiedName() != null &&
+ ConfigurationUtil.PUBLIC_INSTANTIATABLE_CLASS.value(aClass) &&
(aClass.isInheritor(myBase, true) || JUnitUtil.isTestClass(aClass))
&& !CompilerConfiguration.getInstance(getProject()).isExcludedFromCompilation(PsiUtilCore.getVirtualFile(aClass));
}
diff --git a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenArtifactInfo.java b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenArtifactInfo.java
index 9344d31..d04fb9e 100644
--- a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenArtifactInfo.java
+++ b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenArtifactInfo.java
@@ -95,6 +95,7 @@
MavenId.append(builder, myPackaging);
if (!StringUtil.isEmptyOrSpaces(myClassifier)) MavenId.append(builder, myClassifier);
MavenId.append(builder, myVersion);
+ MavenId.append(builder, myRepositoryId);
return builder.toString();
}
diff --git a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenRepositoryInfo.java b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenRepositoryInfo.java
index dd9fd21..2e3a566 100644
--- a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenRepositoryInfo.java
+++ b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenRepositoryInfo.java
@@ -39,4 +39,15 @@
public String getUrl() {
return myUrl;
}
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+
+ MavenId.append(builder, myId);
+ MavenId.append(builder, myName);
+ MavenId.append(builder, myUrl);
+
+ return builder.toString();
+ }
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java
index 69af10c..179127d 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java
@@ -232,6 +232,7 @@
public static <T extends MavenDomElement> T getMavenDomModel(@NotNull Project project,
@NotNull VirtualFile file,
@NotNull Class<T> clazz) {
+ if (!file.isValid()) return null;
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
if (psiFile == null) return null;
return getMavenDomModel(psiFile, clazz);
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicateDependenciesInspection.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicateDependenciesInspection.java
index 134ac62..cd37e99 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicateDependenciesInspection.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicateDependenciesInspection.java
@@ -22,12 +22,12 @@
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.Processor;
+import com.intellij.util.containers.MultiMap;
+import com.intellij.util.containers.MultiMapBasedOnSet;
import com.intellij.util.containers.hash.HashSet;
import com.intellij.util.xml.DomFileElement;
import com.intellij.util.xml.highlighting.BasicDomElementsInspection;
import com.intellij.util.xml.highlighting.DomElementAnnotationHolder;
-import gnu.trove.THashMap;
-import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.DependencyConflictId;
import org.jetbrains.idea.maven.dom.MavenDomBundle;
@@ -56,13 +56,13 @@
private static void checkDependencies(@NotNull MavenDomProjectModel projectModel,
@NotNull DomElementAnnotationHolder holder) {
- final Map<DependencyConflictId, Set<MavenDomDependency>> allDuplicates = getDuplicateDependenciesMap(projectModel);
+ MultiMap<DependencyConflictId, MavenDomDependency> allDuplicates = getDuplicateDependenciesMap(projectModel);
for (MavenDomDependency dependency : projectModel.getDependencies().getDependencies()) {
DependencyConflictId id = DependencyConflictId.create(dependency);
if (id != null) {
- Set<MavenDomDependency> dependencies = allDuplicates.get(id);
- if (dependencies != null && dependencies.size() > 1) {
+ Collection<MavenDomDependency> dependencies = allDuplicates.get(id);
+ if (dependencies.size() > 1) {
List<MavenDomDependency> duplicatedDependencies = new ArrayList<MavenDomDependency>();
@@ -115,22 +115,12 @@
}
private static String createLinkText(@NotNull MavenDomProjectModel model, @NotNull MavenDomDependency dependency) {
- StringBuilder sb = new StringBuilder();
-
XmlTag tag = dependency.getXmlTag();
if (tag == null) return getProjectName(model);
VirtualFile file = tag.getContainingFile().getVirtualFile();
if (file == null) return getProjectName(model);
- sb.append("<a href ='#navigation/");
- sb.append(file.getPath());
- sb.append(":");
- sb.append(tag.getTextRange().getStartOffset());
- sb.append("'>");
- sb.append(getProjectName(model));
- sb.append("</a>");
-
- return sb.toString();
+ return "<a href ='#navigation/" + file.getPath() + ":" + tag.getTextRange().getStartOffset() + "'>" + getProjectName(model) + "</a>";
}
@NotNull
@@ -151,8 +141,8 @@
}
@NotNull
- private static Map<DependencyConflictId, Set<MavenDomDependency>> getDuplicateDependenciesMap(MavenDomProjectModel projectModel) {
- final Map<DependencyConflictId, Set<MavenDomDependency>> allDependencies = new HashMap<DependencyConflictId, Set<MavenDomDependency>>();
+ private static MultiMap<DependencyConflictId, MavenDomDependency> getDuplicateDependenciesMap(MavenDomProjectModel projectModel) {
+ final MultiMap<DependencyConflictId, MavenDomDependency> allDependencies = new MultiMapBasedOnSet<DependencyConflictId, MavenDomDependency>();
Processor<MavenDomProjectModel> collectProcessor = new Processor<MavenDomProjectModel>() {
public boolean process(MavenDomProjectModel model) {
@@ -167,28 +157,22 @@
return allDependencies;
}
- private static void collect(Map<DependencyConflictId, Set<MavenDomDependency>> duplicates, @NotNull MavenDomDependencies dependencies) {
+ private static void collect(MultiMap<DependencyConflictId, MavenDomDependency> duplicates, @NotNull MavenDomDependencies dependencies) {
for (MavenDomDependency dependency : dependencies.getDependencies()) {
DependencyConflictId mavenId = DependencyConflictId.create(dependency);
if (mavenId == null) continue;
- Set<MavenDomDependency> set = duplicates.get(mavenId);
- if (set == null) {
- set = new THashSet<MavenDomDependency>();
- duplicates.put(mavenId, set);
- }
-
- set.add(dependency);
+ duplicates.putValue(mavenId, dependency);
}
}
private static void checkManagedDependencies(@NotNull MavenDomProjectModel projectModel,
@NotNull DomElementAnnotationHolder holder) {
- final Map<DependencyConflictId, Set<MavenDomDependency>> duplicates = new THashMap<DependencyConflictId, Set<MavenDomDependency>>();
+ MultiMap<DependencyConflictId, MavenDomDependency> duplicates = new MultiMapBasedOnSet<DependencyConflictId, MavenDomDependency>();
collect(duplicates, projectModel.getDependencyManagement().getDependencies());
- for (Map.Entry<DependencyConflictId, Set<MavenDomDependency>> entry : duplicates.entrySet()) {
- Set<MavenDomDependency> set = entry.getValue();
+ for (Map.Entry<DependencyConflictId, Collection<MavenDomDependency>> entry : duplicates.entrySet()) {
+ Collection<MavenDomDependency> set = entry.getValue();
if (set.size() <= 1) continue;
for (MavenDomDependency dependency : set) {
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicatePluginInspection.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicatePluginInspection.java
new file mode 100644
index 0000000..7e7f510
--- /dev/null
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicatePluginInspection.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.maven.dom.inspections;
+
+import com.intellij.codeHighlighting.HighlightDisplayLevel;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.containers.MultiMap;
+import com.intellij.util.containers.MultiMapBasedOnSet;
+import com.intellij.util.xml.DomFileElement;
+import com.intellij.util.xml.highlighting.BasicDomElementsInspection;
+import com.intellij.util.xml.highlighting.DomElementAnnotationHolder;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.maven.dom.MavenDomBundle;
+import org.jetbrains.idea.maven.dom.model.MavenDomPlugin;
+import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
+
+import java.util.Collection;
+import java.util.Map;
+
+public class MavenDuplicatePluginInspection extends BasicDomElementsInspection<MavenDomProjectModel> {
+ public MavenDuplicatePluginInspection() {
+ super(MavenDomProjectModel.class);
+ }
+
+ @Override
+ public void checkFileElement(DomFileElement<MavenDomProjectModel> domFileElement,
+ DomElementAnnotationHolder holder) {
+ MavenDomProjectModel projectModel = domFileElement.getRootElement();
+
+ MultiMap<Pair<String,String>, MavenDomPlugin> duplicates = new MultiMapBasedOnSet<Pair<String, String>, MavenDomPlugin>();
+
+ for (MavenDomPlugin plugin : projectModel.getBuild().getPlugins().getPlugins()) {
+ String groupId = plugin.getGroupId().getStringValue();
+ String artifactId = plugin.getArtifactId().getStringValue();
+
+ if (StringUtil.isEmptyOrSpaces(artifactId)) continue;
+
+ if ("".equals(groupId) || "org.apache.maven.plugins".equals(groupId) || "org.codehaus.mojo".equals(groupId)) {
+ groupId = null;
+ }
+
+ duplicates.putValue(Pair.create(groupId, artifactId), plugin);
+ }
+
+ for (Map.Entry<Pair<String,String>, Collection<MavenDomPlugin>> entry : duplicates.entrySet()) {
+ Collection<MavenDomPlugin> set = entry.getValue();
+ if (set.size() <= 1) continue;
+
+ for (MavenDomPlugin dependency : set) {
+ holder.createProblem(dependency, HighlightSeverity.WARNING, "Duplicated plugin declaration");
+ }
+ }
+ }
+
+ @NotNull
+ public String getGroupDisplayName() {
+ return MavenDomBundle.message("inspection.group");
+ }
+
+ @NotNull
+ public String getDisplayName() {
+ return MavenDomBundle.message("inspection.duplicate.plugin.declaration");
+ }
+
+ @NotNull
+ public String getShortName() {
+ return "MavenDuplicatePluginInspection";
+ }
+
+ @NotNull
+ public HighlightDisplayLevel getDefaultLevel() {
+ return HighlightDisplayLevel.WARNING;
+ }
+}
\ No newline at end of file
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExternalParameters.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExternalParameters.java
index 2aa3515..a8f4606 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExternalParameters.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExternalParameters.java
@@ -69,7 +69,7 @@
private static final Logger LOG = Logger.getInstance(MavenExternalParameters.class);
public static final String MAVEN_LAUNCHER_CLASS = "org.codehaus.classworlds.Launcher";
- @NonNls private static final String JAVA_HOME = "JAVA_HOME";
+
@NonNls private static final String MAVEN_OPTS = "MAVEN_OPTS";
@Deprecated // Use createJavaParameters(Project,MavenRunnerParameters, MavenGeneralSettings,MavenRunnerSettings,MavenRunConfiguration)
@@ -295,7 +295,7 @@
}
if (name.equals(MavenRunnerSettings.USE_JAVA_HOME)) {
- final String javaHome = System.getenv(JAVA_HOME);
+ final String javaHome = System.getenv("JAVA_HOME");
if (StringUtil.isEmptyOrSpaces(javaHome)) {
throw new ExecutionException(RunnerBundle.message("maven.java.home.undefined"));
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenJdkComboBox.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenJdkComboBox.java
new file mode 100644
index 0000000..f982ef9
--- /dev/null
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenJdkComboBox.java
@@ -0,0 +1,102 @@
+package org.jetbrains.idea.maven.execution;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.ProjectJdkTable;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
+import com.intellij.openapi.roots.ProjectRootManager;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.maven.utils.ComboBoxUtil;
+
+import javax.swing.*;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author Sergey Evdokimov
+ */
+public class MavenJdkComboBox extends JComboBox {
+
+ private static final int MAX_PATH_LENGTH = 50;
+
+ @Nullable
+ private final Project myProject;
+
+ public MavenJdkComboBox(@Nullable Project project) {
+ myProject = project;
+ }
+
+ @Nullable
+ public Project getProject() {
+ return myProject;
+ }
+
+ public void refreshData(@Nullable String selectedValue) {
+ Map<String, String> jdkMap = collectJdkNamesAndDescriptions();
+ if (selectedValue != null && !jdkMap.containsKey(selectedValue)) {
+ assert selectedValue.length() > 0;
+ jdkMap.put(selectedValue, selectedValue);
+ }
+
+ removeAllItems();
+
+ for (Map.Entry<String, String> entry : jdkMap.entrySet()) {
+ ComboBoxUtil.addToModel((DefaultComboBoxModel)getModel(), entry.getKey(), entry.getValue());
+ }
+
+ ComboBoxUtil.select((DefaultComboBoxModel)getModel(), selectedValue);
+ }
+
+ public String getSelectedValue() {
+ return ComboBoxUtil.getSelectedString((DefaultComboBoxModel)getModel());
+ }
+
+ private Map<String, String> collectJdkNamesAndDescriptions() {
+ Map<String, String> result = new LinkedHashMap<String, String>();
+
+ for (Sdk projectJdk : ProjectJdkTable.getInstance().getSdksOfType(JavaSdk.getInstance())) {
+ String name = projectJdk.getName();
+
+ String label;
+
+ String path = projectJdk.getHomePath();
+ if (path == null) {
+ label = name;
+ }
+ else {
+ label = String.format("<html>%s <font color=gray>(%s)</font></html>", name, truncateLongPath(path));
+ }
+
+ result.put(name, label);
+ }
+
+ String internalJdkPath = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk().getHomePath();
+ assert internalJdkPath != null;
+ result.put(MavenRunnerSettings.USE_INTERNAL_JAVA, RunnerBundle.message("maven.java.internal", truncateLongPath(internalJdkPath)));
+
+ if (myProject != null) {
+ String projectJdk = ProjectRootManager.getInstance(myProject).getProjectSdkName();
+ String projectJdkTitle = String.format("<html>Use Project JDK <font color=gray>(%s)</font></html>", projectJdk == null ? "not defined yet" : projectJdk);
+ result.put(MavenRunnerSettings.USE_PROJECT_JDK, projectJdkTitle);
+ }
+
+ String javaHomePath = System.getenv("JAVA_HOME");
+ String javaHomeLabel = RunnerBundle.message("maven.java.home.env", javaHomePath == null ? "not defined yet" : truncateLongPath(javaHomePath));
+
+ result.put(MavenRunnerSettings.USE_JAVA_HOME, javaHomeLabel);
+
+ return result;
+ }
+
+ @NotNull
+ private static String truncateLongPath(@NotNull String path) {
+ if (path.length() > MAX_PATH_LENGTH) {
+ return path.substring(0, MAX_PATH_LENGTH / 2) + "..." + path.substring(path.length() - MAX_PATH_LENGTH / 2 - 3);
+ }
+
+ return path;
+ }
+
+}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunnerPanel.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunnerPanel.java
index 61a45a4..14a0197 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunnerPanel.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunnerPanel.java
@@ -19,16 +19,11 @@
import com.intellij.execution.configuration.EnvironmentVariablesComponent;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.JavaSdk;
-import com.intellij.openapi.projectRoots.ProjectJdkTable;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.RawCommandLineEditor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
-import org.jetbrains.idea.maven.utils.ComboBoxUtil;
import javax.swing.*;
import java.awt.*;
@@ -43,8 +38,8 @@
private JCheckBox myRunInBackgroundCheckbox;
private RawCommandLineEditor myVMParametersEditor;
private EnvironmentVariablesComponent myEnvVariablesComponent;
- private JComboBox myJdkCombo;
- private final DefaultComboBoxModel myJdkComboModel = new DefaultComboBoxModel();
+ private MavenJdkComboBox myJdkCombo;
+
private JCheckBox mySkipTestsCheckBox;
private MavenPropertiesPanel myPropertiesPanel;
@@ -93,7 +88,7 @@
JLabel jdkLabel = new JLabel("JRE:");
jdkLabel.setDisplayedMnemonic('j');
- jdkLabel.setLabelFor(myJdkCombo = new JComboBox());
+ jdkLabel.setLabelFor(myJdkCombo = new MavenJdkComboBox(myProject));
c.gridx = 0;
c.gridy++;
c.weightx = 0;
@@ -153,17 +148,7 @@
myVMParametersEditor.setText(data.getVmOptions());
mySkipTestsCheckBox.setSelected(data.isSkipTests());
- Map<String, String> jdkMap = collectJdkNamesAndDescriptions();
- if (!jdkMap.containsKey(data.getJreName())) {
- jdkMap.put(data.getJreName(), data.getJreName());
- }
-
- myJdkComboModel.removeAllElements();
- for (Map.Entry<String, String> entry : jdkMap.entrySet()) {
- ComboBoxUtil.addToModel(myJdkComboModel, entry.getKey(), entry.getValue());
- }
- myJdkCombo.setModel(myJdkComboModel);
- ComboBoxUtil.select(myJdkComboModel, data.getJreName());
+ myJdkCombo.refreshData(data.getJreName());
myPropertiesPanel.setDataFromMap(data.getMavenProperties());
@@ -171,37 +156,12 @@
myEnvVariablesComponent.setPassParentEnvs(data.isPassParentEnv());
}
- private Map<String, String> collectJdkNamesAndDescriptions() {
- Map<String, String> result = new LinkedHashMap<String, String>();
-
- for (Sdk projectJdk : ProjectJdkTable.getInstance().getSdksOfType(JavaSdk.getInstance())) {
- String name = projectJdk.getName();
- result.put(name, name);
- }
-
- result.put(MavenRunnerSettings.USE_INTERNAL_JAVA, RunnerBundle.message("maven.java.internal"));
-
- String projectJdkTitle;
-
- String projectJdk = ProjectRootManager.getInstance(myProject).getProjectSdkName();
- if (projectJdk == null) {
- projectJdkTitle = "Use Project JDK (not defined yet)";
- }
- else {
- projectJdkTitle = "Use Project JDK (" + projectJdk + ')';
- }
-
- result.put(MavenRunnerSettings.USE_PROJECT_JDK, projectJdkTitle);
- result.put(MavenRunnerSettings.USE_JAVA_HOME, RunnerBundle.message("maven.java.home.env"));
-
- return result;
- }
protected void setData(MavenRunnerSettings data) {
data.setRunMavenInBackground(myRunInBackgroundCheckbox.isSelected());
data.setVmOptions(myVMParametersEditor.getText().trim());
data.setSkipTests(mySkipTestsCheckBox.isSelected());
- data.setJreName(ComboBoxUtil.getSelectedString(myJdkComboModel));
+ data.setJreName(myJdkCombo.getSelectedValue());
data.setMavenProperties(myPropertiesPanel.getDataAsMap());
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/GroovyImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/GroovyImporter.java
index 2f35f62..d4c4628 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/GroovyImporter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/GroovyImporter.java
@@ -1,12 +1,15 @@
package org.jetbrains.idea.maven.importing;
import com.intellij.openapi.module.Module;
+import com.intellij.util.PairConsumer;
import org.jdom.Element;
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectChanges;
import org.jetbrains.idea.maven.project.MavenProjectsProcessorTask;
import org.jetbrains.idea.maven.project.MavenProjectsTree;
import org.jetbrains.idea.maven.utils.MavenJDOMUtil;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import java.util.List;
import java.util.Map;
@@ -33,23 +36,22 @@
}
@Override
- public void collectSourceFolders(MavenProject mavenProject, List<String> result) {
- collectSourceOrTestFolders(mavenProject, "compile", "src/main/groovy", result);
+ public void collectSourceRoots(MavenProject mavenProject, PairConsumer<String, JpsModuleSourceRootType<?>> result) {
+ collectSourceOrTestFolders(mavenProject, "compile", "src/main/groovy", JavaSourceRootType.SOURCE, result);
+ collectSourceOrTestFolders(mavenProject, "testCompile", "src/test/groovy", JavaSourceRootType.TEST_SOURCE, result);
}
- @Override
- public void collectTestFolders(MavenProject mavenProject, List<String> result) {
- collectSourceOrTestFolders(mavenProject, "testCompile", "src/test/groovy", result);
- }
-
- private void collectSourceOrTestFolders(MavenProject mavenProject, String goal, String defaultDir, List<String> result) {
+ private void collectSourceOrTestFolders(MavenProject mavenProject, String goal, String defaultDir, JavaSourceRootType type,
+ PairConsumer<String, JpsModuleSourceRootType<?>> result) {
Element sourcesElement = getGoalConfig(mavenProject, goal);
List<String> dirs = MavenJDOMUtil.findChildrenValuesByPath(sourcesElement, "sources", "fileset.directory");
if (dirs.isEmpty()) {
- result.add(mavenProject.getDirectory() + "/" + defaultDir);
+ result.consume(mavenProject.getDirectory() + "/" + defaultDir, type);
return;
}
- result.addAll(dirs);
+ for (String dir : dirs) {
+ result.consume(dir, type);
+ }
}
@Override
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java
index 0f5441e..be9ebda 100755
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java
@@ -24,16 +24,20 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.impl.ModifiableModelCommitter;
-import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.PairConsumer;
+import com.intellij.util.containers.LinkedMultiMap;
+import com.intellij.util.containers.MultiMap;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.model.MavenResource;
import org.jetbrains.idea.maven.project.MavenImportingSettings;
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
-import org.jetbrains.idea.maven.utils.Path;
+import org.jetbrains.jps.model.java.JavaResourceRootType;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import java.io.File;
import java.util.ArrayList;
@@ -102,70 +106,60 @@
}
private void configSourceFolders() {
- List<String> sourceFolders = new ArrayList<String>();
- List<String> testFolders = new ArrayList<String>();
+ final MultiMap<JpsModuleSourceRootType<?>, String> roots = new LinkedMultiMap<JpsModuleSourceRootType<?>, String>();
- sourceFolders.addAll(myMavenProject.getSources());
- testFolders.addAll(myMavenProject.getTestSources());
+ roots.putValues(JavaSourceRootType.SOURCE, myMavenProject.getSources());
+ roots.putValues(JavaSourceRootType.TEST_SOURCE, myMavenProject.getTestSources());
for (MavenImporter each : MavenImporter.getSuitableImporters(myMavenProject)) {
- each.collectSourceFolders(myMavenProject, sourceFolders);
- each.collectTestFolders(myMavenProject, testFolders);
+ each.collectSourceRoots(myMavenProject, new PairConsumer<String, JpsModuleSourceRootType<?>>() {
+ @Override
+ public void consume(String s, JpsModuleSourceRootType<?> type) {
+ roots.putValue(type, s);
+ }
+ });
}
for (MavenResource each : myMavenProject.getResources()) {
- sourceFolders.add(each.getDirectory());
+ roots.putValue(JavaResourceRootType.RESOURCE, each.getDirectory());
}
for (MavenResource each : myMavenProject.getTestResources()) {
- testFolders.add(each.getDirectory());
+ roots.putValue(JavaResourceRootType.TEST_RESOURCE, each.getDirectory());
}
- addBuilderHelperPaths("add-source", sourceFolders);
- addBuilderHelperPaths("add-test-source", testFolders);
+ addBuilderHelperPaths("add-source", roots.getModifiable(JavaSourceRootType.SOURCE));
+ addBuilderHelperPaths("add-test-source", roots.getModifiable(JavaSourceRootType.TEST_SOURCE));
- List<Pair<Path, Boolean>> allFolders = new ArrayList<Pair<Path, Boolean>>(sourceFolders.size() + testFolders.size());
- for (String each : sourceFolders) {
- allFolders.add(Pair.create(myModel.toPath(each), false));
- }
- for (String each : testFolders) {
- allFolders.add(Pair.create(myModel.toPath(each), true));
- }
-
- for (Pair<Path, Boolean> each : normalize(allFolders)) {
- myModel.addSourceFolder(each.first.getPath(), each.second);
+ List<String> addedPaths = new ArrayList<String>();
+ for (JpsModuleSourceRootType<?> type : roots.keySet()) {
+ for (String path : roots.get(type)) {
+ addSourceFolderIfNotOverlap(path, type, addedPaths);
+ }
}
}
- private void addBuilderHelperPaths(String goal, List<String> folders) {
+ private void addBuilderHelperPaths(String goal, Collection<String> folders) {
final Element configurationElement = myMavenProject.getPluginGoalConfiguration("org.codehaus.mojo", "build-helper-maven-plugin", goal);
if (configurationElement != null) {
final Element sourcesElement = configurationElement.getChild("sources");
if (sourcesElement != null) {
- //noinspection unchecked
- for (Element element : (List<Element>)sourcesElement.getChildren()) {
+ for (Element element : sourcesElement.getChildren()) {
folders.add(element.getTextTrim());
}
}
}
}
- @NotNull
- private static List<Pair<Path, Boolean>> normalize(@NotNull List<Pair<Path, Boolean>> folders) {
- List<Pair<Path, Boolean>> result = new ArrayList<Pair<Path, Boolean>>(folders.size());
- for (Pair<Path, Boolean> eachToAdd : folders) {
- addSourceFolder(eachToAdd, result);
- }
- return result;
- }
-
- private static void addSourceFolder(Pair<Path, Boolean> folder, List<Pair<Path, Boolean>> result) {
- for (Pair<Path, Boolean> eachExisting : result) {
- if (MavenRootModelAdapter.isEqualOrAncestor(eachExisting.first.getPath(), folder.first.getPath())
- || MavenRootModelAdapter.isEqualOrAncestor(folder.first.getPath(), eachExisting.first.getPath())) {
+ private void addSourceFolderIfNotOverlap(String path, JpsModuleSourceRootType<?> type, List<String> addedPaths) {
+ String canonicalPath = myModel.toPath(path).getPath();
+ for (String existing : addedPaths) {
+ if (MavenRootModelAdapter.isEqualOrAncestor(existing, canonicalPath)
+ || MavenRootModelAdapter.isEqualOrAncestor(canonicalPath, existing)) {
return;
}
}
- result.add(folder);
+ addedPaths.add(canonicalPath);
+ myModel.addSourceFolder(canonicalPath, type);
}
private void configOutputFolders() {
@@ -186,8 +180,8 @@
myModel.unregisterAll(targetDir.getPath(), true, false);
if (myImportingSettings.getGeneratedSourcesFolder() != MavenImportingSettings.GeneratedSourcesFolder.IGNORE) {
- myModel.addSourceFolder(myMavenProject.getAnnotationProcessorDirectory(true), true, true);
- myModel.addSourceFolder(myMavenProject.getAnnotationProcessorDirectory(false), false, true);
+ myModel.addSourceFolder(myMavenProject.getAnnotationProcessorDirectory(true), JavaSourceRootType.TEST_SOURCE, true);
+ myModel.addSourceFolder(myMavenProject.getAnnotationProcessorDirectory(false), JavaSourceRootType.SOURCE, true);
}
File[] targetChildren = targetDir.listFiles();
@@ -197,10 +191,10 @@
if (!f.isDirectory()) continue;
if (FileUtil.pathsEqual(generatedDir, f.getPath())) {
- configGeneratedSourceFolder(f, false);
+ configGeneratedSourceFolder(f, JavaSourceRootType.SOURCE);
}
else if (FileUtil.pathsEqual(generatedDirTest, f.getPath())) {
- configGeneratedSourceFolder(f, true);
+ configGeneratedSourceFolder(f, JavaSourceRootType.TEST_SOURCE);
}
else {
if (myImportingSettings.isExcludeTargetFolder()) {
@@ -232,29 +226,29 @@
}
}
- private void configGeneratedSourceFolder(@NotNull File targetDir, boolean isTestSources) {
+ private void configGeneratedSourceFolder(@NotNull File targetDir, final JavaSourceRootType rootType) {
switch (myImportingSettings.getGeneratedSourcesFolder()) {
case GENERATED_SOURCE_FOLDER:
- myModel.addSourceFolder(targetDir.getPath(), isTestSources, true);
+ myModel.addSourceFolder(targetDir.getPath(), rootType, true);
break;
case SUBFOLDER:
- addAllSubDirsAsSources(targetDir, isTestSources);
+ addAllSubDirsAsSources(targetDir, rootType);
break;
case AUTODETECT:
Collection<JavaModuleSourceRoot> sourceRoots = JavaSourceRootDetectionUtil.suggestRoots(targetDir);
for (JavaModuleSourceRoot root : sourceRoots) {
- if (targetDir.equals(root.getDirectory())) {
- myModel.addSourceFolder(targetDir.getPath(), isTestSources);
+ if (FileUtil.filesEqual(targetDir, root.getDirectory())) {
+ myModel.addSourceFolder(targetDir.getPath(), rootType);
return;
}
- addAsSourceFolder(root.getDirectory(), isTestSources);
+ addAsSourceFolder(root.getDirectory(), rootType);
}
- addAllSubDirsAsSources(targetDir, isTestSources);
+ addAllSubDirsAsSources(targetDir, rootType);
break;
case IGNORE:
@@ -262,16 +256,16 @@
}
}
- private void addAsSourceFolder(@NotNull File dir, boolean isTestSources) {
+ private void addAsSourceFolder(@NotNull File dir, final JavaSourceRootType rootType) {
if (!myModel.hasRegisteredSourceSubfolder(dir)) {
- myModel.addSourceFolder(dir.getPath(), isTestSources, true);
+ myModel.addSourceFolder(dir.getPath(), rootType, true);
}
}
- private void addAllSubDirsAsSources(@NotNull File dir, boolean isTestSources) {
+ private void addAllSubDirsAsSources(@NotNull File dir, final JavaSourceRootType rootType) {
for (File f : getChildren(dir)) {
if (f.isDirectory()) {
- addAsSourceFolder(f, isTestSources);
+ addAsSourceFolder(f, rootType);
}
}
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenImporter.java
index a646e8d..08117ac 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenImporter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenImporter.java
@@ -22,6 +22,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
+import com.intellij.util.PairConsumer;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import org.jdom.Element;
@@ -33,6 +34,8 @@
import org.jetbrains.idea.maven.server.NativeMavenProjectHolder;
import org.jetbrains.idea.maven.utils.MavenJDOMUtil;
import org.jetbrains.idea.maven.utils.MavenProcessCanceledException;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import java.util.*;
@@ -139,9 +142,28 @@
return true;
}
+ public void collectSourceRoots(MavenProject mavenProject, PairConsumer<String, JpsModuleSourceRootType<?>> result) {
+ List<String> sources = new ArrayList<String>();
+ collectSourceFolders(mavenProject, sources);
+ for (String path : sources) {
+ result.consume(path, JavaSourceRootType.SOURCE);
+ }
+ List<String> testSources = new ArrayList<String>();
+ collectTestFolders(mavenProject, testSources);
+ for (String path : testSources) {
+ result.consume(path, JavaSourceRootType.TEST_SOURCE);
+ }
+ }
+
+ /**
+ * @deprecated override {@link #collectSourceRoots} instead
+ */
public void collectSourceFolders(MavenProject mavenProject, List<String> result) {
}
+ /**
+ * @deprecated override {@link #collectSourceRoots} instead
+ */
public void collectTestFolders(MavenProject mavenProject, List<String> result) {
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java
index 373161d..87d5f5e 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java
@@ -39,6 +39,7 @@
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import org.jetbrains.idea.maven.utils.Path;
import org.jetbrains.idea.maven.utils.Url;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import java.io.File;
import java.util.Set;
@@ -129,11 +130,11 @@
}
}
- public void addSourceFolder(String path, boolean testSource) {
- addSourceFolder(path, testSource, false);
+ public void addSourceFolder(String path, final JpsModuleSourceRootType<?> rootType) {
+ addSourceFolder(path, rootType, false);
}
- public void addSourceFolder(String path, boolean testSource, boolean ifNotEmpty) {
+ public void addSourceFolder(String path, final JpsModuleSourceRootType<?> rootType, boolean ifNotEmpty) {
if (ifNotEmpty) {
String[] childs = new File(toPath(path).getPath()).list();
if (childs == null || childs.length == 0) return;
@@ -147,19 +148,7 @@
if (e == null) return;
unregisterAll(path, true, true);
unregisterAll(path, false, true);
- e.addSourceFolder(url.getUrl(), testSource);
- }
-
- public void addSourceFolderSoft(String path, boolean testSource) {
- if (!exists(path)) return;
-
- Url url = toUrl(path);
- ContentEntry e = getContentRootFor(url);
- if (e == null) return;
-
- if (!hasCollision(path)) {
- e.addSourceFolder(url.getUrl(), testSource);
- }
+ e.addSourceFolder(url.getUrl(), rootType);
}
public boolean hasRegisteredSourceSubfolder(File f) {
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingConfigurable.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingConfigurable.java
index 9dbd14f..dd757ac 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingConfigurable.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingConfigurable.java
@@ -23,6 +23,7 @@
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.maven.execution.MavenJdkComboBox;
import org.jetbrains.idea.maven.server.MavenServerManager;
import javax.swing.*;
@@ -37,6 +38,7 @@
private final JCheckBox myUseMaven3CheckBox;
private final JTextField myEmbedderVMOptions;
+ private final MavenJdkComboBox myEmbedderJdk;
public MavenImportingConfigurable(Project project) {
myImportingSettings = MavenProjectsManager.getInstance(project).getImportingSettings();
@@ -50,12 +52,16 @@
myUseMaven3CheckBox.setToolTipText("If this option is disabled maven 2 will be used");
myEmbedderVMOptions = new JTextField(30);
+ myEmbedderJdk = new MavenJdkComboBox(null); // Embedder JDK is an application setting, not a project setting, so don't pass project
+ assert myEmbedderJdk.getProject() == null;
}
public JComponent createComponent() {
final JPanel panel = mySettingsForm.getAdditionalSettingsPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+ panel.add(Box.createVerticalStrut(5));
+
JPanel useMaven3Panel = new JPanel(new BorderLayout());
useMaven3Panel.add(myUseMaven3CheckBox, BorderLayout.WEST);
@@ -67,9 +73,21 @@
vmOptionLabel.setLabelFor(myEmbedderVMOptions);
embedderVMOptionPanel.add(myEmbedderVMOptions);
+
+ panel.add(Box.createVerticalStrut(3));
panel.add(embedderVMOptionPanel);
+ JPanel embedderJdkPanel = new JPanel(new BorderLayout());
+ JLabel embedderJdkLabel = new JLabel("JDK for importer:");
+ embedderJdkLabel.setLabelFor(myEmbedderJdk);
+ embedderJdkPanel.add(embedderJdkLabel, BorderLayout.WEST);
+ embedderJdkPanel.add(myEmbedderJdk);
+
+ panel.add(Box.createVerticalStrut(3));
+ panel.add(embedderJdkPanel);
+
for (final UnnamedConfigurable additionalConfigurable : myAdditionalConfigurables) {
+ panel.add(Box.createVerticalStrut(3));
panel.add(additionalConfigurable.createComponent());
}
return mySettingsForm.createComponent();
@@ -96,6 +114,10 @@
return true;
}
+ if (!MavenServerManager.getInstance().getEmbedderJdk().equals(myEmbedderJdk.getSelectedValue())) {
+ return true;
+ }
+
return mySettingsForm.isModified(myImportingSettings);
}
@@ -104,6 +126,7 @@
MavenServerManager.getInstance().setUseMaven2(!myUseMaven3CheckBox.isSelected());
MavenServerManager.getInstance().setMavenEmbedderVMOptions(myEmbedderVMOptions.getText());
+ MavenServerManager.getInstance().setEmbedderJdk(myEmbedderJdk.getSelectedValue());
for (final UnnamedConfigurable additionalConfigurable : myAdditionalConfigurables) {
additionalConfigurable.apply();
@@ -115,6 +138,7 @@
myUseMaven3CheckBox.setSelected(!MavenServerManager.getInstance().isUseMaven2());
myEmbedderVMOptions.setText(MavenServerManager.getInstance().getMavenEmbedderVMOptions());
+ myEmbedderJdk.refreshData(MavenServerManager.getInstance().getEmbedderJdk());
for (final UnnamedConfigurable additionalConfigurable : myAdditionalConfigurables) {
additionalConfigurable.reset();
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java
index eda90d0..46579b3 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java
@@ -15,9 +15,13 @@
*/
package org.jetbrains.idea.maven.project.actions;
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationType;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.idea.maven.project.MavenProjectsManager;
+import org.jetbrains.idea.maven.utils.MavenUtil;
import org.jetbrains.idea.maven.utils.actions.MavenAction;
import org.jetbrains.idea.maven.utils.actions.MavenActionUtil;
@@ -26,16 +30,35 @@
protected boolean isAvailable(AnActionEvent e) {
if (!super.isAvailable(e)) return false;
- final DataContext context = e.getDataContext();
- for (VirtualFile each : MavenActionUtil.getMavenProjectsFiles(context)) {
- if (MavenActionUtil.getProjectsManager(context).isManagedFile(each)) return true;
- }
- return false;
+ return !MavenActionUtil.getMavenProjectsFiles(e.getDataContext()).isEmpty();
}
@Override
public void actionPerformed(AnActionEvent e) {
final DataContext context = e.getDataContext();
- MavenActionUtil.getProjectsManager(context).removeManagedFiles(MavenActionUtil.getMavenProjectsFiles(context));
+
+ boolean hasManagedFiles = false;
+
+ MavenProjectsManager projectsManager = MavenActionUtil.getProjectsManager(context);
+
+ for (VirtualFile each : MavenActionUtil.getMavenProjectsFiles(context)) {
+ if (projectsManager.isManagedFile(each)) {
+ hasManagedFiles = true;
+ break;
+ }
+ }
+
+ if (!hasManagedFiles) {
+ Notification notification = new Notification(MavenUtil.MAVEN_NOTIFICATION_GROUP, "Failed to remove project",
+ "You can not remove selected project because it's " +
+ "imported as module of other project. You can ignore it. Only root project can be removed.",
+ NotificationType.ERROR);
+
+ notification.setImportant(true);
+ notification.notify(MavenActionUtil.getProject(context));
+ return;
+ }
+
+ projectsManager.removeManagedFiles(MavenActionUtil.getMavenProjectsFiles(context));
}
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenServerManager.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenServerManager.java
index 863594f..774bc83 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenServerManager.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenServerManager.java
@@ -28,16 +28,14 @@
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.*;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.JavaSdkType;
-import com.intellij.openapi.projectRoots.JdkUtil;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.projectRoots.SimpleJavaSdkType;
+import com.intellij.openapi.projectRoots.*;
+import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Alarm;
import com.intellij.util.PathUtil;
-import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashMap;
import org.apache.lucene.search.Query;
@@ -45,6 +43,7 @@
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.maven.execution.MavenRunnerSettings;
import org.jetbrains.idea.maven.model.MavenId;
import org.jetbrains.idea.maven.model.MavenModel;
import org.jetbrains.idea.maven.project.MavenConsole;
@@ -82,6 +81,7 @@
private boolean useMaven2 = true;
private String mavenEmbedderVMOptions = DEFAULT_VM_OPTIONS;
+ private String embedderJdk = MavenRunnerSettings.USE_INTERNAL_JAVA;
public static MavenServerManager getInstance() {
return ServiceManager.getService(MavenServerManager.class);
@@ -164,12 +164,34 @@
myShutdownAlarm.cancelAllRequests();
}
+ @NotNull
+ private Sdk getJdk() {
+ if (embedderJdk.equals(MavenRunnerSettings.USE_JAVA_HOME)) {
+ final String javaHome = System.getenv("JAVA_HOME");
+ if (!StringUtil.isEmptyOrSpaces(javaHome)) {
+ Sdk jdk = JavaSdk.getInstance().createJdk("", javaHome);
+ if (jdk != null) {
+ return jdk;
+ }
+ }
+ }
+
+ for (Sdk projectJdk : ProjectJdkTable.getInstance().getAllJdks()) {
+ if (projectJdk.getName().equals(embedderJdk)) {
+ return projectJdk;
+ }
+ }
+
+ // By default use internal jdk
+ return JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk();
+ }
+
private RunProfileState createRunProfileState() {
return new CommandLineState(null) {
private SimpleJavaParameters createJavaParameters() throws ExecutionException {
final SimpleJavaParameters params = new SimpleJavaParameters();
- params.setJdk(new SimpleJavaSdkType().createJdk("tmp", SystemProperties.getJavaHome()));
+ params.setJdk(getJdk());
params.setWorkingDirectory(PathManager.getBinPath());
final List<String> classPath = new ArrayList<String>();
@@ -461,6 +483,18 @@
}
}
+ @NotNull
+ public String getEmbedderJdk() {
+ return embedderJdk;
+ }
+
+ public void setEmbedderJdk(@NotNull String embedderJdk) {
+ if (!this.embedderJdk.equals(embedderJdk)) {
+ this.embedderJdk = embedderJdk;
+ shutdown(false);
+ }
+ }
+
@Nullable
@Override
public Element getState() {
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachDialog.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachDialog.java
index 0f865a7..3ca1876 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachDialog.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachDialog.java
@@ -90,8 +90,8 @@
myProject = project;
myProgressIcon.suspend();
myCaptionLabel.setText(
- XmlStringUtil.wrapInHtml(StringUtil.escapeXml("enter keyword, pattern or class name to search by or Maven coordinates," +
- "i.e. 'springframework', 'Logger' or 'org.hibernate:hibernate-core:3.5.0.GA':")
+ XmlStringUtil.wrapInHtml(StringUtil.escapeXml("keyword or class name to search by or exact Maven coordinates, " +
+ "i.e. 'spring', 'Logger' or 'ant:ant-junit:1.6.5'")
));
myInfoLabel.setPreferredSize(
new Dimension(myInfoLabel.getFontMetrics(myInfoLabel.getFont()).stringWidth("Showing: 1000"), myInfoLabel.getPreferredSize().height));
@@ -166,6 +166,7 @@
ProjectBundle.message("file.chooser.directory.for.downloaded.libraries.description"), null,
descriptor);
updateInfoLabel();
+ setOKActionEnabled(false);
init();
}
@@ -276,6 +277,9 @@
}
}
updateComboboxSelection(prevSize != myCoordinates.size());
+ // tooMany != null on last call, so enable OK action to let
+ // local maven repo a chance even if all remote services failed
+ setOKActionEnabled(!myRepositories.isEmpty() || tooMany != null);
return true;
}
});
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/library/RepositoryAttachHandler.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/library/RepositoryAttachHandler.java
index 2ae2f00..81e63c3 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/library/RepositoryAttachHandler.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/library/RepositoryAttachHandler.java
@@ -222,7 +222,11 @@
tooManyResults = true;
}
else {
- resultList.add(Pair.create(artifact, map.get(artifact.getRepositoryId())));
+ MavenRepositoryInfo repository = map.get(artifact.getRepositoryId());
+ // if the artifact is provided by an unsupported repository just skip it
+ // because it won't be resolved anyway
+ if (repository == null) continue;
+ resultList.add(Pair.create(artifact, repository));
}
}
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenArchetypesPanel.form b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenArchetypesPanel.form
new file mode 100644
index 0000000..d7bddc1
--- /dev/null
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenArchetypesPanel.form
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.idea.maven.wizards.MavenArchetypesPanel">
+ <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="3" 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>
+ <xy x="20" y="20" width="500" height="400"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="15313" class="javax.swing.JCheckBox" binding="myUseArchetypeCheckBox" default-binding="true">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Create from &archetype"/>
+ </properties>
+ </component>
+ <hspacer id="15e41">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </hspacer>
+ <component id="f63a2" class="javax.swing.JButton" binding="myAddArchetypeButton">
+ <constraints>
+ <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="A&dd Archetype..."/>
+ </properties>
+ </component>
+ <grid id="d872d" binding="myArchetypesPanel" layout-manager="CardLayout" hgap="0" vgap="0">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="3" vsize-policy="7" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children/>
+ </grid>
+ <scrollpane id="88686" class="com.intellij.ui.components.JBScrollPane" binding="myArchetypeDescriptionScrollPane">
+ <constraints>
+ <grid row="2" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="fb4a8" class="javax.swing.JTextArea" binding="myArchetypeDescriptionField">
+ <constraints/>
+ <properties/>
+ </component>
+ </children>
+ </scrollpane>
+ </children>
+ </grid>
+</form>
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenArchetypesPanel.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenArchetypesPanel.java
new file mode 100644
index 0000000..2c9fcca
--- /dev/null
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenArchetypesPanel.java
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.maven.wizards;
+
+import com.intellij.ide.wizard.StepAdapter;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.ui.*;
+import com.intellij.ui.treeStructure.Tree;
+import com.intellij.util.containers.Convertor;
+import com.intellij.util.ui.AsyncProcessIcon;
+import com.intellij.util.ui.UIUtil;
+import com.intellij.util.ui.tree.TreeUtil;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.maven.indices.MavenIndicesManager;
+import org.jetbrains.idea.maven.model.MavenArchetype;
+
+import javax.swing.*;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.*;
+import java.util.List;
+
+/**
+ * @author Dmitry Avdeev
+ * Date: 24.09.13
+ */
+public class MavenArchetypesPanel implements Disposable {
+
+ private JCheckBox myUseArchetypeCheckBox;
+ private JButton myAddArchetypeButton;
+ private JPanel myArchetypesPanel;
+ private final Tree myArchetypesTree;
+ private JScrollPane myArchetypeDescriptionScrollPane;
+ private JPanel myMainPanel;
+ private JTextArea myArchetypeDescriptionField;
+
+ private Object myCurrentUpdaterMarker;
+ private final AsyncProcessIcon myLoadingIcon = new AsyncProcessIcon.Big(getClass() + ".loading");
+
+ private boolean skipUpdateUI;
+ private final MavenModuleBuilder myBuilder;
+ @Nullable private final StepAdapter myStep;
+
+ public MavenArchetypesPanel(MavenModuleBuilder builder, @Nullable StepAdapter step) {
+ myBuilder = builder;
+ myStep = step;
+ Disposer.register(this, myLoadingIcon);
+
+ myArchetypesTree = new Tree();
+ myArchetypesTree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode()));
+ JScrollPane archetypesScrollPane = ScrollPaneFactory.createScrollPane(myArchetypesTree);
+
+ myArchetypesPanel.add(archetypesScrollPane, "archetypes");
+
+ JPanel loadingPanel = new JPanel(new GridBagLayout());
+ JPanel bp = new JPanel(new BorderLayout(10, 10));
+ bp.add(new JLabel("Loading archetype list..."), BorderLayout.NORTH);
+ bp.add(myLoadingIcon, BorderLayout.CENTER);
+
+ loadingPanel.add(bp, new GridBagConstraints());
+
+ myArchetypesPanel.add(ScrollPaneFactory.createScrollPane(loadingPanel), "loading");
+ ((CardLayout)myArchetypesPanel.getLayout()).show(myArchetypesPanel, "archetypes");
+
+
+ myUseArchetypeCheckBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ updateComponents();
+ }
+ });
+ myUseArchetypeCheckBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ archetypeMayBeChanged();
+ }
+ });
+
+ myAddArchetypeButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ doAddArchetype();
+ }
+ });
+
+ myArchetypesTree.setRootVisible(false);
+ myArchetypesTree.setShowsRootHandles(true);
+ myArchetypesTree.setCellRenderer(new MyRenderer());
+ myArchetypesTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+
+ myArchetypesTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
+ public void valueChanged(TreeSelectionEvent e) {
+ updateArchetypeDescription();
+ archetypeMayBeChanged();
+ }
+ });
+
+ new TreeSpeedSearch(myArchetypesTree, new Convertor<TreePath, String>() {
+ public String convert(TreePath path) {
+ MavenArchetype info = getArchetypeInfoFromPathComponent(path.getLastPathComponent());
+ return info.groupId + ":" + info.artifactId + ":" + info.version;
+ }
+ }).setComparator(new SpeedSearchComparator(false));
+
+ myArchetypeDescriptionField.setEditable(false);
+ myArchetypeDescriptionField.setBackground(UIUtil.getPanelBackground());
+
+ updateComponents();
+ requestUpdate();
+ }
+
+ public JPanel getMainPanel() {
+ return myMainPanel;
+ }
+
+ private void updateComponents() {
+ boolean archetypesEnabled = myUseArchetypeCheckBox.isSelected();
+ myAddArchetypeButton.setEnabled(archetypesEnabled);
+ myArchetypesTree.setEnabled(archetypesEnabled);
+ myArchetypesTree.setBackground(archetypesEnabled ? UIUtil.getListBackground() : UIUtil.getPanelBackground());
+
+ }
+
+ @Nullable
+ public MavenArchetype getSelectedArchetype() {
+ if (!myUseArchetypeCheckBox.isSelected() || myArchetypesTree.isSelectionEmpty()) return null;
+ return getArchetypeInfoFromPathComponent(myArchetypesTree.getLastSelectedPathComponent());
+ }
+
+ private static MavenArchetype getArchetypeInfoFromPathComponent(Object sel) {
+ return (MavenArchetype)((DefaultMutableTreeNode)sel).getUserObject();
+ }
+
+ private void updateArchetypeDescription() {
+ MavenArchetype sel = getSelectedArchetype();
+ String desc = sel == null ? null : sel.description;
+ if (StringUtil.isEmptyOrSpaces(desc)) {
+ myArchetypeDescriptionScrollPane.setVisible(false);
+ }
+ else {
+ myArchetypeDescriptionScrollPane.setVisible(true);
+ myArchetypeDescriptionField.setText(desc);
+ }
+ }
+
+ @Nullable
+ private static TreePath findNodePath(MavenArchetype object, TreeModel model, Object parent) {
+ for (int i = 0; i < model.getChildCount(parent); i++) {
+ DefaultMutableTreeNode each = (DefaultMutableTreeNode)model.getChild(parent, i);
+ if (each.getUserObject().equals(object)) return new TreePath(each.getPath());
+
+ TreePath result = findNodePath(object, model, each);
+ if (result != null) return result;
+ }
+ return null;
+ }
+
+ private static TreeNode groupAndSortArchetypes(Set<MavenArchetype> archetypes) {
+ List<MavenArchetype> list = new ArrayList<MavenArchetype>(archetypes);
+
+ Collections.sort(list, new Comparator<MavenArchetype>() {
+ public int compare(MavenArchetype o1, MavenArchetype o2) {
+ String key1 = o1.groupId + ":" + o1.artifactId;
+ String key2 = o2.groupId + ":" + o2.artifactId;
+
+ int result = key1.compareToIgnoreCase(key2);
+ if (result != 0) return result;
+
+ return o2.version.compareToIgnoreCase(o1.version);
+ }
+ });
+
+ Map<String, List<MavenArchetype>> map = new TreeMap<String, List<MavenArchetype>>();
+
+ for (MavenArchetype each : list) {
+ String key = each.groupId + ":" + each.artifactId;
+ List<MavenArchetype> versions = map.get(key);
+ if (versions == null) {
+ versions = new ArrayList<MavenArchetype>();
+ map.put(key, versions);
+ }
+ versions.add(each);
+ }
+
+ DefaultMutableTreeNode result = new DefaultMutableTreeNode("root", true);
+ for (List<MavenArchetype> each : map.values()) {
+ MavenArchetype eachArchetype = each.get(0);
+ DefaultMutableTreeNode node = new DefaultMutableTreeNode(eachArchetype, true);
+ for (MavenArchetype eachVersion : each) {
+ DefaultMutableTreeNode versionNode = new DefaultMutableTreeNode(eachVersion, false);
+ node.add(versionNode);
+ }
+ result.add(node);
+ }
+
+ return result;
+ }
+
+ public void requestUpdate() {
+
+ MavenArchetype selectedArch = getSelectedArchetype();
+ if (selectedArch == null) {
+ selectedArch = myBuilder.getArchetype();
+ }
+ if (selectedArch != null) myUseArchetypeCheckBox.setSelected(true);
+
+ if (myArchetypesTree.getRowCount() == 0) updateArchetypesList(selectedArch);
+ }
+
+ public void updateArchetypesList(final MavenArchetype selected) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+
+ myLoadingIcon.setBackground(myArchetypesTree.getBackground());
+
+ ((CardLayout)myArchetypesPanel.getLayout()).show(myArchetypesPanel, "loading");
+
+ final Object currentUpdaterMarker = new Object();
+ myCurrentUpdaterMarker = currentUpdaterMarker;
+
+ ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+ public void run() {
+ final Set<MavenArchetype> archetypes = MavenIndicesManager.getInstance().getArchetypes();
+
+ //noinspection SSBasedInspection
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ if (currentUpdaterMarker != myCurrentUpdaterMarker) return; // Other updater has been run.
+
+ ((CardLayout)myArchetypesPanel.getLayout()).show(myArchetypesPanel, "archetypes");
+
+ TreeNode root = groupAndSortArchetypes(archetypes);
+ TreeModel model = new DefaultTreeModel(root);
+ myArchetypesTree.setModel(model);
+
+ if (selected != null) {
+ TreePath path = findNodePath(selected, model, model.getRoot());
+ if (path != null) {
+ myArchetypesTree.expandPath(path.getParentPath());
+ TreeUtil.selectPath(myArchetypesTree, path, true);
+ }
+ }
+
+ updateArchetypeDescription();
+ }
+ });
+ }
+ });
+ }
+
+ private void archetypeMayBeChanged() {
+ MavenArchetype selectedArchetype = getSelectedArchetype();
+ if (((myBuilder.getArchetype() == null) != (selectedArchetype == null))) {
+ myBuilder.setArchetype(selectedArchetype);
+ skipUpdateUI = true;
+ try {
+ if (myStep != null) {
+ myStep.fireStateChanged();
+ }
+ }
+ finally {
+ skipUpdateUI = false;
+ }
+ }
+ }
+
+
+ private void doAddArchetype() {
+ MavenAddArchetypeDialog dialog = new MavenAddArchetypeDialog(myMainPanel);
+ dialog.show();
+ if (!dialog.isOK()) return;
+
+ MavenArchetype archetype = dialog.getArchetype();
+ MavenIndicesManager.getInstance().addArchetype(archetype);
+ updateArchetypesList(archetype);
+ }
+
+ @Override
+ public void dispose() {
+ }
+
+ private static class MyRenderer extends ColoredTreeCellRenderer {
+ public void customizeCellRenderer(JTree tree,
+ Object value,
+ boolean selected,
+ boolean expanded,
+ boolean leaf,
+ int row,
+ boolean hasFocus) {
+ Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
+ if (!(userObject instanceof MavenArchetype)) return;
+
+ MavenArchetype info = (MavenArchetype)userObject;
+
+ if (leaf) {
+ append(info.artifactId, SimpleTextAttributes.GRAY_ATTRIBUTES);
+ append(":" + info.version, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ }
+ else {
+ append(info.groupId + ":", SimpleTextAttributes.GRAY_ATTRIBUTES);
+ append(info.artifactId, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ }
+ }
+ }
+
+}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java
index 6133b9e..2d0752a 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java
@@ -20,6 +20,7 @@
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
import com.intellij.ide.util.projectWizard.SourcePathsBuilder;
import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.module.JavaModuleType;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.StdModuleTypes;
@@ -30,12 +31,14 @@
import com.intellij.openapi.projectRoots.SdkTypeId;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import icons.MavenIcons;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.model.MavenArchetype;
import org.jetbrains.idea.maven.model.MavenId;
import org.jetbrains.idea.maven.project.MavenEnvironmentForm;
@@ -122,7 +125,15 @@
@Override
public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) {
return new ModuleWizardStep[]{
- new MavenModuleWizardStep(wizardContext.getProject(), this, wizardContext),
+ new MavenModuleWizardStep(this, wizardContext, true),
+ new SelectPropertiesStep(wizardContext.getProject(), this)
+ };
+ }
+
+ @Override
+ public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider, boolean forNewWizard) {
+ return new ModuleWizardStep[]{
+ new MavenModuleWizardStep(this, wizardContext, !forNewWizard),
new SelectPropertiesStep(wizardContext.getProject(), this)
};
}
@@ -219,4 +230,16 @@
public String getGroupName() {
return JavaModuleType.JAVA_GROUP;
}
+
+ private MavenArchetypesPanel myPanel;
+
+ @Nullable
+ @Override
+ public JComponent getCustomOptionsPanel(Disposable parentDisposable) {
+ if (myPanel == null) {
+ myPanel = new MavenArchetypesPanel(this, null);
+ Disposer.register(parentDisposable, myPanel);
+ }
+ return myPanel.getMainPanel();
+ }
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.form b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.form
index 1c47880..d666fa0 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.form
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.form
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.idea.maven.wizards.MavenModuleWizardStep">
- <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="8" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
- <margin top="8" left="8" bottom="8" right="8"/>
+ <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="5" 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>
- <xy x="20" y="20" width="380" height="386"/>
+ <xy x="20" y="20" width="529" height="386"/>
</constraints>
<properties/>
- <border type="etched"/>
+ <border type="none"/>
<children>
<component id="ddae6" class="javax.swing.JLabel">
<constraints>
- <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <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>
<text value="GroupId"/>
@@ -18,7 +18,7 @@
</component>
<component id="bbb74" class="javax.swing.JLabel">
<constraints>
- <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="2" 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>
<text value="ArtifactId"/>
@@ -26,7 +26,7 @@
</component>
<component id="4eb56" class="javax.swing.JLabel">
<constraints>
- <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="3" 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>
<text value="Version"/>
@@ -34,7 +34,7 @@
</component>
<component id="d7d25" class="javax.swing.JTextField" binding="myGroupIdField">
<constraints>
- <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <grid row="1" 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>
@@ -42,7 +42,7 @@
</component>
<component id="efb5e" class="javax.swing.JTextField" binding="myArtifactIdField">
<constraints>
- <grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <grid row="2" 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>
@@ -50,65 +50,15 @@
</component>
<component id="b1344" class="javax.swing.JTextField" binding="myVersionField">
<constraints>
- <grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <grid row="3" 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>
- <component id="cf9eb" class="javax.swing.JLabel" binding="myAggregatorLabel">
- <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>
- <text value="Add as module to"/>
- </properties>
- </component>
- <component id="e24ab" class="javax.swing.JButton" binding="mySelectAggregator">
- <constraints>
- <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <margin top="0" left="0" bottom="0" right="0"/>
- <text value="..."/>
- </properties>
- </component>
- <component id="ebeaf" class="javax.swing.JLabel" binding="myParentLabel">
- <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>
- <text value="Parent"/>
- </properties>
- </component>
- <component id="376fa" class="javax.swing.JButton" binding="mySelectParent">
- <constraints>
- <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <margin top="0" left="0" bottom="0" right="0"/>
- <text value="..."/>
- </properties>
- </component>
- <component id="6f435" class="javax.swing.JLabel" binding="myAggregatorNameLabel">
- <constraints>
- <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="4" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text value="Label"/>
- </properties>
- </component>
- <component id="5f27e" class="javax.swing.JLabel" binding="myParentNameLabel">
- <constraints>
- <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="4" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text value="Label"/>
- </properties>
- </component>
<component id="d0095" class="javax.swing.JCheckBox" binding="myInheritGroupIdCheckBox">
<constraints>
- <grid row="2" column="2" 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="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="Inherit"/>
@@ -116,62 +66,80 @@
</component>
<component id="897ff" class="javax.swing.JCheckBox" binding="myInheritVersionCheckBox">
<constraints>
- <grid row="4" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="3" 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="Inherit"/>
</properties>
</component>
- <grid id="320a3" 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"/>
+ <grid id="320a3" binding="myArchetypesPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
- <grid row="5" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties/>
- <border type="none"/>
- <children>
- <component id="15313" class="javax.swing.JCheckBox" binding="myUseArchetypeCheckBox" default-binding="true">
- <constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text value="Create from archetype"/>
- </properties>
- </component>
- <component id="f63a2" class="javax.swing.JButton" binding="myAddArchetypeButton">
- <constraints>
- <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text value="Add archetype..."/>
- </properties>
- </component>
- </children>
- </grid>
- <scrollpane id="88686" class="com.intellij.ui.components.JBScrollPane" binding="myArchetypeDescriptionScrollPane">
- <constraints>
- <grid row="7" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties/>
- <border type="none"/>
- <children>
- <component id="28942" class="javax.swing.JTextArea" binding="myArchetypeDescriptionField">
- <constraints/>
- <properties>
- <background swing-color="Panel.background"/>
- <rows value="3"/>
- </properties>
- </component>
- </children>
- </scrollpane>
- <grid id="d872d" binding="myArchetypesPanel" layout-manager="CardLayout" hgap="0" vgap="0">
- <constraints>
- <grid row="6" column="0" row-span="1" col-span="3" vsize-policy="7" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="4" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children/>
</grid>
+ <grid id="102d8" binding="myAddToPanel" 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="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="cf9eb" 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>
+ <text value="Add as module to"/>
+ </properties>
+ </component>
+ <component id="6f435" class="javax.swing.JLabel" binding="myAggregatorNameLabel">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="4" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Label"/>
+ </properties>
+ </component>
+ <component id="e24ab" class="javax.swing.JButton" binding="mySelectAggregator">
+ <constraints>
+ <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <text value="..."/>
+ </properties>
+ </component>
+ <component id="ebeaf" 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>
+ <text value="Parent"/>
+ </properties>
+ </component>
+ <component id="5f27e" class="javax.swing.JLabel" binding="myParentNameLabel">
+ <constraints>
+ <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="4" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Label"/>
+ </properties>
+ </component>
+ <component id="376fa" class="javax.swing.JButton" binding="mySelectParent">
+ <constraints>
+ <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <text value="..."/>
+ </properties>
+ </component>
+ </children>
+ </grid>
</children>
</grid>
</form>
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.java
index 3f60506..ede845ae 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.java
@@ -18,19 +18,11 @@
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
import com.intellij.ide.util.projectWizard.WizardContext;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.ui.*;
-import com.intellij.ui.treeStructure.Tree;
-import com.intellij.util.containers.Convertor;
-import com.intellij.util.ui.AsyncProcessIcon;
-import com.intellij.util.ui.UIUtil;
-import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.idea.maven.indices.MavenIndicesManager;
import org.jetbrains.idea.maven.model.MavenArchetype;
import org.jetbrains.idea.maven.model.MavenId;
import org.jetbrains.idea.maven.navigator.SelectMavenProjectDialog;
@@ -38,14 +30,9 @@
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import javax.swing.*;
-import javax.swing.event.TreeSelectionEvent;
-import javax.swing.event.TreeSelectionListener;
-import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.*;
-import java.util.List;
public class MavenModuleWizardStep extends ModuleWizardStep {
private static final Icon WIZARD_ICON = IconLoader.getIcon("/addmodulewizard.png");
@@ -67,11 +54,8 @@
private JPanel myMainPanel;
- private JLabel myAggregatorLabel;
private JLabel myAggregatorNameLabel;
private JButton mySelectAggregator;
-
- private JLabel myParentLabel;
private JLabel myParentNameLabel;
private JButton mySelectParent;
@@ -81,45 +65,28 @@
private JTextField myVersionField;
private JCheckBox myInheritVersionCheckBox;
- private JCheckBox myUseArchetypeCheckBox;
- private JButton myAddArchetypeButton;
- private JScrollPane myArchetypesScrollPane;
private JPanel myArchetypesPanel;
- private Tree myArchetypesTree;
- private JScrollPane myArchetypeDescriptionScrollPane;
- private JTextArea myArchetypeDescriptionField;
+ private JPanel myAddToPanel;
- private Object myCurrentUpdaterMarker;
- private final AsyncProcessIcon myLoadingIcon = new AsyncProcessIcon.Big(getClass() + ".loading");
+ @Nullable
+ private final MavenArchetypesPanel myArchetypes;
- private boolean skipUpdateUI;
-
- public MavenModuleWizardStep(@Nullable Project project, MavenModuleBuilder builder, WizardContext context) {
- myProjectOrNull = project;
+ public MavenModuleWizardStep(MavenModuleBuilder builder, WizardContext context, boolean includeArtifacts) {
+ myProjectOrNull = context.getProject();
myBuilder = builder;
myContext = context;
-
+ if (includeArtifacts) {
+ myArchetypes = new MavenArchetypesPanel(builder, this);
+ myArchetypesPanel.add(myArchetypes.getMainPanel(), BorderLayout.CENTER);
+ }
+ else {
+ myArchetypes = null;
+ }
initComponents();
loadSettings();
}
private void initComponents() {
- myArchetypesTree = new Tree();
- myArchetypesTree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode()));
- myArchetypesScrollPane = ScrollPaneFactory.createScrollPane(myArchetypesTree);
-
- myArchetypesPanel.add(myArchetypesScrollPane, "archetypes");
-
- JPanel loadingPanel = new JPanel(new GridBagLayout());
- JPanel bp = new JPanel(new BorderLayout(10, 10));
- bp.add(new JLabel("Loading archetype list..."), BorderLayout.NORTH);
- bp.add(myLoadingIcon, BorderLayout.CENTER);
-
- loadingPanel.add(bp, new GridBagConstraints());
-
- myArchetypesPanel.add(ScrollPaneFactory.createScrollPane(loadingPanel), "loading");
- ((CardLayout)myArchetypesPanel.getLayout()).show(myArchetypesPanel, "archetypes");
-
mySelectAggregator.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
@@ -142,56 +109,6 @@
};
myInheritGroupIdCheckBox.addActionListener(updatingListener);
myInheritVersionCheckBox.addActionListener(updatingListener);
-
- myUseArchetypeCheckBox.addActionListener(updatingListener);
- myUseArchetypeCheckBox.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- archetypeMayBeChanged();
- }
- });
-
- myAddArchetypeButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- doAddArchetype();
- }
- });
-
- myArchetypesTree.setRootVisible(false);
- myArchetypesTree.setShowsRootHandles(true);
- myArchetypesTree.setCellRenderer(new MyRenderer());
- myArchetypesTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
-
- myArchetypesTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
- public void valueChanged(TreeSelectionEvent e) {
- updateArchetypeDescription();
- archetypeMayBeChanged();
- }
- });
-
- new TreeSpeedSearch(myArchetypesTree, new Convertor<TreePath, String>() {
- public String convert(TreePath path) {
- MavenArchetype info = getArchetypeInfoFromPathComponent(path.getLastPathComponent());
- return info.groupId + ":" + info.artifactId + ":" + info.version;
- }
- }).setComparator(new SpeedSearchComparator(false));
-
- myArchetypeDescriptionField.setEditable(false);
- myArchetypeDescriptionField.setBackground(UIUtil.getPanelBackground());
- }
-
- private void archetypeMayBeChanged() {
- MavenArchetype selectedArchetype = getSelectedArchetype();
- if (((myBuilder.getArchetype() == null) != (selectedArchetype == null))) {
- myBuilder.setArchetype(selectedArchetype);
- skipUpdateUI = true;
- try {
- fireStateChanged();
- }
- finally {
- skipUpdateUI = false;
- }
- }
}
@Override
@@ -208,27 +125,11 @@
return d.getResult();
}
- private void doAddArchetype() {
- MavenAddArchetypeDialog dialog = new MavenAddArchetypeDialog(myMainPanel);
- dialog.show();
- if (!dialog.isOK()) return;
-
- MavenArchetype archetype = dialog.getArchetype();
- MavenIndicesManager.getInstance().addArchetype(archetype);
- updateArchetypesList(archetype);
- }
-
@Override
public void onStepLeaving() {
saveSettings();
}
- @Override
- public void disposeUIResources() {
- myLoadingIcon.dispose();
- super.disposeUIResources();
- }
-
private void loadSettings() {
myBuilder.setInheritedOptions(getSavedValue(INHERIT_GROUP_ID_KEY, true),
getSavedValue(INHERIT_VERSION_KEY, true));
@@ -248,13 +149,15 @@
saveValue(INHERIT_GROUP_ID_KEY, myInheritGroupIdCheckBox.isSelected());
saveValue(INHERIT_VERSION_KEY, myInheritVersionCheckBox.isSelected());
- MavenArchetype arch = getSelectedArchetype();
- saveValue(ARCHETYPE_GROUP_ID_KEY, arch == null ? null : arch.groupId);
- saveValue(ARCHETYPE_ARTIFACT_ID_KEY, arch == null ? null : arch.artifactId);
- saveValue(ARCHETYPE_VERSION_KEY, arch == null ? null : arch.version);
+ if (myArchetypes != null) {
+ MavenArchetype arch = myArchetypes.getSelectedArchetype();
+ saveValue(ARCHETYPE_GROUP_ID_KEY, arch == null ? null : arch.groupId);
+ saveValue(ARCHETYPE_ARTIFACT_ID_KEY, arch == null ? null : arch.artifactId);
+ saveValue(ARCHETYPE_VERSION_KEY, arch == null ? null : arch.version);
+ }
}
- private boolean getSavedValue(String key, boolean defaultValue) {
+ private static boolean getSavedValue(String key, boolean defaultValue) {
return getSavedValue(key, String.valueOf(defaultValue)).equals(String.valueOf(true));
}
@@ -263,7 +166,7 @@
return value == null ? defaultValue : value;
}
- private void saveValue(String key, boolean value) {
+ private static void saveValue(String key, boolean value) {
saveValue(key, String.valueOf(value));
}
@@ -296,8 +199,6 @@
@Override
public void updateStep() {
- if (skipUpdateUI) return;
-
if (isMavenizedProject()) {
MavenProject parent = myBuilder.findPotentialParentProject(myProjectOrNull);
myAggregator = parent;
@@ -320,135 +221,18 @@
myInheritGroupIdCheckBox.setSelected(myBuilder.isInheritGroupId());
myInheritVersionCheckBox.setSelected(myBuilder.isInheritVersion());
- MavenArchetype selectedArch = getSelectedArchetype();
- if (selectedArch == null) {
- selectedArch = myBuilder.getArchetype();
+ if (myArchetypes != null) {
+ myArchetypes.requestUpdate();
}
- if (selectedArch != null) myUseArchetypeCheckBox.setSelected(true);
-
- if (myArchetypesTree.getRowCount() == 0) updateArchetypesList(selectedArch);
updateComponents();
}
- private void updateArchetypesList(final MavenArchetype selected) {
- ApplicationManager.getApplication().assertIsDispatchThread();
-
- myLoadingIcon.setBackground(myArchetypesTree.getBackground());
-
- ((CardLayout)myArchetypesPanel.getLayout()).show(myArchetypesPanel, "loading");
-
- final Object currentUpdaterMarker = new Object();
- myCurrentUpdaterMarker = currentUpdaterMarker;
-
- ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
- public void run() {
- final Set<MavenArchetype> archetypes = MavenIndicesManager.getInstance().getArchetypes();
-
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- if (currentUpdaterMarker != myCurrentUpdaterMarker) return; // Other updater has been run.
-
- ((CardLayout)myArchetypesPanel.getLayout()).show(myArchetypesPanel, "archetypes");
-
- TreeNode root = groupAndSortArchetypes(archetypes);
- TreeModel model = new DefaultTreeModel(root);
- myArchetypesTree.setModel(model);
-
- if (selected != null) {
- TreePath path = findNodePath(selected, model, model.getRoot());
- if (path != null) {
- myArchetypesTree.expandPath(path.getParentPath());
- TreeUtil.selectPath(myArchetypesTree, path, true);
- }
- }
-
- updateArchetypeDescription();
- }
- });
- }
- });
- }
-
- private void updateArchetypeDescription() {
- MavenArchetype sel = getSelectedArchetype();
- String desc = sel == null ? null : sel.description;
- if (StringUtil.isEmptyOrSpaces(desc)) {
- myArchetypeDescriptionScrollPane.setVisible(false);
- }
- else {
- myArchetypeDescriptionScrollPane.setVisible(true);
- myArchetypeDescriptionField.setText(desc);
- }
- myMainPanel.revalidate();
- }
-
- @Nullable
- private static TreePath findNodePath(MavenArchetype object, TreeModel model, Object parent) {
- for (int i = 0; i < model.getChildCount(parent); i++) {
- DefaultMutableTreeNode each = (DefaultMutableTreeNode)model.getChild(parent, i);
- if (each.getUserObject().equals(object)) return new TreePath(each.getPath());
-
- TreePath result = findNodePath(object, model, each);
- if (result != null) return result;
- }
- return null;
- }
-
- private static TreeNode groupAndSortArchetypes(Set<MavenArchetype> archetypes) {
- List<MavenArchetype> list = new ArrayList<MavenArchetype>(archetypes);
-
- Collections.sort(list, new Comparator<MavenArchetype>() {
- public int compare(MavenArchetype o1, MavenArchetype o2) {
- String key1 = o1.groupId + ":" + o1.artifactId;
- String key2 = o2.groupId + ":" + o2.artifactId;
-
- int result = key1.compareToIgnoreCase(key2);
- if (result != 0) return result;
-
- return o2.version.compareToIgnoreCase(o1.version);
- }
- });
-
- Map<String, List<MavenArchetype>> map = new TreeMap<String, List<MavenArchetype>>();
-
- for (MavenArchetype each : list) {
- String key = each.groupId + ":" + each.artifactId;
- List<MavenArchetype> versions = map.get(key);
- if (versions == null) {
- versions = new ArrayList<MavenArchetype>();
- map.put(key, versions);
- }
- versions.add(each);
- }
-
- DefaultMutableTreeNode result = new DefaultMutableTreeNode("root", true);
- for (List<MavenArchetype> each : map.values()) {
- MavenArchetype eachArchetype = each.get(0);
- DefaultMutableTreeNode node = new DefaultMutableTreeNode(eachArchetype, true);
- for (MavenArchetype eachVersion : each) {
- DefaultMutableTreeNode versionNode = new DefaultMutableTreeNode(eachVersion, false);
- node.add(versionNode);
- }
- result.add(node);
- }
-
- return result;
- }
-
private boolean isMavenizedProject() {
return myProjectOrNull != null && MavenProjectsManager.getInstance(myProjectOrNull).isMavenizedProject();
}
private void updateComponents() {
- if (!isMavenizedProject()) {
- myAggregatorLabel.setEnabled(false);
- myAggregatorNameLabel.setEnabled(false);
- mySelectAggregator.setEnabled(false);
-
- myParentLabel.setEnabled(false);
- myParentNameLabel.setEnabled(false);
- mySelectParent.setEnabled(false);
- }
+ myAddToPanel.setVisible(isMavenizedProject());
myAggregatorNameLabel.setText(formatProjectString(myAggregator));
myParentNameLabel.setText(formatProjectString(myParent));
@@ -476,11 +260,6 @@
myInheritGroupIdCheckBox.setEnabled(true);
myInheritVersionCheckBox.setEnabled(true);
}
-
- boolean archetypesEnabled = myUseArchetypeCheckBox.isSelected();
- myAddArchetypeButton.setEnabled(archetypesEnabled);
- myArchetypesTree.setEnabled(archetypesEnabled);
- myArchetypesTree.setBackground(archetypesEnabled ? UIUtil.getListBackground() : UIUtil.getPanelBackground());
}
private static String formatProjectString(MavenProject project) {
@@ -500,17 +279,9 @@
myBuilder.setInheritedOptions(myInheritGroupIdCheckBox.isSelected(),
myInheritVersionCheckBox.isSelected());
- myBuilder.setArchetype(getSelectedArchetype());
- }
-
- @Nullable
- private MavenArchetype getSelectedArchetype() {
- if (!myUseArchetypeCheckBox.isSelected() || myArchetypesTree.isSelectionEmpty()) return null;
- return getArchetypeInfoFromPathComponent(myArchetypesTree.getLastSelectedPathComponent());
- }
-
- private static MavenArchetype getArchetypeInfoFromPathComponent(Object sel) {
- return (MavenArchetype)((DefaultMutableTreeNode)sel).getUserObject();
+ if (myArchetypes != null) {
+ myBuilder.setArchetype(myArchetypes.getSelectedArchetype());
+ }
}
@Override
@@ -518,30 +289,6 @@
return WIZARD_ICON;
}
- private static class MyRenderer extends ColoredTreeCellRenderer {
- public void customizeCellRenderer(JTree tree,
- Object value,
- boolean selected,
- boolean expanded,
- boolean leaf,
- int row,
- boolean hasFocus) {
- Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
- if (!(userObject instanceof MavenArchetype)) return;
-
- MavenArchetype info = (MavenArchetype)userObject;
-
- if (leaf) {
- append(info.artifactId, SimpleTextAttributes.GRAY_ATTRIBUTES);
- append(":" + info.version, SimpleTextAttributes.REGULAR_ATTRIBUTES);
- }
- else {
- append(info.groupId + ":", SimpleTextAttributes.GRAY_ATTRIBUTES);
- append(info.artifactId, SimpleTextAttributes.REGULAR_ATTRIBUTES);
- }
- }
- }
-
@Override
public String getHelpId() {
return "reference.dialogs.new.project.fromScratch.maven";
diff --git a/plugins/maven/src/main/resources/META-INF/plugin.xml b/plugins/maven/src/main/resources/META-INF/plugin.xml
index eb65fe8..491fad1 100644
--- a/plugins/maven/src/main/resources/META-INF/plugin.xml
+++ b/plugins/maven/src/main/resources/META-INF/plugin.xml
@@ -88,6 +88,9 @@
<localInspection language="XML" shortName="MavenDuplicateDependenciesInspection" bundle="MavenDomBundle" key="inspection.duplicate.dependencies.name"
groupKey="inspection.group" enabledByDefault="true" level="WARNING"
implementationClass="org.jetbrains.idea.maven.dom.inspections.MavenDuplicateDependenciesInspection"/>
+ <localInspection language="XML" shortName="MavenDuplicatePluginInspection" bundle="MavenDomBundle" key="inspection.duplicate.plugin.declaration"
+ groupKey="inspection.group" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.idea.maven.dom.inspections.MavenDuplicatePluginInspection"/>
<localInspection language="XML" shortName="MavenRedundantGroupId" bundle="MavenDomBundle" key="inspection.redundant.groupId.name"
groupKey="inspection.group" enabledByDefault="true" level="WARNING"
implementationClass="org.jetbrains.idea.maven.dom.inspections.MavenRedundantGroupIdInspection"/>
diff --git a/plugins/maven/src/main/resources/MavenDomBundle.properties b/plugins/maven/src/main/resources/MavenDomBundle.properties
index 2b10fb8..d840ea4 100644
--- a/plugins/maven/src/main/resources/MavenDomBundle.properties
+++ b/plugins/maven/src/main/resources/MavenDomBundle.properties
@@ -35,5 +35,6 @@
refactoring.introduce.property=Introduce Property
choose.project=Choose project
inspection.duplicate.dependencies.name=Duplicate Dependencies
+inspection.duplicate.plugin.declaration=Duplicate plugin declaration
MavenDuplicateDependenciesInspection.has.duplicates=<html><body>Dependency is duplicated in file(s): {0} </body></html>
inspection.redundant.groupId.name=Redundant groupId
\ No newline at end of file
diff --git a/plugins/maven/src/main/resources/RunnerBundle.properties b/plugins/maven/src/main/resources/RunnerBundle.properties
index a12ded3..4ebc070 100644
--- a/plugins/maven/src/main/resources/RunnerBundle.properties
+++ b/plugins/maven/src/main/resources/RunnerBundle.properties
@@ -28,8 +28,8 @@
maven.select.maven.home.directory=Select Maven home directory
maven.running=Running
-maven.java.internal=Internal JRE
-maven.java.home.env=Use JAVA_HOME
+maven.java.internal=<html>Internal JRE <font color=gray>({0})</font></html>
+maven.java.home.env=<html>Use JAVA_HOME <font color=gray>({0})</font></html>
maven.java.home.undefined=JAVA_HOME environment variable not defined
maven.java.home.invalid=JAVA_HOME environment vairable does not point to valid JRE ({0})
maven.java.not.found=Cannot find JRE ''{0}''
diff --git a/plugins/maven/src/main/resources/inspectionDescriptions/MavenDuplicatePluginInspection.html b/plugins/maven/src/main/resources/inspectionDescriptions/MavenDuplicatePluginInspection.html
new file mode 100644
index 0000000..0fd90db
--- /dev/null
+++ b/plugins/maven/src/main/resources/inspectionDescriptions/MavenDuplicatePluginInspection.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<span style="font-family: verdana,serif; font-size: smaller;">This inspection checks duplication of plugin declaration in pom.xml</span>
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java
index c75a604..94ca15b 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java
@@ -48,9 +48,13 @@
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.execution.*;
import org.jetbrains.idea.maven.model.MavenArtifact;
import org.jetbrains.idea.maven.project.*;
+import org.jetbrains.jps.model.java.JavaResourceRootType;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import javax.swing.*;
import java.io.File;
@@ -115,36 +119,42 @@
}
protected void assertSources(String moduleName, String... expectedSources) {
- doAssertContentFolders(moduleName, true, false, expectedSources);
+ doAssertContentFolders(moduleName, JavaSourceRootType.SOURCE, expectedSources);
+ }
+
+ protected void assertResources(String moduleName, String... expectedSources) {
+ doAssertContentFolders(moduleName, JavaResourceRootType.RESOURCE, expectedSources);
}
protected void assertTestSources(String moduleName, String... expectedSources) {
- doAssertContentFolders(moduleName, true, true, expectedSources);
+ doAssertContentFolders(moduleName, JavaSourceRootType.TEST_SOURCE, expectedSources);
+ }
+
+ protected void assertTestResources(String moduleName, String... expectedSources) {
+ doAssertContentFolders(moduleName, JavaResourceRootType.TEST_RESOURCE, expectedSources);
}
protected void assertExcludes(String moduleName, String... expectedExcludes) {
- doAssertContentFolders(moduleName, false, false, expectedExcludes);
+ doAssertContentFolders(moduleName, null, expectedExcludes);
}
protected void assertContentRootExcludes(String moduleName, String contentRoot, String... expectedExcudes) {
- doAssertContentFolders(getContentRoot(moduleName, contentRoot), false, false, expectedExcudes);
+ doAssertContentFolders(getContentRoot(moduleName, contentRoot), null, expectedExcudes);
}
- private void doAssertContentFolders(String moduleName, boolean isSource, boolean isTest, String... expected) {
- doAssertContentFolders(getContentRoot(moduleName), isSource, isTest, expected);
+ private void doAssertContentFolders(String moduleName, @Nullable JpsModuleSourceRootType<?> rootType, String... expected) {
+ doAssertContentFolders(getContentRoot(moduleName), rootType, expected);
}
- private static void doAssertContentFolders(ContentEntry e, boolean isSource, boolean isTest, String... expected) {
+ private static void doAssertContentFolders(ContentEntry e, @Nullable JpsModuleSourceRootType<?> rootType, String... expected) {
List<String> actual = new ArrayList<String>();
- for (ContentFolder f : isSource ? e.getSourceFolders() : e.getExcludeFolders()) {
- if (isSource && (isTest != ((SourceFolder)f).isTestSource())) continue;
-
+ for (ContentFolder f : rootType != null ? e.getSourceFolders(rootType) : Arrays.asList(e.getExcludeFolders())) {
String rootUrl = e.getUrl();
String folderUrl = f.getUrl();
if (folderUrl.startsWith(rootUrl)) {
- int lenght = rootUrl.length() + 1;
- folderUrl = folderUrl.substring(Math.min(lenght, folderUrl.length()));
+ int length = rootUrl.length() + 1;
+ folderUrl = folderUrl.substring(Math.min(length, folderUrl.length()));
}
actual.add(folderUrl);
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java
index 93cad46..7ef085a 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java
@@ -29,23 +29,12 @@
import java.io.File;
-public abstract class ResourceCopyingTest extends MavenImportingTestCase {
-
- public static class IdeaModeTest extends ResourceCopyingTest {
- @Override
- protected boolean useJps() {
- return false;
- }
+public class ResourceCopyingTest extends MavenImportingTestCase {
+ @Override
+ protected boolean useJps() {
+ return true;
}
- public static class JpsModeTest extends ResourceCopyingTest {
- @Override
- protected boolean useJps() {
- return true;
- }
- }
-
-
@Override
protected void setUpInWriteAction() throws Exception {
super.setUpInWriteAction();
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenExecutionTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenExecutionTest.java
index 9752ee7..4a0f5e2 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenExecutionTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenExecutionTest.java
@@ -95,8 +95,9 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"target/generated-sources/foo");
+ assertResources("project",
+ "src/main/resources");
assertExcludes("project",
"target/bar",
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/FoldersImportingTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/FoldersImportingTest.java
index fa08576..fd88870 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/FoldersImportingTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/FoldersImportingTest.java
@@ -16,14 +16,13 @@
package org.jetbrains.idea.maven.importing;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.roots.CompilerModuleExtension;
-import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.idea.maven.MavenCustomRepositoryHelper;
import org.jetbrains.idea.maven.MavenImportingTestCase;
import org.jetbrains.idea.maven.project.MavenImportingSettings;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import org.jetbrains.idea.maven.utils.Path;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
import java.io.File;
import java.io.IOException;
@@ -39,8 +38,10 @@
assertModules("project");
assertContentRoots("project", getProjectPath());
- assertSources("project", "src/main/java", "src/main/resources");
- assertTestSources("project", "src/test/java", "src/test/resources");
+ assertSources("project", "src/main/java");
+ assertResources("project", "src/main/resources");
+ assertTestSources("project", "src/test/java");
+ assertTestResources("project", "src/test/resources");
}
public void testInvalidProjectHasContentRoot() throws Exception {
@@ -70,8 +71,10 @@
"</build>");
assertModules("project");
- assertSources("project", "src/main/java", "src/main/resources");
- assertTestSources("project", "src/test/java", "src/test/resources");
+ assertSources("project", "src/main/java");
+ assertResources("project", "src/main/resources");
+ assertTestSources("project", "src/test/java");
+ assertTestResources("project", "src/test/resources");
}
public void testDoesNotResetUserFolders() throws Exception {
@@ -87,7 +90,7 @@
MavenRootModelAdapter adapter = new MavenRootModelAdapter(myProjectsTree.findProject(myProjectPom),
getModule("project"),
new MavenDefaultModifiableModelsProvider(myProject));
- adapter.addSourceFolder(dir1.getPath(), false);
+ adapter.addSourceFolder(dir1.getPath(), JavaSourceRootType.SOURCE);
adapter.addExcludedFolder(dir2.getPath());
adapter.getRootModel().commit();
}
@@ -115,7 +118,8 @@
"<artifactId>project</artifactId>" +
"<version>1</version>");
- assertSources("project", "src/main/java", "src/main/resources");
+ assertSources("project", "src/main/java");
+ assertResources("project", "src/main/resources");
importProject("<groupId>test</groupId>" +
"<artifactId>project</artifactId>" +
@@ -131,7 +135,8 @@
"<artifactId>project</artifactId>" +
"<version>1</version>");
- assertSources("project", "src/main/java", "src/main/resources");
+ assertSources("project", "src/main/java");
+ assertResources("project", "src/main/resources");
}
public void testSourceFoldersOnReimport() throws Exception {
@@ -195,8 +200,10 @@
assertModules("project");
assertContentRoots("project", getProjectPath());
- assertSources("project", "src", "res1", "res2");
- assertTestSources("project", "test", "testRes1", "testRes2");
+ assertSources("project", "src");
+ assertResources("project", "res1", "res2");
+ assertTestSources("project", "test");
+ assertTestResources("project", "testRes1", "testRes2");
}
public void testDoNotAddCustomSourceFoldersOutsideOfContentRoot() throws Exception {
@@ -275,7 +282,8 @@
resolveFoldersAndImport();
assertModules("project");
- assertSources("project", "src/main/java", "src/main/resources", "src1", "src2");
+ assertSources("project", "src/main/java", "src1", "src2");
+ assertResources("project", "src/main/resources");
}
public void testPluginSourceDuringGenerateResourcesPhase() throws Exception {
@@ -312,7 +320,8 @@
resolveFoldersAndImport();
assertModules("project");
- assertSources("project", "extraResources", "src/main/java", "src/main/resources");
+ assertSources("project", "src/main/java", "extraResources");
+ assertResources("project", "src/main/resources");
}
public void testPluginTestSourcesDuringGenerateTestResourcesPhase() throws Exception {
@@ -351,7 +360,8 @@
resolveFoldersAndImport();
assertModules("project");
- assertTestSources("project", "extraTestResources", "src/test/java", "src/test/resources");
+ assertTestSources("project", "src/test/java", "extraTestResources");
+ assertTestResources("project", "src/test/resources");
}
public void testPluginSourcesWithRelativePath() throws Exception {
@@ -388,7 +398,8 @@
resolveFoldersAndImport();
assertModules("project");
- assertSources("project", "src/main/java", "src/main/resources", "relativePath");
+ assertSources("project", "src/main/java", "relativePath");
+ assertResources("project", "src/main/resources");
}
public void testPluginSourcesWithVariables() throws Exception {
@@ -425,7 +436,8 @@
resolveFoldersAndImport();
assertModules("project");
- assertSources("project", "src/main/java", "src/main/resources", "target/src");
+ assertSources("project", "src/main/java", "target/src");
+ assertResources("project", "src/main/resources");
}
public void testPluginSourcesWithIntermoduleDependency() throws Exception {
@@ -487,7 +499,8 @@
assertModules("project", "m1", "m2");
resolveFoldersAndImport();
- assertSources("m1", "src/main/java", "src/main/resources", "src/foo");
+ assertSources("m1", "src/main/java", "src/foo");
+ assertResources("m1", "src/main/resources");
}
public void testDownloadingNecessaryPlugins() throws Exception {
@@ -545,15 +558,15 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"target/generated-sources/src1",
"target/generated-sources/src2");
+ assertResources("project", "src/main/resources");
assertTestSources("project",
"src/test/java",
- "src/test/resources",
"target/generated-test-sources/test1",
"target/generated-test-sources/test2");
+ assertTestResources("project", "src/test/resources");
}
public void testAddingExistingGeneratedSources2() throws Exception {
@@ -567,8 +580,8 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"target/generated-sources");
+ assertResources("project", "src/main/resources");
}
public void testAddingExistingGeneratedSources3() throws Exception {
@@ -585,8 +598,8 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"target/generated-sources/com");
+ assertResources("project", "src/main/resources");
}
public void testOverrideAnnotationSources() throws Exception {
@@ -604,8 +617,8 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"target/generated-sources");
+ assertResources("project", "src/main/resources");
}
public void testIgnoreGeneratedSources() throws Exception {
@@ -621,9 +634,8 @@
"<artifactId>project</artifactId>" +
"<version>1</version>");
- assertSources("project",
- "src/main/java",
- "src/main/resources");
+ assertSources("project", "src/main/java");
+ assertResources("project", "src/main/resources");
}
@@ -640,10 +652,10 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"target/generated-sources/A1/B1",
"target/generated-sources/A1/B2",
"target/generated-sources/A2");
+ assertResources("project", "src/main/resources");
}
public void testAddingExistingGeneratedSources5() throws Exception {
@@ -658,8 +670,8 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"target/generated-sources");
+ assertResources("project", "src/main/resources");
}
@@ -678,13 +690,13 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"targetCustom/generated-sources/src");
+ assertResources("project", "src/main/resources");
assertTestSources("project",
"src/test/java",
- "src/test/resources",
"targetCustom/generated-test-sources/test");
+ assertTestResources("project", "src/test/resources");
}
public void testDoesNotAddAlreadyRegisteredSourcesUnderGeneratedDir() throws Exception {
@@ -735,13 +747,13 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"target/generated-sources/main/src");
+ assertResources("project", "src/main/resources");
assertTestSources("project",
"src/test/java",
- "src/test/resources",
"target/generated-test-sources/test/src");
+ assertTestResources("project", "src/test/resources");
}
public void testIgnoringFilesRightUnderGeneratedSources() throws Exception {
@@ -753,8 +765,10 @@
"<artifactId>project</artifactId>" +
"<version>1</version>");
- assertSources("project", "src/main/java", "src/main/resources");
- assertTestSources("project", "src/test/java", "src/test/resources");
+ assertSources("project", "src/main/java");
+ assertResources("project", "src/main/resources");
+ assertTestSources("project", "src/test/java");
+ assertTestResources("project", "src/test/resources");
}
public void testExcludingOutputDirectories() throws Exception {
@@ -891,13 +905,13 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"target/generated-sources/baz");
+ assertResources("project", "src/main/resources");
assertTestSources("project",
"src/test/java",
- "src/test/resources",
"target/generated-test-sources/bazz");
+ assertTestResources("project", "src/test/resources");
}
public void testDoesNotExcludeSourcesUnderTargetDir() throws Exception {
@@ -954,9 +968,8 @@
assertExcludes("project", "target/foo");
- assertSources("project",
- "target/src/main",
- "src/main/resources");
+ assertSources("project", "target/src/main");
+ assertResources("project", "src/main/resources");
}
public void testUnexcludeNewSources() throws Exception {
@@ -1023,15 +1036,15 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"target/generated-sources/foo",
"target/generated-sources/annotations");
+ assertResources("project", "src/main/resources");
assertTestSources("project",
"src/test/java",
- "src/test/resources",
"target/generated-test-sources/foo",
"target/generated-test-sources/test-annotations");
+ assertTestResources("project", "src/test/resources");
}
public void testCustomAnnotationProcessorSources() throws Exception {
@@ -1064,20 +1077,16 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"anno",
"target/generated-sources/foo",
"target/generated-sources/annotations",
"target/generated-sources/test-annotations");
+ assertResources("project", "src/main/resources");
assertTestSources("project",
"src/test/java",
- "src/test/resources",
"target/generated-test-sources/foo");
- }
-
- private CompilerModuleExtension getCompilerExtension(String moduleName) {
- return ModuleRootManager.getInstance(getModule(moduleName)).getModuleExtension(CompilerModuleExtension.class);
+ assertTestResources("project", "src/test/resources");
}
private void createProjectSubDirsWithFile(String ... dirs) throws IOException {
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/GroovyImporterTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/GroovyImporterTest.java
index 9cf632dc..53941f9 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/GroovyImporterTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/GroovyImporterTest.java
@@ -93,12 +93,12 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"src/main/groovy");
+ assertResources("project", "src/main/resources");
assertTestSources("project",
"src/test/java",
- "src/test/resources",
"src/test/groovy");
+ assertTestResources("project", "src/test/resources");
}
public void testAddingCustomGroovySpecificSources() throws Exception {
@@ -161,14 +161,14 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"src/foo1",
"src/foo2");
+ assertResources("project", "src/main/resources");
assertTestSources("project",
"src/test/java",
- "src/test/resources",
"src/test-foo1",
"src/test-foo2");
+ assertTestResources("project", "src/test/resources");
}
public void testAddingCustomGroovySpecificSourcesByRelativePath() throws Exception {
@@ -255,11 +255,10 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"target/generated-sources/xxx");
- assertTestSources("project",
- "src/test/java",
- "src/test/resources");
+ assertResources("project", "src/main/resources");
+ assertTestSources("project", "src/test/java");
+ assertTestResources("project", "src/test/resources");
assertExcludes("project",
"target/generated-sources/groovy-stubs");
@@ -308,11 +307,10 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"target/generated-sources/xxx");
- assertTestSources("project",
- "src/test/java",
- "src/test/resources");
+ assertResources("project", "src/main/resources");
+ assertTestSources("project", "src/test/java");
+ assertTestResources("project", "src/test/resources");
assertExcludes("project",
"target/generated-sources/foo",
@@ -456,11 +454,10 @@
assertSources("project",
"src/main/java",
- "src/main/resources",
"target/generated-sources/xxx");
- assertTestSources("project",
- "src/test/java",
- "src/test/resources");
+ assertResources("project", "src/main/resources");
+ assertTestSources("project", "src/test/java");
+ assertTestResources("project", "src/test/resources");
assertExcludes("project",
"target/generated-sources/groovy-stubs");
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedDependencyInspectionTest.groovy b/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedDependencyInspectionTest.groovy
new file mode 100644
index 0000000..62de301
--- /dev/null
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedDependencyInspectionTest.groovy
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.maven.inspections
+
+import org.jetbrains.idea.maven.dom.MavenDomTestCase
+import org.jetbrains.idea.maven.dom.inspections.MavenDuplicateDependenciesInspection
+
+/**
+ * @author Sergey Evdokimov
+ */
+class MavenDuplicatedDependencyInspectionTest extends MavenDomTestCase {
+
+ public void testDuplicatedInSameFile() {
+ myFixture.enableInspections(MavenDuplicateDependenciesInspection)
+
+ createProjectPom("""
+ <groupId>mavenParent</groupId>
+ <artifactId>childA</artifactId>
+ <version>1.0</version>
+
+ <dependencies>
+ <<warning>dependency</warning>>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <<warning>dependency</warning>>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.2</version>
+ </dependency>
+ </dependencies>
+""")
+
+ checkHighlighting()
+ }
+
+ public void testDuplicatedInSameFileDifferentVersion() {
+ myFixture.enableInspections(MavenDuplicateDependenciesInspection)
+
+ createProjectPom("""
+ <groupId>mavenParent</groupId>
+ <artifactId>childA</artifactId>
+ <version>1.0</version>
+
+ <dependencies>
+ <<warning>dependency</warning>>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.2</version>
+ </dependency>
+ <<warning>dependency</warning>>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ </dependency>
+ </dependencies>
+""")
+
+ checkHighlighting()
+ }
+
+ public void testDuplicatedInParentDifferentScope() {
+ myFixture.enableInspections(MavenDuplicateDependenciesInspection)
+
+ createModulePom("child", """
+ <groupId>mavenParent</groupId>
+ <artifactId>child</artifactId>
+ <version>1.0</version>
+
+<parent>
+ <groupId>mavenParent</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+</parent>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.2</version>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+""")
+
+ createProjectPom("""
+ <groupId>mavenParent</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>child</module>
+ </modules>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.2</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+""")
+
+ importProject()
+
+ checkHighlighting(myProjectPom, true, false, true)
+ }
+
+ public void testDuplicatedInParentSameScope() {
+ myFixture.enableInspections(MavenDuplicateDependenciesInspection)
+
+ createModulePom("child", """
+ <groupId>mavenParent</groupId>
+ <artifactId>child</artifactId>
+ <version>1.0</version>
+
+<parent>
+ <groupId>mavenParent</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+</parent>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.2</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+""")
+
+ createProjectPom("""
+ <groupId>mavenParent</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>child</module>
+ </modules>
+
+ <dependencies>
+ <<warning>dependency</warning>>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.2</version>
+ </dependency>
+ </dependencies>
+""")
+
+ importProject()
+
+ checkHighlighting(myProjectPom, true, false, true)
+ }
+
+ public void testDuplicatedInParentDifferentVersion() {
+ myFixture.enableInspections(MavenDuplicateDependenciesInspection)
+
+ createModulePom("child", """
+ <groupId>mavenParent</groupId>
+ <artifactId>child</artifactId>
+ <version>1.0</version>
+
+<parent>
+ <groupId>mavenParent</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+</parent>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ </dependency>
+ </dependencies>
+""")
+
+ importProject("""
+ <groupId>mavenParent</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>child</module>
+ </modules>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.2</version>
+ </dependency>
+ </dependencies>
+""")
+
+ checkHighlighting(myProjectPom, true, false, true)
+ }
+
+ public void testDuplicatedInManagedDependencies() {
+ myFixture.enableInspections(MavenDuplicateDependenciesInspection)
+
+ createProjectPom("""
+ <groupId>mavenParent</groupId>
+ <artifactId>childA</artifactId>
+ <version>1.0</version>
+
+ <dependencyManagement>
+ <dependencies>
+ <<warning>dependency</warning>>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.2</version>
+ <type>jar</type>
+ </dependency>
+
+ <<warning>dependency</warning>>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.0</version>
+ <classifier>sources</classifier>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+""")
+
+ checkHighlighting()
+ }
+
+}
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedInspectionTest.groovy b/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedInspectionTest.groovy
deleted file mode 100644
index c589168..0000000
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedInspectionTest.groovy
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.idea.maven.inspections
-
-import org.jetbrains.idea.maven.dom.MavenDomTestCase
-import org.jetbrains.idea.maven.dom.inspections.MavenDuplicateDependenciesInspection
-
-/**
- * @author Sergey Evdokimov
- */
-class MavenDuplicatedInspectionTest extends MavenDomTestCase {
-
- public void testDuplicatedInSameFile() {
- myFixture.enableInspections(MavenDuplicateDependenciesInspection)
-
- createProjectPom("""
- <groupId>mavenParent</groupId>
- <artifactId>childA</artifactId>
- <version>1.0</version>
-
- <dependencies>
- <<warning>dependency</warning>>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.2</version>
- <scope>provided</scope>
- </dependency>
- <<warning>dependency</warning>>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.2</version>
- </dependency>
- </dependencies>
-""")
-
- checkHighlighting()
- }
-
- public void testDuplicatedInSameFileDifferentVersion() {
- myFixture.enableInspections(MavenDuplicateDependenciesInspection)
-
- createProjectPom("""
- <groupId>mavenParent</groupId>
- <artifactId>childA</artifactId>
- <version>1.0</version>
-
- <dependencies>
- <<warning>dependency</warning>>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.2</version>
- </dependency>
- <<warning>dependency</warning>>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- </dependency>
- </dependencies>
-""")
-
- checkHighlighting()
- }
-
- public void testDuplicatedInParentDifferentScope() {
- myFixture.enableInspections(MavenDuplicateDependenciesInspection)
-
- createModulePom("child", """
- <groupId>mavenParent</groupId>
- <artifactId>child</artifactId>
- <version>1.0</version>
-
-<parent>
- <groupId>mavenParent</groupId>
- <artifactId>parent</artifactId>
- <version>1.0</version>
-</parent>
-
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.2</version>
- <scope>runtime</scope>
- </dependency>
- </dependencies>
-""")
-
- createProjectPom("""
- <groupId>mavenParent</groupId>
- <artifactId>parent</artifactId>
- <version>1.0</version>
- <packaging>pom</packaging>
-
- <modules>
- <module>child</module>
- </modules>
-
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.2</version>
- <scope>provided</scope>
- </dependency>
- </dependencies>
-""")
-
- importProject()
-
- checkHighlighting(myProjectPom, true, false, true)
- }
-
- public void testDuplicatedInParentSameScope() {
- myFixture.enableInspections(MavenDuplicateDependenciesInspection)
-
- createModulePom("child", """
- <groupId>mavenParent</groupId>
- <artifactId>child</artifactId>
- <version>1.0</version>
-
-<parent>
- <groupId>mavenParent</groupId>
- <artifactId>parent</artifactId>
- <version>1.0</version>
-</parent>
-
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.2</version>
- <scope>compile</scope>
- </dependency>
- </dependencies>
-""")
-
- createProjectPom("""
- <groupId>mavenParent</groupId>
- <artifactId>parent</artifactId>
- <version>1.0</version>
- <packaging>pom</packaging>
-
- <modules>
- <module>child</module>
- </modules>
-
- <dependencies>
- <<warning>dependency</warning>>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.2</version>
- </dependency>
- </dependencies>
-""")
-
- importProject()
-
- checkHighlighting(myProjectPom, true, false, true)
- }
-
- public void testDuplicatedInParentDifferentVersion() {
- myFixture.enableInspections(MavenDuplicateDependenciesInspection)
-
- createModulePom("child", """
- <groupId>mavenParent</groupId>
- <artifactId>child</artifactId>
- <version>1.0</version>
-
-<parent>
- <groupId>mavenParent</groupId>
- <artifactId>parent</artifactId>
- <version>1.0</version>
-</parent>
-
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- </dependency>
- </dependencies>
-""")
-
- importProject("""
- <groupId>mavenParent</groupId>
- <artifactId>parent</artifactId>
- <version>1.0</version>
- <packaging>pom</packaging>
-
- <modules>
- <module>child</module>
- </modules>
-
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.2</version>
- </dependency>
- </dependencies>
-""")
-
- checkHighlighting(myProjectPom, true, false, true)
- }
-
- public void testDuplicatedInManagedDependencies() {
- myFixture.enableInspections(MavenDuplicateDependenciesInspection)
-
- createProjectPom("""
- <groupId>mavenParent</groupId>
- <artifactId>childA</artifactId>
- <version>1.0</version>
-
- <dependencyManagement>
- <dependencies>
- <<warning>dependency</warning>>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.2</version>
- <type>jar</type>
- </dependency>
-
- <<warning>dependency</warning>>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.0</version>
- </dependency>
-
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.0</version>
- <classifier>sources</classifier>
- </dependency>
- </dependencies>
- </dependencyManagement>
-""")
-
- checkHighlighting()
- }
-
-}
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedPluginInspectionTest.groovy b/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedPluginInspectionTest.groovy
new file mode 100644
index 0000000..4535f26
--- /dev/null
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedPluginInspectionTest.groovy
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.maven.inspections
+
+import org.jetbrains.idea.maven.dom.MavenDomTestCase
+import org.jetbrains.idea.maven.dom.inspections.MavenDuplicatePluginInspection
+/**
+ * @author Sergey Evdokimov
+ */
+class MavenDuplicatedPluginInspectionTest extends MavenDomTestCase {
+
+ public void testDuplicatedPlugin() {
+ myFixture.enableInspections(MavenDuplicatePluginInspection)
+
+ createProjectPom("""
+ <groupId>mavenParent</groupId>
+ <artifactId>childA</artifactId>
+ <version>1.0</version>
+
+ <build>
+ <plugins>
+ <<warning>plugin</warning>>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <<warning>plugin</warning>>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ </plugins>
+ </build>
+""")
+
+ checkHighlighting()
+ }
+}
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenFoldersImporterTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenFoldersImporterTest.java
index 9bd3df2..b25d8fb 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenFoldersImporterTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenFoldersImporterTest.java
@@ -23,6 +23,7 @@
import org.jetbrains.idea.maven.importing.MavenDefaultModifiableModelsProvider;
import org.jetbrains.idea.maven.importing.MavenFoldersImporter;
import org.jetbrains.idea.maven.importing.MavenRootModelAdapter;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
import java.io.File;
@@ -90,13 +91,17 @@
"<artifactId>project</artifactId>" +
"<version>1</version>");
- assertSources("project", "src/main/java", "src/main/resources");
- assertTestSources("project", "src/test/java", "src/test/resources");
+ assertSources("project", "src/main/java");
+ assertResources("project", "src/main/resources");
+ assertTestSources("project", "src/test/java");
+ assertTestResources("project", "src/test/resources");
updateProjectFolders();
- assertSources("project", "src/main/java", "src/main/resources");
- assertTestSources("project", "src/test/java", "src/test/resources");
+ assertSources("project", "src/main/java");
+ assertResources("project", "src/main/resources");
+ assertTestSources("project", "src/test/java");
+ assertTestResources("project", "src/test/resources");
}
public void testDoesNotExcludeRegisteredSources() throws Exception {
@@ -113,7 +118,7 @@
MavenRootModelAdapter adapter = new MavenRootModelAdapter(myProjectsTree.findProject(myProjectPom),
getModule("project"),
new MavenDefaultModifiableModelsProvider(myProject));
- adapter.addSourceFolder(sourceDir.getPath(), false);
+ adapter.addSourceFolder(sourceDir.getPath(), JavaSourceRootType.SOURCE);
adapter.getRootModel().commit();
}
});
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsManagerTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsManagerTest.java
index ac9b17a..6c9bc1c 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsManagerTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsManagerTest.java
@@ -920,7 +920,8 @@
" </plugins>" +
"</build>");
- assertSources("project", "src/main/java", "src/main/resources", "src1", "src2");
+ assertSources("project", "src/main/java", "src1", "src2");
+ assertResources("project", "src/main/resources");
}
public void testForceReimport() throws Exception {
diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesProjectViewTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesProjectViewTest.java
index 1b2ffb9f..b91a878 100644
--- a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesProjectViewTest.java
+++ b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesProjectViewTest.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.lang.properties;
import com.intellij.ide.projectView.impl.AbstractProjectViewPSIPane;
@@ -13,6 +28,7 @@
public class PropertiesProjectViewTest extends LightPlatformCodeInsightFixtureTestCase {
private TestProjectTreeStructure myStructure;
+ @SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors")
public PropertiesProjectViewTest() {
PlatformTestCase.initPlatformLangPrefix();
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties
index b642114..bbb8e54 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties
@@ -206,6 +206,7 @@
radio.configure.upgrade.auto.15format=Upgrade automatically (use Subversion 1.&5)
radio.configure.upgrade.auto.16format=Upgrade automatically (use Subversion 1.&6)
radio.configure.upgrade.auto.17format=Upgrade automatically (use Subversion 1.&7)
+radio.configure.upgrade.auto.18format=Upgrade automatically (use Subversion 1.&8)
label.configure.create.label={0} is about to create new Subversion working copy,\n\
please, select desired working copy format:
@@ -215,10 +216,12 @@
radio.configure.create.auto.15format=1.&5 format
radio.configure.create.auto.16format=1.&6 format
radio.configure.create.auto.17format=1.&7 format
+radio.configure.create.auto.18format=1.&8 format
label.configure.change.label=Change working copy ''{0}'' format to:
radio.configure.change.auto.16format=1.&6 format
radio.configure.change.auto.17format=1.&7 format
+radio.configure.change.auto.18format=1.&8 format
dialog.upgrade.wcopy.format.title=Subversion Working Copy Format
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java
index ecd387b..ac23963 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java
@@ -282,10 +282,6 @@
return SvnConfiguration.UseAcceleration.nothing;
}
- private void setAcceleration(SvnConfiguration.UseAcceleration acceleration) {
- myWithCommandLineClient.setSelected(SvnConfiguration.UseAcceleration.commandLine.equals(acceleration));
- }
-
public void apply() throws ConfigurationException {
SvnConfiguration configuration = SvnConfiguration.getInstance(myProject);
configuration.setConfigurationDirParameters(myUseDefaultCheckBox.isSelected(), myConfigurationDirectoryText.getText());
@@ -351,7 +347,7 @@
mySSHConnectionTimeout.setValue(Long.valueOf(configuration.mySSHConnectionTimeout / 1000));
mySSHReadTimeout.setValue(Long.valueOf(configuration.mySSHReadTimeout / 1000));
myHttpTimeout.setValue(Long.valueOf(configuration.getHttpTimeout() / 1000));
- setAcceleration(configuration.myUseAcceleration);
+ myWithCommandLineClient.setSelected(configuration.isCommandLine());
final SvnApplicationSettings applicationSettings17 = SvnApplicationSettings.getInstance();
myCommandLineClient.setText(applicationSettings17.getCommandLinePath());
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java
index b4f7991..1b2a8df 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java
@@ -75,11 +75,6 @@
private final static String SERVERS_FILE_NAME = "servers";
- public static final String UPGRADE_AUTO = "auto";
- public static final String UPGRADE_AUTO_15 = "auto1.5";
- public static final String UPGRADE_AUTO_16 = "auto1.6";
- public static final String UPGRADE_AUTO_17 = "auto1.7";
- public static final String UPGRADE_NONE = "none";
public static final String CLEANUP_ON_START_RUN = "cleanupOnStartRun";
private final Project myProject;
@@ -130,6 +125,10 @@
private SvnInteractiveAuthenticationProvider myInteractiveProvider;
private IdeaSVNConfigFile myConfigFile;
+ public boolean isCommandLine() {
+ return UseAcceleration.commandLine.equals(myUseAcceleration);
+ }
+
@Override
public Element getState() {
Element element = new Element("state");
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java
index 77783bad..2595631 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java
@@ -136,17 +136,20 @@
return result;
}
- public static String showUpgradeDialog(final File path, final Project project, final boolean display13format, final String mode,
- @NotNull final Ref<Boolean> wasOk) {
+ public static WorkingCopyFormat showUpgradeDialog(final File path,
+ final Project project,
+ final boolean display13format,
+ @NotNull final WorkingCopyFormat defaultSelection,
+ @NotNull final Ref<Boolean> wasOk) {
assert ! ApplicationManager.getApplication().isUnitTestMode();
- final String[] newMode = new String[] {mode};
+ final Ref<WorkingCopyFormat> format = new Ref<WorkingCopyFormat>(defaultSelection);
WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(new Runnable() {
public void run() {
- wasOk.set(displayUpgradeDialog(project, path, display13format, newMode));
+ wasOk.set(displayUpgradeDialog(project, path, display13format, format));
}
});
ApplicationManager.getApplication().getMessageBus().syncPublisher(SvnVcs.WC_CONVERTED).run();
- return newMode[0];
+ return format.get();
}
public static WorkingCopyFormat findRootAndGetFormat(final File path) {
@@ -187,12 +190,12 @@
return WorkingCopyFormat.getInstance(format);
}
- private static boolean displayUpgradeDialog(Project project, File path, final boolean dispay13format, String[] newMode) {
+ private static boolean displayUpgradeDialog(Project project, File path, final boolean dispay13format, Ref<WorkingCopyFormat> format) {
UpgradeFormatDialog dialog = new UpgradeFormatDialog(project, path, false);
- dialog.setData(newMode[0]);
+ dialog.setData(format.get());
dialog.show();
if (dialog.isOK()) {
- newMode[0] = dialog.getUpgradeMode();
+ format.set(dialog.getUpgradeMode());
}
return dialog.isOK();
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java
index 2de7232..1b0792a 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java
@@ -24,4 +24,5 @@
String SVN_EXECUTABLE = "svn:executable";
String SVN_IGNORE = "svn:ignore";
String SVN_EXTERNALS = "svn:externals";
+ String LOG = "svn:log";
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java
deleted file mode 100644
index fcac396..0000000
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.idea.svn;
-
-import com.intellij.vcsUtil.LearningProxy;
-import org.jetbrains.idea.svn.portable.SVNChangelistClientI;
-import org.jetbrains.idea.svn.portable.SvnUpdateClientI;
-import org.tmatesoft.svn.core.SVNException;
-
-import java.io.File;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 10/19/12
- * Time: 4:22 PM
- */
-// TODO: Likely to be removed (together with SvnAbstractWriteOperationLocks).
-public class SvnProxies {
- private final SvnAbstractWriteOperationLocks myLocks;
- private final AtomicReference<LearningProxy<SVNChangelistClientI, SVNException>> myChangelist;
- private final AtomicReference<LearningProxy<SvnUpdateClientI, SVNException>> myUpdate;
-
- public SvnProxies(SvnAbstractWriteOperationLocks locks) {
- myLocks = locks;
- myChangelist = new AtomicReference<LearningProxy<SVNChangelistClientI, SVNException>>();
- myUpdate = new AtomicReference<LearningProxy<SvnUpdateClientI, SVNException>>();
- }
-
- public LearningProxy<SVNChangelistClientI, SVNException> getChangelistsProfessor(final File file) {
- if (myChangelist.get() == null) {
- final MyLearningProxy<SVNChangelistClientI> proxy = new MyLearningProxy<SVNChangelistClientI>(myLocks, file);
- final SVNChangelistClientI learn = proxy.learn(SVNChangelistClientI.class);
- try {
- learn.addToChangelist(null, null, null, null);
- learn.doAddToChangelist(null, null, null, null);
- learn.doRemoveFromChangelist(null, null, null);
- learn.removeFromChangelist(null, null, null);
- } catch (SVNException e) {
- //can not occur since methods are not really called
- throw new RuntimeException(e);
- }
-
- myChangelist.set(proxy);
- }
- return myChangelist.get();
- }
-
- public LearningProxy<SvnUpdateClientI, SVNException> getUpdateProfessor(final File file) {
- if (myUpdate.get() == null) {
- final MyLearningProxy<SvnUpdateClientI> proxy = new MyLearningProxy<SvnUpdateClientI>(myLocks, file);
- final SvnUpdateClientI learn = proxy.learn(SvnUpdateClientI.class);
- try {
- learn.doUpdate(null, null, false);
- learn.doUpdate(null, null, false, false);
- learn.doUpdate((File[]) null, null, null, false, false);
- learn.doUpdate((File[]) null, null, null, false, false, false);
- learn.doUpdate((File) null, null, null, false, false);
-
- learn.doSwitch(null, null, null, false);
- learn.doSwitch(null, null, null, null, false);
- learn.doSwitch(null, null, null, null, false, false);
- learn.doSwitch(null, null, null, null, null, false, false);
- learn.doSwitch(null, null, null, null, null, false, false, false);
-
- learn.doCheckout(null, null, null, null, false);
- // todo continue
- //learn.doCheckout();
- //learn.doCheckout();
- }
- catch (SVNException e) {
- //can not occur since methods are not really called
- throw new RuntimeException(e);
- }
- myUpdate.set(proxy);
- }
- return myUpdate.get();
- }
-
- private static class MyLearningProxy<T> extends LearningProxy<T, SVNException> {
- private final SvnAbstractWriteOperationLocks myLocks;
- private final File myFile;
-
- private MyLearningProxy(SvnAbstractWriteOperationLocks locks, final File file) {
- myLocks = locks;
- myFile = file;
- }
-
- @Override
- protected void onBefore() throws SVNException {
- myLocks.lockWrite(myFile);
- }
-
- @Override
- protected void onAfter() throws SVNException {
- myLocks.unlockWrite(myFile);
- }
- }
-}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java
index b246ea7..690ec0e 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java
@@ -129,8 +129,8 @@
myConfiguration17 = SvnConfiguration.getInstance(myProject);
myPath = path;
myDepth = depth;
- mySvnClient = new SvnkitSvnStatusClient(client);
- myCommandLineClient = new SvnCommandLineStatusClient(myProject);
+ mySvnClient = new SvnkitSvnStatusClient(myVcs, client);
+ myCommandLineClient = new SvnCommandLineStatusClient(myVcs);
myIsInnerCopyRoot = isInnerCopyRoot;
}
@@ -159,7 +159,7 @@
if (CheckJavaHL.isPresent() && SvnConfiguration.UseAcceleration.javaHL.equals(myConfiguration17.myUseAcceleration) &&
Svn17Detector.is17(myProject, file)) {
return new JavaHLSvnStatusClient(myProject);
- } else if (SvnConfiguration.UseAcceleration.commandLine.equals(myConfiguration17.myUseAcceleration)) {
+ } else if (myConfiguration17.isCommandLine()) {
// apply command line disregarding working copy format
return myCommandLineClient;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
index 7594c2a..07301c0 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
@@ -91,7 +91,11 @@
}
public static boolean isSvnVersioned(final Project project, File parent) {
- final SVNInfo info = SvnVcs.getInstance(project).getInfo(parent);
+ return isSvnVersioned(SvnVcs.getInstance(project), parent);
+ }
+
+ public static boolean isSvnVersioned(final @NotNull SvnVcs vcs, File parent) {
+ final SVNInfo info = vcs.getInfo(parent);
return info != null;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
index 02b28a9..55b79b0 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
@@ -83,6 +83,7 @@
import org.jetbrains.idea.svn.lowLevel.PrimitivePool;
import org.jetbrains.idea.svn.networking.SSLProtocolExceptionParser;
import org.jetbrains.idea.svn.portable.SvnWcClientI;
+import org.jetbrains.idea.svn.properties.PropertyClient;
import org.jetbrains.idea.svn.rollback.SvnRollbackEnvironment;
import org.jetbrains.idea.svn.update.SvnIntegrateEnvironment;
import org.jetbrains.idea.svn.update.SvnUpdateEnvironment;
@@ -202,8 +203,8 @@
};
private SvnCheckoutProvider myCheckoutProvider;
- private ClientFactory cmdClientFactory;
- private ClientFactory svnKitClientFactory;
+ private final ClientFactory cmdClientFactory;
+ private final ClientFactory svnKitClientFactory;
private final boolean myLogExceptions;
@@ -244,6 +245,9 @@
public SvnVcs(final Project project, MessageBus bus, SvnConfiguration svnConfiguration, final SvnLoadedBrachesStorage storage) {
super(project, VCS_NAME);
+ cmdClientFactory = new CmdClientFactory(this);
+ svnKitClientFactory = new SvnKitClientFactory(this);
+
myLoadedBranchesStorage = storage;
myRootsToWorkingCopies = new RootsToWorkingCopies(this);
myConfiguration = svnConfiguration;
@@ -362,7 +366,7 @@
public boolean checkCommandLineVersion() {
boolean isValid = true;
- if (!isProject16() && (SvnConfiguration.UseAcceleration.commandLine.equals(myConfiguration.myUseAcceleration) || isProject18())) {
+ if (!isProject16() && (myConfiguration.isCommandLine() || isProject18())) {
isValid = myChecker.checkExecutableAndNotifyIfNeeded();
}
@@ -501,9 +505,6 @@
checkCommandLineVersion();
}
- cmdClientFactory = new CmdClientFactory(this);
- svnKitClientFactory = new SvnKitClientFactory(this);
-
// do one time after project loaded
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() {
@Override
@@ -861,7 +862,7 @@
}
@Nullable
- public SVNPropertyValue getPropertyWithCaching(final VirtualFile file, final String propName) throws SVNException {
+ public SVNPropertyValue getPropertyWithCaching(final VirtualFile file, final String propName) throws VcsException {
Map<String, Pair<SVNPropertyValue, Trinity<Long, Long, Long>>> cachedMap = myPropertyCache.get(keyForVf(file));
final Pair<SVNPropertyValue, Trinity<Long, Long, Long>> cachedValue = cachedMap == null ? null : cachedMap.get(propName);
@@ -875,7 +876,8 @@
}
}
- final SVNPropertyData value = createWCClient().doGetProperty(ioFile, propName, SVNRevision.WORKING, SVNRevision.WORKING);
+ PropertyClient client = getFactory(ioFile).createPropertyClient();
+ final SVNPropertyData value = client.getProperty(SvnTarget.fromFile(ioFile, SVNRevision.WORKING), propName, false, SVNRevision.WORKING);
final SVNPropertyValue propValue = value == null ? null : value.getValue();
if (cachedMap == null) {
@@ -1349,7 +1351,7 @@
}
private WorkingCopyFormat getProjectRootFormat() {
- return getWorkingCopyFormat(new File(getProject().getBaseDir().getPath()));
+ return !getProject().isDefault() ? getWorkingCopyFormat(new File(getProject().getBaseDir().getPath())) : WorkingCopyFormat.UNKNOWN;
}
/**
@@ -1395,6 +1397,11 @@
@NotNull
public ClientFactory getFactoryFromSettings() {
- return myConfiguration.myUseAcceleration.equals(SvnConfiguration.UseAcceleration.commandLine) ? cmdClientFactory : svnKitClientFactory;
+ return myConfiguration.isCommandLine() ? cmdClientFactory : svnKitClientFactory;
+ }
+
+ @NotNull
+ public ClientFactory getCommandLineFactory() {
+ return cmdClientFactory;
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java
index 909d904..041ee28 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java
@@ -97,33 +97,7 @@
return UNKNOWN;
}
- public static WorkingCopyFormat getInstance(final String updateOption) {
- if (SvnConfiguration.UPGRADE_AUTO_17.equals(updateOption)) {
- return ONE_DOT_SEVEN;
- } else if (SvnConfiguration.UPGRADE_AUTO_16.equals(updateOption)) {
- return ONE_DOT_SIX;
- } else if (SvnConfiguration.UPGRADE_AUTO_15.equals(updateOption)) {
- return ONE_DOT_FIVE;
- } else if (SvnConfiguration.UPGRADE_AUTO.equals(updateOption)) {
- return ONE_DOT_FOUR;
- }
- return ONE_DOT_THREE;
- }
-
public int getFormat() {
return myFormat;
}
-
- public String getOption() {
- if (ONE_DOT_SEVEN.equals(this)) {
- return SvnConfiguration.UPGRADE_AUTO_17;
- } else if (ONE_DOT_SIX.equals(this)) {
- return SvnConfiguration.UPGRADE_AUTO_16;
- } else if (ONE_DOT_FIVE.equals(this)) {
- return SvnConfiguration.UPGRADE_AUTO_15;
- } else if (ONE_DOT_FOUR.equals(this)) {
- return SvnConfiguration.UPGRADE_AUTO;
- }
- return SvnConfiguration.UPGRADE_NONE;
- }
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java
index 1af0550..337a045 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java
@@ -36,13 +36,17 @@
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnPropertyKeys;
import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.api.ClientFactory;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
import org.jetbrains.idea.svn.dialogs.SelectCreateExternalTargetDialog;
+import org.jetbrains.idea.svn.update.UpdateClient;
import org.tmatesoft.svn.core.SVNCancelException;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.internal.wc.SVNExternal;
import org.tmatesoft.svn.core.wc.*;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
@@ -94,7 +98,7 @@
dirtyScopeManager.fileDirty(filePath);
if (checkout) {
// +-
- final SVNUpdateClient client = vcs.createUpdateClient();
+ final UpdateClient client = vcs.getFactory(ioFile).createUpdateClient();
client.setEventHandler(new ISVNEventHandler() {
@Override
public void handleEvent(SVNEvent event, double progress) throws SVNException {
@@ -118,12 +122,16 @@
catch (SVNException e1) {
AbstractVcsHelper.getInstance(project).showError(new VcsException(e1), "Create External");
}
+ catch (VcsException e1) {
+ AbstractVcsHelper.getInstance(project).showError(e1, "Create External");
+ }
}
- public static boolean addToExternalProperty(SvnVcs vcs, File ioFile, String target, String url) throws SVNException {
- final SVNWCClient wcClient = vcs.createWCClient();
- final SVNPropertyData propertyData =
- wcClient.doGetProperty(ioFile, SvnPropertyKeys.SVN_EXTERNALS, SVNRevision.UNDEFINED, SVNRevision.UNDEFINED);
+ public static boolean addToExternalProperty(@NotNull SvnVcs vcs, @NotNull File ioFile, String target, String url)
+ throws SVNException, VcsException {
+ ClientFactory factory = vcs.getFactory(ioFile);
+ SVNPropertyData propertyData = factory.createPropertyClient().getProperty(SvnTarget.fromFile(ioFile), SvnPropertyKeys.SVN_EXTERNALS,
+ false, SVNRevision.UNDEFINED);
String newValue;
if (propertyData != null && propertyData.getValue() != null && ! StringUtil.isEmptyOrSpaces(propertyData.getValue().getString())) {
final SVNExternal[] externals = SVNExternal.parseExternals("Create External", propertyData.getValue().getString());
@@ -135,16 +143,17 @@
}
}
final String string = createExternalDefinitionString(url, target);
- newValue = propertyData.getValue().getString() + "\n" + string;
+ newValue = propertyData.getValue().getString().trim() + "\n" + string;
} else {
newValue = createExternalDefinitionString(url, target);
}
- wcClient.doSetProperty(ioFile, SvnPropertyKeys.SVN_EXTERNALS, SVNPropertyValue.create(newValue), false, SVNDepth.EMPTY, null, null);
+ factory.createPropertyClient().setProperty(ioFile, SvnPropertyKeys.SVN_EXTERNALS, SVNPropertyValue.create(newValue), SVNDepth.EMPTY,
+ false);
return false;
}
public static String createExternalDefinitionString(String url, String target) {
- return url + " " + target;
+ return CommandUtil.escape(url) + " " + target;
}
@Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java
index c2fe2c3..f7674b6 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java
@@ -37,9 +37,6 @@
boolean includeMergedRevisions,
@Nullable SVNDiffOptions diffOptions,
@Nullable final ISVNAnnotateHandler handler) throws VcsException {
- // TODO: after merge remove setting includeMergedRevisions to false and update parsing
- includeMergedRevisions = false;
-
List<String> parameters = new ArrayList<String>();
CommandUtil.put(parameters, target.getPathOrUrlString(), pegRevision);
parameters.add("--revision");
@@ -55,9 +52,7 @@
public void parseOutput(@NotNull String output, @Nullable ISVNAnnotateHandler handler) throws VcsException {
try {
- JAXBContext context = JAXBContext.newInstance(BlameInfo.class);
- Unmarshaller unmarshaller = context.createUnmarshaller();
- BlameInfo info = (BlameInfo)unmarshaller.unmarshal(new StringReader(output));
+ BlameInfo info = CommandUtil.parse(output, BlameInfo.class);
if (handler != null && info != null && info.target != null && info.target.lineEntries != null) {
for (LineEntry entry : info.target.lineEntries) {
@@ -75,7 +70,10 @@
private static void invokeHandler(ISVNAnnotateHandler handler, LineEntry entry) throws SVNException {
// line numbers in our api start from 0 - not from 1 like in svn output
- handler.handleLine(entry.date(), entry.revision(), entry.author(), null, null, 0, null, null, entry.lineNumber - 1);
+ // "line" value is not used in handlers - so null is passed
+ handler
+ .handleLine(entry.date(), entry.revision(), entry.author(), null, entry.mergedDate(), entry.mergedRevision(), entry.mergedAuthor(),
+ entry.mergedPath(), entry.lineNumber - 1);
}
@XmlRootElement(name = "blame")
@@ -99,15 +97,53 @@
@XmlElement(name = "commit")
public CommitEntry commit;
+ @XmlElement(name = "merged")
+ public MergedEntry merged;
+
public long revision() {
+ return revision(commit);
+ }
+
+ @Nullable
+ public String author() {
+ return author(commit);
+ }
+
+ @Nullable
+ public Date date() {
+ return date(commit);
+ }
+
+ @Nullable
+ public String mergedPath() {
+ return merged != null ? merged.path : null;
+ }
+
+ public long mergedRevision() {
+ return merged != null ? revision(merged.commit) : 0;
+ }
+
+ @Nullable
+ public String mergedAuthor() {
+ return merged != null ? author(merged.commit) : null;
+ }
+
+ @Nullable
+ public Date mergedDate() {
+ return merged != null ? date(merged.commit) : null;
+ }
+
+ private static long revision(@Nullable CommitEntry commit) {
return commit != null ? commit.revision : 0;
}
- public String author() {
+ @Nullable
+ private static String author(@Nullable CommitEntry commit) {
return commit != null ? commit.author : null;
}
- public Date date() {
+ @Nullable
+ private static Date date(@Nullable CommitEntry commit) {
return commit != null ? commit.date : null;
}
}
@@ -123,4 +159,13 @@
@XmlElement(name = "date")
public Date date;
}
+
+ public static class MergedEntry {
+
+ @XmlAttribute(name = "path")
+ public String path;
+
+ @XmlElement(name = "commit")
+ public CommitEntry commit;
+ }
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java
index 739e2ad..27c0d1e 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java
@@ -5,7 +5,9 @@
import org.jetbrains.idea.svn.add.AddClient;
import org.jetbrains.idea.svn.annotate.AnnotateClient;
import org.jetbrains.idea.svn.change.ChangeListClient;
+import org.jetbrains.idea.svn.checkin.ImportClient;
import org.jetbrains.idea.svn.checkout.CheckoutClient;
+import org.jetbrains.idea.svn.checkout.ExportClient;
import org.jetbrains.idea.svn.cleanup.CleanupClient;
import org.jetbrains.idea.svn.conflict.ConflictClient;
import org.jetbrains.idea.svn.content.ContentClient;
@@ -15,7 +17,7 @@
import org.jetbrains.idea.svn.integrate.MergeClient;
import org.jetbrains.idea.svn.lock.LockClient;
import org.jetbrains.idea.svn.portable.SvnStatusClientI;
-import org.jetbrains.idea.svn.portable.SvnUpdateClientI;
+import org.jetbrains.idea.svn.update.UpdateClient;
import org.jetbrains.idea.svn.portable.SvnWcClientI;
import org.jetbrains.idea.svn.properties.PropertyClient;
import org.jetbrains.idea.svn.revert.RevertClient;
@@ -46,6 +48,9 @@
protected LockClient myLockClient;
protected CleanupClient myCleanupClient;
protected RelocateClient myRelocateClient;
+ protected VersionClient myVersionClient;
+ protected ImportClient myImportClient;
+ protected ExportClient myExportClient;
protected ClientFactory(@NotNull SvnVcs vcs) {
myVcs = vcs;
@@ -94,7 +99,7 @@
// TODO: Update this in same like other clients - move to corresponding package, rename clients
// New instances should be always created by this method, as setXxx() methods are currently used in update logic
@NotNull
- public abstract SvnUpdateClientI createUpdateClient();
+ public abstract UpdateClient createUpdateClient();
@NotNull
public DeleteClient createDeleteClient() {
@@ -147,6 +152,21 @@
}
@NotNull
+ public VersionClient createVersionClient() {
+ return prepare(myVersionClient);
+ }
+
+ @NotNull
+ public ImportClient createImportClient() {
+ return prepare(myImportClient);
+ }
+
+ @NotNull
+ public ExportClient createExportClient() {
+ return prepare(myExportClient);
+ }
+
+ @NotNull
protected <T extends SvnClient> T prepare(@NotNull T client) {
client.setVcs(myVcs);
client.setFactory(this);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java
index e0849d9..8b73377 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java
@@ -5,11 +5,13 @@
import org.jetbrains.idea.svn.add.CmdAddClient;
import org.jetbrains.idea.svn.annotate.CmdAnnotateClient;
import org.jetbrains.idea.svn.change.CmdChangeListClient;
+import org.jetbrains.idea.svn.checkin.CmdImportClient;
import org.jetbrains.idea.svn.checkout.CmdCheckoutClient;
+import org.jetbrains.idea.svn.checkout.CmdExportClient;
import org.jetbrains.idea.svn.cleanup.CmdCleanupClient;
+import org.jetbrains.idea.svn.update.CmdUpdateClient;
import org.jetbrains.idea.svn.commandLine.SvnCommandLineInfoClient;
import org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient;
-import org.jetbrains.idea.svn.commandLine.SvnCommandLineUpdateClient;
import org.jetbrains.idea.svn.conflict.CmdConflictClient;
import org.jetbrains.idea.svn.content.CmdContentClient;
import org.jetbrains.idea.svn.copy.CmdCopyMoveClient;
@@ -17,7 +19,7 @@
import org.jetbrains.idea.svn.history.CmdHistoryClient;
import org.jetbrains.idea.svn.integrate.CmdMergeClient;
import org.jetbrains.idea.svn.lock.CmdLockClient;
-import org.jetbrains.idea.svn.portable.SvnUpdateClientI;
+import org.jetbrains.idea.svn.update.UpdateClient;
import org.jetbrains.idea.svn.properties.CmdPropertyClient;
import org.jetbrains.idea.svn.revert.CmdRevertClient;
import org.jetbrains.idea.svn.update.CmdRelocateClient;
@@ -48,13 +50,16 @@
myLockClient = new CmdLockClient();
myCleanupClient = new CmdCleanupClient();
myRelocateClient = new CmdRelocateClient();
- statusClient = new SvnCommandLineStatusClient(myVcs.getProject());
- infoClient = new SvnCommandLineInfoClient(myVcs.getProject());
+ myVersionClient = new CmdVersionClient();
+ myImportClient = new CmdImportClient();
+ myExportClient = new CmdExportClient();
+ statusClient = new SvnCommandLineStatusClient(myVcs);
+ infoClient = new SvnCommandLineInfoClient(myVcs);
}
@NotNull
@Override
- public SvnUpdateClientI createUpdateClient() {
- return new SvnCommandLineUpdateClient(myVcs, null);
+ public UpdateClient createUpdateClient() {
+ return prepare(new CmdUpdateClient());
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java
new file mode 100644
index 0000000..bc40a9f
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java
@@ -0,0 +1,80 @@
+package org.jetbrains.idea.svn.api;
+
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.execution.process.CapturingProcessHandler;
+import com.intellij.execution.process.ProcessOutput;
+import com.intellij.openapi.util.Version;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.SvnApplicationSettings;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdVersionClient extends BaseSvnClient implements VersionClient {
+
+ @NotNull
+ @Override
+ public Version getVersion() throws VcsException {
+ // TODO: Do not use common command running mechanism for now - to preserve timeout behavior.
+ ProcessOutput output;
+
+ try {
+ output = runCommand();
+ }
+ catch (ExecutionException e) {
+ throw new VcsException(e);
+ }
+
+ return parseVersion(output);
+ }
+
+ private static ProcessOutput runCommand() throws ExecutionException {
+ GeneralCommandLine commandLine = new GeneralCommandLine();
+ commandLine.setExePath(SvnApplicationSettings.getInstance().getCommandLinePath());
+ commandLine.addParameter(SvnCommandName.version.getName());
+ commandLine.addParameter("--quiet");
+
+ CapturingProcessHandler handler = new CapturingProcessHandler(commandLine.createProcess(), CharsetToolkit.getDefaultSystemCharset());
+ return handler.runProcess(30 * 1000);
+ }
+
+ @NotNull
+ private static Version parseVersion(@NotNull ProcessOutput output) throws VcsException {
+ if (output.isTimeout() || (output.getExitCode() != 0) || !output.getStderr().isEmpty()) {
+ throw new VcsException(
+ String.format("Exit code: %d, Error: %s, Timeout: %b", output.getExitCode(), output.getStderr(), output.isTimeout()));
+ }
+
+ return parseVersion(output.getStdout());
+ }
+
+ @NotNull
+ private static Version parseVersion(@NotNull String versionText) throws VcsException {
+ Version result = null;
+ Exception cause = null;
+ String[] parts = versionText.trim().split("\\.");
+
+ if (parts.length == 3) {
+ try {
+ result = new Version(getInt(parts[0]), getInt(parts[1]), getInt(parts[2]));
+ }
+ catch (NumberFormatException e) {
+ cause = e;
+ }
+ }
+
+ if (cause != null || result == null) {
+ throw new VcsException(String.format("Could not parse svn version: %s", versionText), cause);
+ }
+
+ return result;
+ }
+
+ private static int getInt(@NotNull String value) {
+ return Integer.parseInt(value);
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java
index c11226a..002820d 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java
@@ -5,7 +5,9 @@
import org.jetbrains.idea.svn.add.SvnKitAddClient;
import org.jetbrains.idea.svn.annotate.SvnKitAnnotateClient;
import org.jetbrains.idea.svn.change.SvnKitChangeListClient;
+import org.jetbrains.idea.svn.checkin.SvnKitImportClient;
import org.jetbrains.idea.svn.checkout.SvnKitCheckoutClient;
+import org.jetbrains.idea.svn.checkout.SvnKitExportClient;
import org.jetbrains.idea.svn.cleanup.SvnKitCleanupClient;
import org.jetbrains.idea.svn.conflict.SvnKitConflictClient;
import org.jetbrains.idea.svn.content.SvnKitContentClient;
@@ -14,8 +16,8 @@
import org.jetbrains.idea.svn.history.SvnKitHistoryClient;
import org.jetbrains.idea.svn.integrate.SvnKitMergeClient;
import org.jetbrains.idea.svn.lock.SvnKitLockClient;
-import org.jetbrains.idea.svn.portable.SvnSvnkitUpdateClient;
-import org.jetbrains.idea.svn.portable.SvnUpdateClientI;
+import org.jetbrains.idea.svn.update.SvnKitUpdateClient;
+import org.jetbrains.idea.svn.update.UpdateClient;
import org.jetbrains.idea.svn.portable.SvnkitSvnStatusClient;
import org.jetbrains.idea.svn.portable.SvnkitSvnWcClient;
import org.jetbrains.idea.svn.properties.SvnKitPropertyClient;
@@ -48,13 +50,16 @@
myLockClient = new SvnKitLockClient();
myCleanupClient = new SvnKitCleanupClient();
myRelocateClient = new SvnKitRelocateClient();
- statusClient = new SvnkitSvnStatusClient(myVcs.createStatusClient());
+ myVersionClient = new SvnKitVersionClient();
+ myImportClient = new SvnKitImportClient();
+ myExportClient = new SvnKitExportClient();
+ statusClient = new SvnkitSvnStatusClient(myVcs, null);
infoClient = new SvnkitSvnWcClient(myVcs);
}
@NotNull
@Override
- public SvnUpdateClientI createUpdateClient() {
- return new SvnSvnkitUpdateClient(myVcs.createUpdateClient());
+ public UpdateClient createUpdateClient() {
+ return prepare(new SvnKitUpdateClient());
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitVersionClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitVersionClient.java
new file mode 100644
index 0000000..084f7f7
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitVersionClient.java
@@ -0,0 +1,18 @@
+package org.jetbrains.idea.svn.api;
+
+import com.intellij.openapi.util.Version;
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.WorkingCopyFormat;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitVersionClient extends BaseSvnClient implements VersionClient {
+
+ @NotNull
+ @Override
+ public Version getVersion() throws VcsException {
+ return WorkingCopyFormat.ONE_DOT_SEVEN.getVersion();
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/VersionClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/VersionClient.java
new file mode 100644
index 0000000..bbd7092
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/VersionClient.java
@@ -0,0 +1,14 @@
+package org.jetbrains.idea.svn.api;
+
+import com.intellij.openapi.util.Version;
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface VersionClient extends SvnClient {
+
+ @NotNull
+ Version getVersion() throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/CmdImportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/CmdImportClient.java
new file mode 100644
index 0000000..d6cb894
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/CmdImportClient.java
@@ -0,0 +1,51 @@
+package org.jetbrains.idea.svn.checkin;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.CommitEventHandler;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.jetbrains.idea.svn.commandLine.SvnCommitRunner;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.wc.ISVNCommitHandler;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdImportClient extends BaseSvnClient implements ImportClient {
+
+ @Override
+ public long doImport(@NotNull File path,
+ @NotNull SVNURL url,
+ @Nullable SVNDepth depth,
+ @NotNull String message,
+ boolean noIgnore,
+ @Nullable CommitEventHandler handler,
+ @Nullable ISVNCommitHandler commitHandler) throws VcsException {
+ // TODO: ISVNFileFilter from ISVNCommitHandler is not currently implemented
+
+ List<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, path, false);
+ CommandUtil.put(parameters, SvnTarget.fromURL(url), false);
+ CommandUtil.put(parameters, depth);
+ CommandUtil.put(parameters, noIgnore, "--no-ignore");
+ parameters.add("--message");
+ parameters.add(message);
+
+ SvnCommitRunner.CommandListener listener = new SvnCommitRunner.CommandListener(handler);
+ listener.setBaseDirectory(path);
+
+ CommandUtil.execute(myVcs, SvnTarget.fromURL(url), SvnCommandName.importFolder, parameters, listener);
+
+ return listener.getCommittedRevision();
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java
index 7c68e86..8a4b203 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java
@@ -94,6 +94,8 @@
result = CommitEventType.replacing;
} else if (SVNEventAction.COMMIT_DELTA_SENT.equals(action)) {
result = CommitEventType.transmittingDeltas;
+ } else if (SVNEventAction.SKIP.equals(action)) {
+ result = CommitEventType.skipped;
}
if (result == null) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/ImportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/ImportClient.java
new file mode 100644
index 0000000..2a8a549
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/ImportClient.java
@@ -0,0 +1,26 @@
+package org.jetbrains.idea.svn.checkin;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.jetbrains.idea.svn.commandLine.CommitEventHandler;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.wc.ISVNCommitHandler;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface ImportClient extends SvnClient {
+
+ long doImport(@NotNull File path,
+ @NotNull SVNURL url,
+ @Nullable SVNDepth depth,
+ @NotNull String message,
+ boolean noIgnore,
+ @Nullable CommitEventHandler handler,
+ @Nullable ISVNCommitHandler commitHandler) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java
index 8e2e10d8..c1f3ede 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java
@@ -178,7 +178,7 @@
return;
}
if (WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) || WorkingCopyFormat.ONE_DOT_SEVEN.equals(format) &&
- SvnConfiguration.UseAcceleration.commandLine.equals(SvnConfiguration.getInstance(mySvnVcs.getProject()).myUseAcceleration) &&
+ SvnConfiguration.getInstance(mySvnVcs.getProject()).isCommandLine() &&
(SvnAuthenticationManager.HTTP.equals(url.getProtocol()) || SvnAuthenticationManager.HTTPS.equals(url.getProtocol()))) {
doWithCommandLine(committables, comment, exception, feedback);
return;
@@ -282,7 +282,7 @@
if (! childrenOfSomebody.isEmpty()) {
final HashSet<File> result = new HashSet<File>(committables);
result.removeAll(childrenOfSomebody);
- final SvnCommandLineStatusClient statusClient = new SvnCommandLineStatusClient(mySvnVcs.getProject());
+ final SvnCommandLineStatusClient statusClient = new SvnCommandLineStatusClient(mySvnVcs);
for (File file : childrenOfSomebody) {
try {
final SVNStatus status = statusClient.doStatus(file, false);
@@ -385,7 +385,7 @@
}
private SVNStatus getStatusCommandLine(File file) throws SVNException {
- return new SvnCommandLineStatusClient(mySvnVcs.getProject()).doStatus(file, false);
+ return new SvnCommandLineStatusClient(mySvnVcs).doStatus(file, false);
}
private static List<File> collectPaths(final List<Change> changes) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnKitImportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnKitImportClient.java
new file mode 100644
index 0000000..838e764
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnKitImportClient.java
@@ -0,0 +1,44 @@
+package org.jetbrains.idea.svn.checkin;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommitEventHandler;
+import org.jetbrains.idea.svn.commandLine.SvnBindException;
+import org.tmatesoft.svn.core.SVNCommitInfo;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.wc.ISVNCommitHandler;
+import org.tmatesoft.svn.core.wc.SVNCommitClient;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitImportClient extends BaseSvnClient implements ImportClient {
+
+ @Override
+ public long doImport(@NotNull File path,
+ @NotNull SVNURL url,
+ @Nullable SVNDepth depth,
+ @NotNull String message,
+ boolean noIgnore,
+ @Nullable CommitEventHandler handler,
+ @Nullable ISVNCommitHandler commitHandler) throws VcsException {
+ SVNCommitClient client = myVcs.createCommitClient();
+
+ client.setEventHandler(handler);
+ client.setCommitHandler(commitHandler);
+
+ try {
+ SVNCommitInfo info = client.doImport(path, url, message, null, !noIgnore, false, depth);
+ return info.getNewRevision();
+ }
+ catch (SVNException e) {
+ throw new SvnBindException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutEventHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutEventHandler.java
index 3650696..88f2a69 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutEventHandler.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutEventHandler.java
@@ -19,6 +19,8 @@
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.StatusBar;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
@@ -30,13 +32,13 @@
import org.tmatesoft.svn.core.wc.SVNEventAction;
public class CheckoutEventHandler implements ISVNEventHandler {
- private final ProgressIndicator myIndicator;
+ @Nullable private final ProgressIndicator myIndicator;
private int myExternalsCount;
- private final SvnVcs myVCS;
+ @NotNull private final SvnVcs myVCS;
private final boolean myIsExport;
private int myCnt;
- public CheckoutEventHandler(SvnVcs vcs, boolean isExport, ProgressIndicator indicator) {
+ public CheckoutEventHandler(@NotNull SvnVcs vcs, boolean isExport, @Nullable ProgressIndicator indicator) {
myIndicator = indicator;
myVCS = vcs;
myExternalsCount = 1;
@@ -51,16 +53,17 @@
}
if (event.getAction() == SVNEventAction.UPDATE_EXTERNAL) {
myExternalsCount++;
- ProgressManager.progress(SvnBundle.message("progress.text2.fetching.external.location", event.getFile().getAbsolutePath()), "");
+ progress(SvnBundle.message("progress.text2.fetching.external.location", event.getFile().getAbsolutePath()));
}
else if (event.getAction() == SVNEventAction.UPDATE_ADD) {
- ProgressManager.progress2(SvnBundle.message(myIsExport ? "progress.text2.exported" : "progress.text2.checked.out", event.getFile().getName(), myCnt));
+ progress2(SvnBundle.message(myIsExport ? "progress.text2.exported" : "progress.text2.checked.out", event.getFile().getName(), myCnt));
++ myCnt;
}
else if (event.getAction() == SVNEventAction.UPDATE_COMPLETED) {
myExternalsCount--;
- ProgressManager.progress2((SvnBundle.message(myIsExport ? "progress.text2.exported.revision" : "progress.text2.checked.out.revision", event.getRevision())));
- if (myExternalsCount == 0 && event.getRevision() >= 0 && myVCS != null) {
+ progress2(
+ (SvnBundle.message(myIsExport ? "progress.text2.exported.revision" : "progress.text2.checked.out.revision", event.getRevision())));
+ if (myExternalsCount == 0 && event.getRevision() >= 0) {
myExternalsCount = 1;
Project project = myVCS.getProject();
if (project != null) {
@@ -68,9 +71,9 @@
}
}
} else if (event.getAction() == SVNEventAction.COMMIT_ADDED) {
- ProgressManager.progress2((SvnBundle.message("progress.text2.adding", path)));
+ progress2((SvnBundle.message("progress.text2.adding", path)));
} else if (event.getAction() == SVNEventAction.COMMIT_DELTA_SENT) {
- ProgressManager.progress2((SvnBundle.message("progress.text2.transmitting.delta", path)));
+ progress2((SvnBundle.message("progress.text2.transmitting.delta", path)));
}
}
@@ -79,4 +82,23 @@
throw new SVNCancelException(SVNErrorMessage.create(SVNErrorCode.CANCELLED, "Operation cancelled"));
}
}
+
+ private void progress(@NotNull String text) {
+ if (myIndicator != null) {
+ myIndicator.checkCanceled();
+ myIndicator.setText(text);
+ myIndicator.setText2("");
+ } else {
+ ProgressManager.progress(text);
+ }
+ }
+
+ private void progress2(@NotNull String text) {
+ if (myIndicator != null) {
+ myIndicator.checkCanceled();
+ myIndicator.setText2(text);
+ } else {
+ ProgressManager.progress2(text);
+ }
+ }
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CmdExportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CmdExportClient.java
new file mode 100644
index 0000000..6bff70f
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CmdExportClient.java
@@ -0,0 +1,53 @@
+package org.jetbrains.idea.svn.checkout;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.BaseUpdateCommandListener;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdExportClient extends BaseSvnClient implements ExportClient {
+
+ @Override
+ public void export(@NotNull SvnTarget from,
+ @NotNull File to,
+ @Nullable SVNRevision revision,
+ @Nullable SVNDepth depth,
+ @Nullable String nativeLineEnd,
+ boolean force,
+ boolean ignoreExternals,
+ @Nullable ISVNEventHandler handler) throws VcsException {
+ List<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, from);
+ CommandUtil.put(parameters, to);
+ CommandUtil.put(parameters, revision);
+ CommandUtil.put(parameters, depth);
+ CommandUtil.put(parameters, force, "--force");
+ CommandUtil.put(parameters, ignoreExternals, "--ignore-externals");
+ if (!StringUtil.isEmpty(nativeLineEnd)) {
+ parameters.add("--native-eol");
+ parameters.add(nativeLineEnd);
+ }
+
+ BaseUpdateCommandListener listener = new BaseUpdateCommandListener(to, handler);
+
+ CommandUtil.execute(myVcs, from, to, SvnCommandName.export, parameters, listener);
+
+ listener.throwWrappedIfException();
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/ExportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/ExportClient.java
new file mode 100644
index 0000000..6ddd6de
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/ExportClient.java
@@ -0,0 +1,27 @@
+package org.jetbrains.idea.svn.checkout;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface ExportClient extends SvnClient {
+
+ void export(@NotNull SvnTarget from,
+ @NotNull File to,
+ @Nullable SVNRevision revision,
+ @Nullable SVNDepth depth,
+ @Nullable String nativeLineEnd,
+ boolean force,
+ boolean ignoreExternals,
+ @Nullable ISVNEventHandler handler) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java
index 7b0ed8c..ff415a0 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java
@@ -33,11 +33,14 @@
import com.intellij.openapi.vcs.update.RefreshVFsSynchronously;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.StatusBar;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
import org.jetbrains.idea.svn.actions.ExclusiveBackgroundVcsAction;
import org.jetbrains.idea.svn.actions.SvnExcludingIgnoredOperation;
+import org.jetbrains.idea.svn.checkin.IdeaCommitHandler;
+import org.jetbrains.idea.svn.commandLine.CommitEventHandler;
import org.jetbrains.idea.svn.dialogs.CheckoutDialog;
import org.tmatesoft.svn.core.SVNCancelException;
import org.tmatesoft.svn.core.SVNDepth;
@@ -62,13 +65,11 @@
target.mkdirs();
}
- final String selectedFormat = promptForWCopyFormat(target, project);
- if (selectedFormat == null) {
- // cancelled
- return;
+ final WorkingCopyFormat selectedFormat = promptForWCopyFormat(target, project);
+ // UNKNOWN here means operation was cancelled
+ if (selectedFormat != WorkingCopyFormat.UNKNOWN) {
+ checkout(project, target, url, revision, depth, ignoreExternals, listener, selectedFormat);
}
-
- checkout(project, target, url, revision, depth, ignoreExternals, listener, WorkingCopyFormat.getInstance(selectedFormat));
}
public static void checkout(final Project project,
@@ -168,52 +169,50 @@
}
public static boolean promptForWCFormatAndSelect(final File target, final Project project) {
- final String result = promptForWCopyFormat(target, project);
- if (result != null) {
- SvnWorkingCopyFormatHolder.setPresetFormat(WorkingCopyFormat.getInstance(result));
+ final WorkingCopyFormat result = promptForWCopyFormat(target, project);
+ if (result != WorkingCopyFormat.UNKNOWN) {
+ SvnWorkingCopyFormatHolder.setPresetFormat(result);
}
- return result != null;
+ return result != WorkingCopyFormat.UNKNOWN;
}
- @Nullable
- private static String promptForWCopyFormat(final File target, final Project project) {
- String formatMode = null;
+ @NotNull
+ private static WorkingCopyFormat promptForWCopyFormat(final File target, final Project project) {
+ WorkingCopyFormat format = WorkingCopyFormat.UNKNOWN;
final Ref<Boolean> wasOk = new Ref<Boolean>();
- while ((formatMode == null) && (! Boolean.FALSE.equals(wasOk.get()))) {
- formatMode = SvnFormatSelector.showUpgradeDialog(target, project, true, SvnConfiguration.UPGRADE_AUTO_17, wasOk);
+ while ((format == WorkingCopyFormat.UNKNOWN) && (! Boolean.FALSE.equals(wasOk.get()))) {
+ format = SvnFormatSelector.showUpgradeDialog(target, project, true, WorkingCopyFormat.ONE_DOT_SEVEN, wasOk);
}
- return Boolean.TRUE.equals(wasOk.get()) ? formatMode : null;
+ return Boolean.TRUE.equals(wasOk.get()) ? format : WorkingCopyFormat.UNKNOWN;
}
- public static void doExport(final Project project, final File target, final String url, final SVNDepth depth,
+ public static void doExport(final Project project, final File target, final SVNURL url, final SVNDepth depth,
final boolean ignoreExternals, final boolean force, final String eolStyle) {
try {
- final SVNException[] exception = new SVNException[1];
- final SVNUpdateClient client = SvnVcs.getInstance(project).createUpdateClient();
+ final VcsException[] exception = new VcsException[1];
+ final SvnVcs vcs = SvnVcs.getInstance(project);
ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
public void run() {
ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
- client.setEventHandler(new CheckoutEventHandler(SvnVcs.getInstance(project), true, progressIndicator));
- client.setIgnoreExternals(ignoreExternals);
+ ISVNEventHandler handler = new CheckoutEventHandler(vcs, true, progressIndicator);
try {
progressIndicator.setText(SvnBundle.message("progress.text.export", target.getAbsolutePath()));
- client.doExport(SVNURL.parseURIEncoded(url), target, SVNRevision.UNDEFINED, SVNRevision.HEAD, eolStyle, force, depth);
+
+ SvnTarget from = SvnTarget.fromURL(url);
+ ExportClient client = vcs.getFactoryFromSettings().createExportClient();
+ client.export(from, target, SVNRevision.HEAD, depth, eolStyle, force, ignoreExternals, handler);
}
- catch (SVNException e) {
+ catch (VcsException e) {
exception[0] = e;
}
- finally {
- client.setIgnoreExternals(false);
- client.setEventHandler(null);
- }
}
}, SvnBundle.message("message.title.export"), true, project);
if (exception[0] != null) {
throw exception[0];
}
}
- catch (SVNException e1) {
+ catch (VcsException e1) {
Messages.showErrorDialog(SvnBundle.message("message.text.cannot.export", e1.getMessage()), SvnBundle.message("message.title.export"));
}
}
@@ -221,7 +220,7 @@
public static void doImport(final Project project, final File target, final SVNURL url, final SVNDepth depth,
final boolean includeIgnored, final String message) {
final Ref<String> errorMessage = new Ref<String>();
- final SVNCommitClient client = SvnVcs.getInstance(project).createCommitClient();
+ final SvnVcs vcs = SvnVcs.getInstance(project);
final String targetPath = FileUtil.toSystemIndependentName(target.getAbsolutePath());
ExclusiveBackgroundVcsAction.run(project, new Runnable() {
@@ -230,7 +229,6 @@
public void run() {
final FileIndexFacade facade = PeriodicalTasksCloser.getInstance().safeGetService(project, FileIndexFacade.class);
ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
- client.setEventHandler(new CheckoutEventHandler(SvnVcs.getInstance(project), true, progressIndicator));
try {
progressIndicator.setText(SvnBundle.message("progress.text.import", target.getAbsolutePath()));
@@ -244,22 +242,21 @@
return facade.isInContent(targetVf);
}
});
- if (project.isDefault() || !isInContent) {
- // do not pay attention to ignored/excluded settings
- client.doImport(target, url, message, null, !includeIgnored, false, depth);
- } else {
- client.setCommitHandler(new MyFilter(LocalFileSystem.getInstance(), new SvnExcludingIgnoredOperation.Filter(project)));
- client.doImport(target, url, message, null, !includeIgnored, false, depth);
+ CommitEventHandler handler = new IdeaCommitHandler(progressIndicator);
+ boolean useFileFilter = !project.isDefault() && isInContent;
+ ISVNCommitHandler commitHandler =
+ useFileFilter ? new MyFilter(LocalFileSystem.getInstance(), new SvnExcludingIgnoredOperation.Filter(project)) : null;
+ long revision = vcs.getFactoryFromSettings().createImportClient()
+ .doImport(target, url, depth, message, includeIgnored, handler, commitHandler);
+
+ if (revision > 0) {
+ StatusBar.Info.set(SvnBundle.message("status.text.comitted.revision", revision), project);
}
}
}
- catch (SVNException e) {
+ catch (VcsException e) {
errorMessage.set(e.getMessage());
}
- finally {
- client.setIgnoreExternals(false);
- client.setEventHandler(null);
- }
}
}, SvnBundle.message("message.title.import"), true, project);
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnKitExportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnKitExportClient.java
new file mode 100644
index 0000000..f04c749
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnKitExportClient.java
@@ -0,0 +1,48 @@
+package org.jetbrains.idea.svn.checkout;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.SvnBindException;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc.SVNUpdateClient;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitExportClient extends BaseSvnClient implements ExportClient {
+
+ @Override
+ public void export(@NotNull SvnTarget from,
+ @NotNull File to,
+ @Nullable SVNRevision revision,
+ @Nullable SVNDepth depth,
+ @Nullable String nativeLineEnd,
+ boolean force,
+ boolean ignoreExternals,
+ @Nullable ISVNEventHandler handler) throws VcsException {
+ SVNUpdateClient client = myVcs.createUpdateClient();
+
+ client.setEventHandler(handler);
+ client.setIgnoreExternals(ignoreExternals);
+
+ try {
+ if (from.isFile()) {
+ client.doExport(from.getFile(), to, from.getPegRevision(), revision, nativeLineEnd, force, depth);
+ }
+ else {
+ client.doExport(from.getURL(), to, from.getPegRevision(), revision, nativeLineEnd, force, depth);
+ }
+ }
+ catch (SVNException e) {
+ throw new SvnBindException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java
index 393cccc..0279eba 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java
@@ -103,9 +103,18 @@
}
public static void put(@NotNull List<String> parameters, @Nullable SVNDepth depth) {
+ put(parameters, depth, false);
+ }
+
+ public static void put(@NotNull List<String> parameters, @Nullable SVNDepth depth, boolean sticky) {
if (depth != null && !SVNDepth.UNKNOWN.equals(depth)) {
parameters.add("--depth");
parameters.add(depth.getName());
+
+ if (sticky) {
+ parameters.add("--set-depth");
+ parameters.add(depth.getName());
+ }
}
}
@@ -148,6 +157,16 @@
}
}
+ public static String escape(@NotNull String path) {
+ String result = path;
+
+ if (path.contains("@")) {
+ result += "@";
+ }
+
+ return result;
+ }
+
public static <T> T parse(@NotNull String data, @NotNull Class<T> type) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(type);
Unmarshaller unmarshaller = context.createUnmarshaller();
@@ -171,8 +190,18 @@
@NotNull SvnCommandName name,
@NotNull List<String> parameters,
@Nullable LineCommandListener listener) throws VcsException {
- SVNURL repositoryUrl = resolveRepositoryUrl(vcs, name, target);
File workingDirectory = resolveWorkingDirectory(vcs, target);
+
+ return execute(vcs, target, workingDirectory, name, parameters, listener);
+ }
+
+ public static SvnCommand execute(@NotNull SvnVcs vcs,
+ @NotNull SvnTarget target,
+ @NotNull File workingDirectory,
+ @NotNull SvnCommandName name,
+ @NotNull List<String> parameters,
+ @Nullable LineCommandListener listener) throws VcsException {
+ SVNURL repositoryUrl = resolveRepositoryUrl(vcs, name, target);
IdeaSvnkitBasedAuthenticationCallback callback = new IdeaSvnkitBasedAuthenticationCallback(vcs);
return SvnLineCommand.runWithAuthenticationAttempt(workingDirectory, repositoryUrl, name,
@@ -180,6 +209,11 @@
ArrayUtil.toStringArray(parameters));
}
+ @NotNull
+ public static File getHomeDirectory() {
+ return new File(PathManager.getHomePath());
+ }
+
private static SVNURL resolveRepositoryUrl(@NotNull SvnVcs vcs, @NotNull SvnCommandName name, @NotNull SvnTarget target) {
RootUrlInfo rootInfo = target.isFile()
? vcs.getSvnFileUrlMapping().getWcRootForFilePath(target.getFile())
@@ -204,7 +238,7 @@
if (workingDirectory == null) {
workingDirectory =
- !vcs.getProject().isDefault() ? VfsUtilCore.virtualToIoFile(vcs.getProject().getBaseDir()) : new File(PathManager.getHomePath());
+ !vcs.getProject().isDefault() ? VfsUtilCore.virtualToIoFile(vcs.getProject().getBaseDir()) : getHomeDirectory();
}
return workingDirectory;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java
index 87dc212..f0c6df7 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java
@@ -27,7 +27,8 @@
sending("Sending"),
replacing("Replacing"),
transmittingDeltas("Transmitting file data"),
- committedRevision("Committed revision");
+ committedRevision("Committed revision"),
+ skipped("Skipped");
private final String myText;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java
index 766d95a..0e93b54 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java
@@ -56,12 +56,11 @@
private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.commandLine.SvnCommandLineInfoClient");
- @NotNull
- private final Project myProject;
+ @NotNull private final SvnVcs myVcs;
- public SvnCommandLineInfoClient(@NotNull final Project project) {
- super(SvnVcs.getInstance(project));
- myProject = project;
+ public SvnCommandLineInfoClient(@NotNull final SvnVcs vcs) {
+ super(vcs);
+ myVcs = vcs;
}
@Override
@@ -118,8 +117,7 @@
};
try {
- SvnCommand command =
- CommandUtil.execute(SvnVcs.getInstance(myProject), SvnTarget.fromFile(path), SvnCommandName.info, parameters, listener);
+ SvnCommand command = CommandUtil.execute(myVcs, SvnTarget.fromFile(path), SvnCommandName.info, parameters, listener);
return command.getOutput();
}
@@ -217,7 +215,7 @@
fillParameters(path, pegRevision, revision, depth, parameters);
SvnCommand command;
try {
- command = CommandUtil.execute(SvnVcs.getInstance(myProject), SvnTarget.fromURL(url), SvnCommandName.info, parameters, null);
+ command = CommandUtil.execute(myVcs, SvnTarget.fromURL(url), SvnCommandName.info, parameters, null);
}
catch (VcsException e) {
throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java
index 1cdf15f..14c701b 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java
@@ -16,7 +16,6 @@
package org.jetbrains.idea.svn.commandLine;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Getter;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -53,12 +52,12 @@
public class SvnCommandLineStatusClient implements SvnStatusClientI {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient");
- private final Project myProject;
private final SvnCommandLineInfoClient myInfoClient;
+ @NotNull private final SvnVcs myVcs;
- public SvnCommandLineStatusClient(Project project) {
- myProject = project;
- myInfoClient = new SvnCommandLineInfoClient(project);
+ public SvnCommandLineStatusClient(@NotNull SvnVcs vcs) {
+ myVcs = vcs;
+ myInfoClient = new SvnCommandLineInfoClient(vcs);
}
@Override
@@ -111,7 +110,7 @@
SvnCommand command;
try {
- command = CommandUtil.execute(SvnVcs.getInstance(myProject), SvnTarget.fromFile(path), SvnCommandName.st, parameters, null);
+ command = CommandUtil.execute(myVcs, SvnTarget.fromFile(path), SvnCommandName.st, parameters, null);
}
catch (VcsException e) {
throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
@@ -139,7 +138,7 @@
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse(new ByteArrayInputStream(result.getBytes(CharsetToolkit.UTF8_CHARSET)), svnHandl[0]);
if (!svnHandl[0].isAnythingReported()) {
- if (!SvnUtil.isSvnVersioned(myProject, path)) {
+ if (!SvnUtil.isSvnVersioned(myVcs, path)) {
throw new SVNException(
SVNErrorMessage.create(SVNErrorCode.WC_NOT_DIRECTORY, "Command - " + command.getCommandText() + ". Result - " + result));
} else {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java
deleted file mode 100644
index 06901ea..0000000
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.idea.svn.commandLine;
-
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vcs.VcsException;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.idea.svn.SvnVcs;
-import org.jetbrains.idea.svn.portable.SvnSvnkitUpdateClient;
-import org.tmatesoft.svn.core.*;
-import org.tmatesoft.svn.core.wc.*;
-import org.tmatesoft.svn.core.wc2.SvnTarget;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/1/12
- * Time: 12:13 PM
- */
-public class SvnCommandLineUpdateClient extends SvnSvnkitUpdateClient {
- private static final Pattern ourExceptionPattern = Pattern.compile("svn: E(\\d{6}): .+");
- private static final String ourAuthenticationRealm = "Authentication realm:";
- private final Project myProject;
- private final VirtualFile myCommonAncestor;
- private boolean myIgnoreExternals;
- private SvnVcs myVcs;
-
- public SvnCommandLineUpdateClient(final SvnVcs vcs, VirtualFile commonAncestor) {
- super(vcs.createUpdateClient());
- myVcs = vcs;
- myProject = vcs.getProject();
- myCommonAncestor = commonAncestor;
- }
-
- @Override
- public long doUpdate(File file, SVNRevision revision, boolean recursive) throws SVNException {
- final long[] longs = doUpdate(new File[]{file}, revision, SVNDepth.fromRecurse(recursive), false, false, false);
- return longs[0];
- }
-
- @Override
- public long doUpdate(File file, SVNRevision revision, boolean recursive, boolean force) throws SVNException {
- final long[] longs = doUpdate(new File[]{file}, revision, SVNDepth.fromRecurse(recursive), force, false, false);
- return longs[0];
- }
-
- @Override
- public long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky)
- throws SVNException {
- return doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, false);
- }
-
- @Override
- public long[] doUpdate(final File[] paths, final SVNRevision revision, final SVNDepth depth, final boolean allowUnversionedObstructions,
- final boolean depthIsSticky, final boolean makeParents) throws SVNException {
- // since one revision is passed -> I assume same repository here
- final SvnCommandLineInfoClient infoClient = new SvnCommandLineInfoClient(myProject);
- final SVNInfo info = infoClient.doInfo(paths[0], SVNRevision.UNDEFINED);
- if (info == null || info.getURL() == null) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_WORKING_COPY, paths[0].getPath()));
- }
- final AtomicReference<long[]> updatedToRevision = new AtomicReference<long[]>();
- updatedToRevision.set(new long[0]);
-
- File base = myCommonAncestor == null ? paths[0] : new File(myCommonAncestor.getPath());
- base = base.isDirectory() ? base : base.getParentFile();
-
- final List<String> parameters = prepareParameters(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, makeParents);
- final BaseUpdateCommandListener listener = createCommandListener(paths, updatedToRevision, base);
- try {
- CommandUtil.execute(myVcs, SvnTarget.fromFile(base), SvnCommandName.up, parameters, listener);
- }
- catch (VcsException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e));
- }
-
- listener.throwIfException();
-
- return updatedToRevision.get();
- }
-
- private BaseUpdateCommandListener createCommandListener(final File[] paths,
- final AtomicReference<long[]> updatedToRevision,
- final File base) {
- return new BaseUpdateCommandListener(base, getEventHandler()) {
- final long[] myRevisions = new long[paths.length];
-
- @Override
- protected void beforeHandler(@NotNull SVNEvent event) {
- if (SVNEventAction.UPDATE_COMPLETED.equals(event.getAction())) {
- final long eventRevision = event.getRevision();
- for (int i = 0; i < paths.length; i++) {
- final File path = paths[i];
- if (FileUtil.filesEqual(path, event.getFile())) {
- myRevisions[i] = eventRevision;
- break;
- }
- }
- }
- }
-
- @Override
- public void processTerminated(int exitCode) {
- super.processTerminated(exitCode);
- updatedToRevision.set(myRevisions);
- }
- };
- }
-
- private List<String> prepareParameters(File[] paths,
- SVNRevision revision,
- SVNDepth depth,
- boolean allowUnversionedObstructions,
- boolean depthIsSticky, boolean makeParents) {
- List<String> parameters = new ArrayList<String>();
-
- CommandUtil.put(parameters, revision);
- CommandUtil.put(parameters, depth);
- CommandUtil.put(parameters, allowUnversionedObstructions, "--force");
- if (depthIsSticky && depth != null) {// !!! not sure, but not used
- parameters.add("--set-depth");
- parameters.add(depth.toString());
- }
- CommandUtil.put(parameters, makeParents, "--parents");
- CommandUtil.put(parameters, myIgnoreExternals, "--ignore-externals");
- parameters.add("--accept");
- parameters.add("postpone");
- CommandUtil.put(parameters, paths);
-
- return parameters;
- }
-
-
- private void checkForException(final StringBuffer sbError) throws SVNException {
- if (sbError.length() == 0) return;
- final String message = sbError.toString();
- final Matcher matcher = ourExceptionPattern.matcher(message);
- if (matcher.matches()) {
- final String group = matcher.group(1);
- if (group != null) {
- try {
- final int code = Integer.parseInt(group);
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.getErrorCode(code), message));
- } catch (NumberFormatException e) {
- //
- }
- }
- }
- if (message.contains(ourAuthenticationRealm)) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.AUTHN_CREDS_UNAVAILABLE, message));
- }
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.UNKNOWN, message));
- }
-
- @Override
- public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky)
- throws SVNException {
- final long[] longs = doUpdate(new File[]{path}, revision, depth, allowUnversionedObstructions, depthIsSticky, false);
- return longs[0];
- }
-
- @Override
- public long doSwitch(File file, SVNURL url, SVNRevision revision, boolean recursive) throws SVNException {
- throw new UnsupportedOperationException();
- //return super.doSwitch(file, url, revision, recursive);
- }
-
- @Override
- public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException {
- throw new UnsupportedOperationException();
- //return super.doSwitch(file, url, pegRevision, revision, recursive);
- }
-
- @Override
- public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force)
- throws SVNException {
- throw new UnsupportedOperationException();
- //return super.doSwitch(file, url, pegRevision, revision, recursive, force);
- }
-
- @Override
- public long doSwitch(File path,
- SVNURL url,
- SVNRevision pegRevision,
- SVNRevision revision,
- SVNDepth depth,
- boolean allowUnversionedObstructions,
- boolean depthIsSticky) throws SVNException {
- throw new UnsupportedOperationException();
- //return super.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky);
- }
-
- @Override
- public long doSwitch(File path,
- SVNURL url,
- SVNRevision pegRevision,
- SVNRevision revision,
- SVNDepth depth,
- boolean allowUnversionedObstructions,
- boolean depthIsSticky,
- boolean ignoreAncestry) throws SVNException {
- throw new UnsupportedOperationException();
- // todo MAIN
- //return super.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky, ignoreAncestry);
- }
-
- @Override
- public void setIgnoreExternals(boolean ignoreExternals) {
- myIgnoreExternals = ignoreExternals;
- }
-}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java
index 72fd465..9182d937 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java
@@ -26,6 +26,7 @@
info("info", false),
st("st", false),
up("up", true),
+ switchCopy("switch", true),
relocate("relocate", true),
ci("commit", true),
checkout("checkout", true),
@@ -46,7 +47,9 @@
merge("merge", true),
changelist("changelist", true),
lock("lock", true),
- unlock("unlock", true);
+ unlock("unlock", true),
+ importFolder("import", false),
+ export("export", false);
private final String myName;
private final boolean myWriteable;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java
index 1f93976..cf13f126 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java
@@ -29,6 +29,8 @@
import java.io.File;
import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Created with IntelliJ IDEA.
@@ -94,6 +96,14 @@
}
public static class CommandListener extends LineCommandListener {
+
+ // Status could contain spaces, like "Adding copy of <path>". But at the end we are not interested in "copy of" part and want to have
+ // only "Adding" in match group.
+ private static final String STATUS = "\\s*(\\w+)(.*?)\\s\\s+";
+ private static final String OPTIONAL_FILE_TYPE = "(\\(.*\\))?";
+ private static final String PATH = "\\s*(.*?)\\s*";
+ private static final Pattern CHANGED_PATH = Pattern.compile(STATUS + OPTIONAL_FILE_TYPE + PATH);
+
@Nullable private final CommitEventHandler myHandler;
private SvnBindException myException;
private long myCommittedRevision = Revision.SVN_INVALID_REVNUM;
@@ -138,6 +148,24 @@
}
return;
}
+ if (line.startsWith(CommitEventType.skipped.getText())) {
+ File target = null;
+ if (myHandler != null) {
+ int pathStart = line.indexOf('\'');
+ if (pathStart > -1) {
+ int pathEnd = line.indexOf('\'', pathStart + 1);
+ if (pathEnd > -1) {
+ target = toFile(line.substring(pathStart + 1, pathEnd));
+ }
+ }
+ if (target != null) {
+ myHandler.commitEvent(CommitEventType.skipped, myBase);
+ } else {
+ LOG.info("Can not parse 'Skipped' path " + line);
+ }
+ }
+ return;
+ }
if (line.startsWith(CommitEventType.committedRevision.getText())) {
final String substring = line.substring(CommitEventType.committedRevision.getText().length());
int cnt = 0;
@@ -167,26 +195,34 @@
}
} else {
if (myHandler == null) return;
- // status and path are separated by several spaces
- final int idxSpace = line.indexOf(" ");
- if (idxSpace == -1) {
- LOG.info("Can not parse event type: " + line);
- return;
+
+ Matcher matcher = CHANGED_PATH.matcher(line);
+ if (matcher.matches()) {
+ final CommitEventType type = CommitEventType.create(matcher.group(1));
+ if (type == null) {
+ LOG.info("Can not parse event type: " + line);
+ return;
+ }
+ myHandler.commitEvent(type, toFile(matcher.group(4)));
+ } else {
+ LOG.info("Can not parse output: " + line);
}
- final CommitEventType type = CommitEventType.create(line.substring(0, idxSpace));
- if (type == null) {
- LOG.info("Can not parse event type: " + line);
- return;
- }
- File target = new File(new String(line.substring(idxSpace + 1).trim()));
- if (!target.isAbsolute()) {
- target = new File(myBase, target.getPath());
- }
- myHandler.commitEvent(type, target);
}
}
+
+ @NotNull
+ private File toFile(@NotNull String path) {
+ File result = new File(path);
+
+ if (!result.isAbsolute()) {
+ result = new File(myBase, result.getPath());
+ }
+
+ return result;
+ }
}
+
/*C:\TestProjects\sortedProjects\Subversion\local2\preRelease\mod2\src\com\test>sv
n st
D gggG
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java
index 9294f0b..34525c6 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java
@@ -16,14 +16,11 @@
package org.jetbrains.idea.svn.commandLine;
import com.intellij.execution.ExecutableValidator;
-import com.intellij.execution.configurations.GeneralCommandLine;
-import com.intellij.execution.process.CapturingProcessHandler;
-import com.intellij.execution.process.ProcessOutput;
import com.intellij.notification.Notification;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Version;
-import com.intellij.openapi.vfs.CharsetToolkit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnApplicationSettings;
@@ -41,6 +38,8 @@
*/
public class SvnExecutableChecker extends ExecutableValidator {
+ private static final Logger LOG = Logger.getInstance(SvnExecutableChecker.class);
+
public SvnExecutableChecker(Project project) {
super(project, getNotificationTitle(), getWrongPathMessage());
}
@@ -74,12 +73,13 @@
protected boolean isExecutableValid(@NotNull String executable) {
setNotificationErrorDescription(getWrongPathMessage());
- final Version version = getVersion(executable);
+ // Necessary executable path will be taken from settings while command execution
+ final Version version = getConfiguredClientVersion();
try {
return version != null && validateVersion(version);
}
catch (Throwable e) {
- // do nothing
+ LOG.info(e);
return false;
}
}
@@ -101,38 +101,19 @@
}
@Nullable
- public Version getVersion(@NotNull String executable) {
+ private Version getConfiguredClientVersion() {
Version result = null;
try {
- GeneralCommandLine commandLine = new GeneralCommandLine();
- commandLine.setExePath(executable);
- commandLine.addParameter("--version");
- commandLine.addParameter("--quiet");
-
- CapturingProcessHandler handler = new CapturingProcessHandler(commandLine.createProcess(), CharsetToolkit.getDefaultSystemCharset());
- ProcessOutput output = handler.runProcess(30 * 1000);
-
- if (!output.isTimeout() && (output.getExitCode() == 0) && output.getStderr().isEmpty()) {
- String versionText = output.getStdout().trim();
- final String[] parts = versionText.split("\\.");
-
- if (parts.length >= 3) {
- result = new Version(getInt(parts[0]), getInt(parts[1]), getInt(parts[2]));
- }
- }
+ result = getVcs().getCommandLineFactory().createVersionClient().getVersion();
}
catch (Throwable e) {
- // do nothing
+ LOG.info(e);
}
return result;
}
- private static int getInt(@NotNull String value) {
- return Integer.parseInt(value);
- }
-
private static String getWrongPathMessage() {
return SvnBundle.message("subversion.executable.notification.description");
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java
index cfd6db9..6520c62 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java
@@ -26,7 +26,9 @@
import org.tmatesoft.svn.core.wc.SVNStatusType;
import java.io.File;
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -55,12 +57,18 @@
private final static Pattern ourUpdatedToRevision = Pattern.compile(UPDATED_TO_REVISION);
private final static Pattern ourCheckedOutRevision = Pattern.compile("Checked out revision (\\d+)\\.");
+ // export from repository
+ private final static Pattern ourExportedRevision = Pattern.compile("Exported revision (\\d+)\\.");
+ // export from working copy
+ private final static Pattern ourExportComplete = Pattern.compile("Export complete\\.");
+
private final static Pattern ourExternal = Pattern.compile(EXTERNAL);
private final static Pattern ourUpdatedExternal = Pattern.compile(UPDATED_EXTERNAL);
private final static Pattern ourCheckedOutExternal = Pattern.compile("Checked out external at revision (\\d+)\\.");
private final static Pattern[] ourCompletePatterns =
- new Pattern[]{ourAtRevision, ourUpdatedToRevision, ourCheckedOutRevision, ourExternal, ourUpdatedExternal, ourCheckedOutExternal};
+ new Pattern[]{ourAtRevision, ourUpdatedToRevision, ourCheckedOutRevision, ourExportedRevision, ourExternal, ourUpdatedExternal,
+ ourCheckedOutExternal, ourExportComplete};
private final File myBase;
private File myCurrentFile;
@@ -168,6 +176,10 @@
private long matchAndGetRevision(final Pattern pattern, final String line) {
final Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
+ if (pattern == ourExportComplete) {
+ return 0;
+ }
+
final String group = matcher.group(1);
if (group == null) return -1;
try {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java
index 0cfe815..f88c8eb 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java
@@ -340,14 +340,13 @@
private void changeFormat(final WCInfo wcInfo) {
ChangeFormatDialog dialog = new ChangeFormatDialog(myProject, new File(wcInfo.getPath()), false, ! wcInfo.isIsWcRoot());
- dialog.setData(wcInfo.getFormat().getOption());
+ dialog.setData(wcInfo.getFormat());
dialog.show();
if (! dialog.isOK()) {
return;
}
- final String newMode = dialog.getUpgradeMode();
- if (! wcInfo.getFormat().getOption().equals(newMode)) {
- final WorkingCopyFormat newFormat = WorkingCopyFormat.getInstance(newMode);
+ final WorkingCopyFormat newFormat = dialog.getUpgradeMode();
+ if (!wcInfo.getFormat().equals(newFormat)) {
ApplicationManager.getApplication().saveAll();
final Task.Backgroundable task = new SvnFormatWorker(myProject, newFormat, wcInfo) {
@Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java
index ca596e9..a04f817 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java
@@ -894,7 +894,7 @@
ExportOptionsDialog dialog = new ExportOptionsDialog(p, url, dir);
dialog.show();
if (dialog.isOK()) {
- SvnCheckoutProvider.doExport(myProject, dir, url.toString(), dialog.getDepth(),
+ SvnCheckoutProvider.doExport(myProject, dir, url, dialog.getDepth(),
dialog.isIgnoreExternals(), dialog.isForce(), dialog.getEOLStyle());
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java
index f9bf6bd..cb2fcda 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java
@@ -23,16 +23,19 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnBundle;
-import org.jetbrains.idea.svn.SvnConfiguration;
+import org.jetbrains.idea.svn.WorkingCopyFormat;
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
import javax.swing.*;
import java.awt.*;
import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
public class UpgradeFormatDialog extends DialogWrapper {
- private JRadioButton myUpgradeAuto16Button;
- private JRadioButton myUpgradeAuto17Button;
+
+ private ButtonGroup formatGroup = new ButtonGroup();
+ private List<JRadioButton> formatButtons = new ArrayList<JRadioButton>();
protected File myPath;
@@ -61,11 +64,12 @@
return "svn.upgradeDialog";
}
- public void setData(final String selectedFormat) {
- if (SvnConfiguration.UPGRADE_AUTO_17.equals(selectedFormat)) {
- myUpgradeAuto17Button.setSelected(true);
- } else {
- myUpgradeAuto16Button.setSelected(true);
+ public void setData(final WorkingCopyFormat selectedFormat) {
+ for (JRadioButton button : formatButtons) {
+ if (selectedFormat == getFormat(button)) {
+ button.setSelected(true);
+ break;
+ }
}
}
@@ -101,17 +105,9 @@
panel.add(topLabel, gb);
gb.gridy += 1;
-
- myUpgradeAuto16Button = new JRadioButton(SvnBundle.message("radio.configure." + label + ".auto.16format"));
- myUpgradeAuto17Button = new JRadioButton(SvnBundle.message("radio.configure." + label + ".auto.17format"));
-
- ButtonGroup group = new ButtonGroup();
- group.add(myUpgradeAuto16Button);
- group.add(myUpgradeAuto17Button);
- panel.add(myUpgradeAuto16Button, gb);
- gb.gridy += 1;
- panel.add(myUpgradeAuto17Button, gb);
- gb.gridy += 1;
+ registerFormat(WorkingCopyFormat.ONE_DOT_SIX, label, panel, gb);
+ registerFormat(WorkingCopyFormat.ONE_DOT_SEVEN, label, panel, gb);
+ registerFormat(WorkingCopyFormat.ONE_DOT_EIGHT, label, panel, gb);
final JPanel auxiliaryPanel = getBottomAuxiliaryPanel();
if (auxiliaryPanel != null) {
@@ -122,6 +118,24 @@
return panel;
}
+ private void registerFormat(@NotNull WorkingCopyFormat format,
+ @NotNull String label,
+ @NotNull JPanel panel,
+ @NotNull GridBagConstraints gb) {
+ JRadioButton button = new JRadioButton(SvnBundle.message("radio.configure." + label + ".auto." + getKey(format) + "format"));
+ button.putClientProperty("format", format);
+
+ panel.add(button, gb);
+ gb.gridy += 1;
+
+ formatGroup.add(button);
+ formatButtons.add(button);
+ }
+
+ private static String getKey(@NotNull WorkingCopyFormat format) {
+ return String.format("%d%d", format.getVersion().major, format.getVersion().minor);
+ }
+
@Nullable
protected JPanel getBottomAuxiliaryPanel() {
return null;
@@ -135,14 +149,24 @@
return true;
}
- @Nullable
- public String getUpgradeMode() {
- if (myUpgradeAuto17Button.isSelected()) {
- return SvnConfiguration.UPGRADE_AUTO_17;
- } else if (myUpgradeAuto16Button.isSelected()) {
- return SvnConfiguration.UPGRADE_AUTO_16;
- }
- return null;
+ @NotNull
+ private static WorkingCopyFormat getFormat(@NotNull JRadioButton button) {
+ Object format = button.getClientProperty("format");
+
+ return format instanceof WorkingCopyFormat ? (WorkingCopyFormat)format : WorkingCopyFormat.UNKNOWN;
}
+ @NotNull
+ public WorkingCopyFormat getUpgradeMode() {
+ WorkingCopyFormat result = WorkingCopyFormat.UNKNOWN;
+
+ for (JRadioButton button : formatButtons) {
+ if (button.isSelected()) {
+ result = getFormat(button);
+ break;
+ }
+ }
+
+ return result;
+ }
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java
index fa11d6e..4123a6f 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java
@@ -1,10 +1,7 @@
package org.jetbrains.idea.svn.history;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
-import com.intellij.util.LineSeparator;
-import com.intellij.util.containers.hash.HashMap;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.api.BaseSvnClient;
@@ -18,23 +15,22 @@
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlValue;
import java.io.File;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
/**
* @author Konstantin Kolosovsky.
*/
public class CmdHistoryClient extends BaseSvnClient implements HistoryClient {
- private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.history.CmdHistoryClient");
-
@Override
public void doLog(@NotNull File path,
@NotNull SVNRevision startRevision,
@@ -47,10 +43,6 @@
@Nullable String[] revisionProperties,
@Nullable ISVNLogEntryHandler handler) throws VcsException {
// TODO: add revision properties parameter if necessary
- // TODO: svn log command supports --xml option - could update parsing to use xml format
-
- // TODO: after merge remove setting includeMergedRevisions to false and update parsing
- includeMergedRevisions = false;
List<String> parameters =
prepareCommand(path, startRevision, endRevision, pegRevision, stopOnCopy, discoverChangedPaths, includeMergedRevisions, limit);
@@ -59,18 +51,39 @@
SvnCommand command = CommandUtil.execute(myVcs, SvnTarget.fromFile(path, pegRevision), SvnCommandName.log, parameters, null);
// TODO: handler should be called in parallel with command execution, but this will be in other thread
// TODO: check if that is ok for current handler implementation
- parseOutput(handler, command);
+ parseOutput(command, handler);
}
catch (SVNException e) {
throw new VcsException(e);
}
}
- private static void parseOutput(@Nullable ISVNLogEntryHandler handler, @NotNull SvnCommand command)
+ private static void parseOutput(@NotNull SvnCommand command, @Nullable ISVNLogEntryHandler handler)
throws VcsException, SVNException {
- Parser parser = new Parser(handler);
- for (String line : StringUtil.splitByLines(command.getOutput(), false)) {
- parser.onLine(line);
+ try {
+ LogInfo log = CommandUtil.parse(command.getOutput(), LogInfo.class);
+
+ if (handler != null && log != null) {
+ for (LogEntry entry : log.entries) {
+ iterateRecursively(entry, handler);
+ }
+ }
+ }
+ catch (JAXBException e) {
+ throw new VcsException(e);
+ }
+ }
+
+ private static void iterateRecursively(@NotNull LogEntry entry, @NotNull ISVNLogEntryHandler handler) throws SVNException {
+ handler.handleLogEntry(entry.toLogEntry());
+
+ for (LogEntry childEntry : entry.childEntries) {
+ iterateRecursively(childEntry, handler);
+ }
+
+ if (entry.hasChildren()) {
+ // empty log entry passed to handler to fully correspond to SVNKit behavior.
+ handler.handleLogEntry(SVNLogEntry.EMPTY_ENTRY);
}
}
@@ -92,133 +105,90 @@
parameters.add("--limit");
parameters.add(String.valueOf(limit));
}
+ parameters.add("--xml");
return parameters;
}
- private static class Parser {
- private static final String REVISION = "\\s*r(\\d+)\\s*";
- private static final String AUTHOR = "\\s*([^|]*)\\s*";
- private static final String DATE = "\\s*([^|]*)\\s*";
- private static final String MESSAGE_LINES = "\\s*(\\d+).*";
+ @XmlRootElement(name = "log")
+ public static class LogInfo {
- private static final Pattern ENTRY_START = Pattern.compile("-+");
- private static final Pattern DETAILS = Pattern.compile(REVISION + "\\|" + AUTHOR + "\\|" + DATE + "\\|" + MESSAGE_LINES);
+ @XmlElement(name = "logentry")
+ public List<LogEntry> entries = new ArrayList<LogEntry>();
+ }
- private static final String STATUS = "\\s*(\\w)";
- private static final String PATH = "\\s*(.*?)\\s*";
- private static final String COPY_FROM_PATH = "(/[^:]*)";
- private static final String COPY_FROM_REVISION = "(\\d+)\\))\\s*";
- private static final String COPY_FROM_INFO = "((\\(from " + COPY_FROM_PATH + ":" + COPY_FROM_REVISION + ")?";
- private static final Pattern CHANGED_PATH = Pattern.compile(STATUS + PATH + COPY_FROM_INFO);
+ public static class LogEntry {
- private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
+ @XmlAttribute(name = "revision")
+ public long revision;
- ISVNLogEntryHandler handler;
+ @XmlElement(name = "author")
+ public String author;
- Entry entry;
- boolean waitDetails;
- boolean waitChangedPath;
- boolean waitMessage;
+ @XmlElement(name = "date")
+ public Date date;
- public Parser(@Nullable ISVNLogEntryHandler handler) {
- this.handler = handler;
+ @XmlElement(name = "msg")
+ public String message;
+
+ @XmlElement(name = "paths")
+ public ChangedPaths changedPaths;
+
+ @XmlElement(name = "logentry")
+ public List<LogEntry> childEntries = new ArrayList<LogEntry>();
+
+ public boolean hasChildren() {
+ return !childEntries.isEmpty();
}
- public void onLine(@NotNull String line) throws VcsException, SVNException {
- if (ENTRY_START.matcher(line).matches()) {
- processEntryStart();
- }
- else if (waitDetails) {
- processDetails(line);
- }
- else if (waitMessage) {
- processMessage(line);
- }
- else if (StringUtil.isEmpty(line.trim())) {
- processChangedPathsFinished();
- }
- else if (line.startsWith("Changed paths:")) {
- processChangedPathsStarted();
- }
- else if (waitChangedPath) {
- processChangedPath(line);
- }
- else {
- throw new VcsException("unknown state on line " + line);
- }
+ public SVNLogEntry toLogEntry() {
+ SVNLogEntry entry = new SVNLogEntry(toChangedPathsMap(), revision, author, date, message);
+
+ entry.setHasChildren(hasChildren());
+
+ return entry;
}
- private void processChangedPath(@NotNull String line) throws VcsException {
- Matcher matcher = CHANGED_PATH.matcher(line);
- if (!matcher.matches()) {
- throw new VcsException("changed path not found in " + line);
+ public Map<String, SVNLogEntryPath> toChangedPathsMap() {
+ return changedPaths != null ? changedPaths.toMap() : ContainerUtil.<String, SVNLogEntryPath>newHashMap();
+ }
+ }
+
+ public static class ChangedPaths {
+
+ @XmlElement(name = "path")
+ public List<ChangedPath> changedPaths = new ArrayList<ChangedPath>();
+
+ public Map<String, SVNLogEntryPath> toMap() {
+ Map<String, SVNLogEntryPath> changes = ContainerUtil.newHashMap();
+
+ for (ChangedPath path : changedPaths) {
+ changes.put(path.path, path.toLogEntryPath());
}
- String path = matcher.group(2);
- char type = CommandUtil.getStatusChar(matcher.group(1));
- String copyPath = matcher.group(5);
- long copyRevision = !StringUtil.isEmpty(matcher.group(6)) ? Long.valueOf(matcher.group(6)) : 0;
-
- entry.changedPaths.put(path, new SVNLogEntryPath(path, type, copyPath, copyRevision));
+ return changes;
}
+ }
- private void processChangedPathsStarted() {
- waitChangedPath = true;
- }
+ public static class ChangedPath {
- private void processChangedPathsFinished() {
- waitChangedPath = false;
- waitMessage = true;
- }
+ @XmlAttribute(name = "kind")
+ public String kind;
- private void processMessage(@NotNull String line) {
- entry.message.append(line);
- entry.message.append(LineSeparator.LF.getSeparatorString());
- }
+ @XmlAttribute(name = "action")
+ public String action;
- private void processDetails(@NotNull String line) throws VcsException {
- Matcher matcher = DETAILS.matcher(line);
- if (!matcher.matches()) {
- throw new VcsException("details not found in " + line);
- }
- entry.revision = Long.valueOf(matcher.group(1));
- entry.author = matcher.group(2).trim();
- entry.date = tryGetDate(matcher.group(3));
+ @XmlAttribute(name = "copyfrom-path")
+ public String copyFromPath;
- waitDetails = false;
- }
+ @XmlAttribute(name = "copyfrom-rev")
+ public long copyFromRevision;
- private void processEntryStart() throws SVNException {
- if (entry != null) {
- handler.handleLogEntry(entry.toLogEntry());
- }
- entry = new Entry();
- waitDetails = true;
- waitMessage = false;
- }
+ @XmlValue
+ public String path;
- private static Date tryGetDate(@NotNull String value) {
- Date result = null;
- try {
- result = DATE_FORMAT.parse(value);
- }
- catch (ParseException e) {
- LOG.debug(e);
- }
- return result;
- }
-
- private static class Entry {
- Map<String, SVNLogEntryPath> changedPaths = new HashMap<String, SVNLogEntryPath>();
- long revision;
- String author;
- Date date;
- StringBuilder message = new StringBuilder();
-
- private SVNLogEntry toLogEntry() {
- return new SVNLogEntry(changedPaths, revision, author, date, message.toString());
- }
+ public SVNLogEntryPath toLogEntryPath() {
+ return new SVNLogEntryPath(path, CommandUtil.getStatusChar(action), copyFromPath, copyFromRevision);
}
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java
index d67e29b..f45a294 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java
@@ -36,13 +36,14 @@
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.SvnPropertyKeys;
import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.SVNRevision;
-import org.tmatesoft.svn.core.wc.SVNWCClient;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
/**
* Created with IntelliJ IDEA.
@@ -133,7 +134,6 @@
@Override
public void run(@NotNull ProgressIndicator indicator) {
- final SVNWCClient client = myVcs.createWCClient();
final String url = myLocation.getURL();
final SVNURL root;
try {
@@ -142,12 +142,16 @@
myException = new VcsException("Can not determine repository root for URL: " + url);
return;
}
- client.doSetRevisionProperty(root, SVNRevision.create(myNumber), "svn:log",
- SVNPropertyValue.create(myNewMessage), false, null);
+ SvnTarget target = SvnTarget.fromURL(root);
+ myVcs.getFactory(target).createPropertyClient()
+ .setRevisionProperty(target, SvnPropertyKeys.LOG, SVNRevision.create(myNumber), SVNPropertyValue.create(myNewMessage), false);
}
catch (SVNException e) {
myException = new VcsException(e);
}
+ catch (VcsException e) {
+ myException = e;
+ }
}
@Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
index 44870c1..a429999 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
@@ -20,6 +20,7 @@
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsConfiguration;
import com.intellij.openapi.vcs.VcsException;
@@ -42,7 +43,9 @@
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
-import org.tmatesoft.svn.core.wc.*;
+import org.tmatesoft.svn.core.wc.SVNInfo;
+import org.tmatesoft.svn.core.wc.SVNLogClient;
+import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.util.SVNLogType;
import javax.swing.*;
@@ -502,6 +505,8 @@
}
SVNLogEntryPath entryPath = null;
String copyPath = null;
+ final int mergeLevel = svnLogEntryIntegerPair.getSecond();
+
if (! myLastPathCorrector.isRoot()) {
myLastPathCorrector.handleLogEntry(logEntry);
entryPath = myLastPathCorrector.getDirectlyMentioned();
@@ -511,11 +516,16 @@
} else {
// if there are no path with exact match, check whether parent or child paths had changed
// "entry path" is allowed to be null now; if it is null, last path would be taken for revision construction
- if (! checkForChildChanges(logEntry) && ! checkForParentChanges(logEntry)) return;
+
+ // Separate SVNLogEntry is issued for each "merge source" revision. These "merge source" revisions are treated as child
+ // revisions of some other revision - this way we construct merge hierarchy.
+ // mergeLevel >= 0 indicates that we are currently processing some "merge source" revision. This "merge source" revision
+ // contains changes from some other branch - so checkForChildChanges() and checkForParentChanges() return "false".
+ // Because of this case we apply these methods only for non-"merge source" revisions - this means mergeLevel < 0.
+ if (mergeLevel < 0 && !checkForChildChanges(logEntry) && !checkForParentChanges(logEntry)) return;
}
}
- final int mergeLevel = svnLogEntryIntegerPair.getSecond();
final SvnFileRevision revision = createRevision(logEntry, copyPath, entryPath);
if (mergeLevel >= 0) {
addToListByLevel((SvnFileRevision)myPrevious, revision, mergeLevel);
@@ -608,7 +618,47 @@
}
}
- private class MergeSourceColumnInfo extends ColumnInfo<VcsFileRevision, String> {
+ private static class RevisionMergeSourceInfo {
+
+ @NotNull private final VcsFileRevision revision;
+
+ private RevisionMergeSourceInfo(@NotNull VcsFileRevision revision) {
+ this.revision = revision;
+ }
+
+ @NotNull
+ public SvnFileRevision getRevision() {
+ return (SvnFileRevision)revision;
+ }
+
+ // will be used, for instance, while copying (to clipboard) data from table
+ @Override
+ public String toString() {
+ return toString(revision);
+ }
+
+ private static String toString(@Nullable VcsFileRevision value) {
+ if (!(value instanceof SvnFileRevision)) return "";
+ final SvnFileRevision revision = (SvnFileRevision)value;
+ final List<SvnFileRevision> mergeSources = revision.getMergeSources();
+ if (mergeSources.isEmpty()) {
+ return "";
+ }
+ final StringBuilder sb = new StringBuilder();
+ for (SvnFileRevision source : mergeSources) {
+ if (sb.length() != 0) {
+ sb.append(", ");
+ }
+ sb.append(source.getRevisionNumber().asString());
+ if (!source.getMergeSources().isEmpty()) {
+ sb.append("*");
+ }
+ }
+ return sb.toString();
+ }
+ }
+
+ private class MergeSourceColumnInfo extends ColumnInfo<VcsFileRevision, RevisionMergeSourceInfo> {
private final MergeSourceRenderer myRenderer;
private MergeSourceColumnInfo(final SvnHistorySession session) {
@@ -621,8 +671,8 @@
return myRenderer;
}
- public String valueOf(final VcsFileRevision vcsFileRevision) {
- return vcsFileRevision == null ? "" : getText(vcsFileRevision);
+ public RevisionMergeSourceInfo valueOf(final VcsFileRevision vcsFileRevision) {
+ return vcsFileRevision != null ? new RevisionMergeSourceInfo(vcsFileRevision) : null;
}
public String getText(final VcsFileRevision vcsFileRevision) {
@@ -673,8 +723,8 @@
int column = table.columnAtPoint(e.getPoint());
final Object value = table.getModel().getValueAt(row, column);
- if (value instanceof SvnFileRevision) {
- return (SvnFileRevision)value;
+ if (value instanceof RevisionMergeSourceInfo) {
+ return ((RevisionMergeSourceInfo)value).getRevision();
}
return null;
}
@@ -700,23 +750,7 @@
}
public String getText(final VcsFileRevision value) {
- if (!(value instanceof SvnFileRevision)) return "";
- final SvnFileRevision revision = (SvnFileRevision)value;
- final List<SvnFileRevision> mergeSources = revision.getMergeSources();
- if (mergeSources.isEmpty()) {
- return "";
- }
- final StringBuilder sb = new StringBuilder();
- for (SvnFileRevision source : mergeSources) {
- if (sb.length() != 0) {
- sb.append(", ");
- }
- sb.append(source.getRevisionNumber().asString());
- if (!source.getMergeSources().isEmpty()) {
- sb.append("*");
- }
- }
- return sb.toString();
+ return RevisionMergeSourceInfo.toString(value);
}
protected void customizeCellRenderer(final JTable table,
@@ -729,22 +763,17 @@
myListener = new MergeSourceDetailsLinkListener(MERGE_SOURCE_DETAILS_TAG, myFile);
myListener.installOn(table);
}
- if (value instanceof String) {
- append((String)value, SimpleTextAttributes.REGULAR_ATTRIBUTES);
- return;
- }
- if (!(value instanceof SvnFileRevision)) {
- append("", SimpleTextAttributes.REGULAR_ATTRIBUTES);
- return;
- }
- final SvnFileRevision revision = (SvnFileRevision)value;
- final String text = getText(revision);
- if (text.length() == 0) {
- append("", SimpleTextAttributes.REGULAR_ATTRIBUTES);
- return;
- }
+ appendMergeSourceText(table, row, column, value instanceof RevisionMergeSourceInfo ? value.toString() : null);
+ }
- append(cutString(text, table.getCellRect(row, column, false).getWidth()), SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ private void appendMergeSourceText(JTable table, int row, int column, @Nullable String text) {
+ if (StringUtil.isEmpty(text)) {
+ append("", SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ }
+ else {
+ append(cutString(text, table.getCellRect(row, column, false).getWidth()), SimpleTextAttributes.REGULAR_ATTRIBUTES,
+ MERGE_SOURCE_DETAILS_TAG);
+ }
}
private String cutString(final String text, final double value) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java
index 5b76f6a..2bd8627 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java
@@ -15,28 +15,24 @@
*/
package org.jetbrains.idea.svn.ignore;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnPropertyKeys;
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.SVNDepth;
-import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.wc.SVNPropertyData;
import org.tmatesoft.svn.core.wc.SVNRevision;
-import org.tmatesoft.svn.core.wc.SVNWCClient;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
import java.util.*;
public class SvnPropertyService {
- private final static Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.ignore.SvnPropertyService");
private SvnPropertyService() {
}
@@ -67,22 +63,23 @@
private static abstract class IgnorePropertyWorkTemplate {
protected final SvnVcs myVcs;
- protected final SVNWCClient myClient;
protected final Project myProject;
protected final boolean myUseCommonExtension;
protected final boolean myCanUseCachedProperty;
protected abstract void processFolder(final VirtualFile folder, final File folderDir, final Set<String> data,
- final SVNPropertyValue propertyValue) throws SVNException;
+ final SVNPropertyValue propertyValue) throws VcsException;
+
protected abstract void onAfterProcessing(final VirtualFile[] file) throws VcsException;
- protected abstract void onSVNException(SVNException e);
+
+ protected abstract void onSVNException(Exception e);
+
protected abstract boolean stopIteration();
private IgnorePropertyWorkTemplate(final SvnVcs activeVcs, final Project project, final boolean useCommonExtension,
final boolean canUseCachedProperty) {
myVcs = activeVcs;
myCanUseCachedProperty = canUseCachedProperty;
- myClient = activeVcs.createWCClient();
myProject = project;
myUseCommonExtension = useCommonExtension;
}
@@ -100,12 +97,13 @@
value = myVcs.getPropertyWithCaching(entry.getKey(), SvnPropertyKeys.SVN_IGNORE);
} else {
final SVNPropertyData data =
- myVcs.createWCClient().doGetProperty(dir, SvnPropertyKeys.SVN_IGNORE, SVNRevision.UNDEFINED, SVNRevision.WORKING);
+ myVcs.getFactory(dir).createPropertyClient()
+ .getProperty(SvnTarget.fromFile(dir), SvnPropertyKeys.SVN_IGNORE, false, SVNRevision.WORKING);
value = data == null ? null : data.getValue();
}
processFolder(entry.getKey(), dir, entry.getValue(), value);
}
- catch (SVNException e) {
+ catch (VcsException e) {
onSVNException(e);
}
}
@@ -113,28 +111,6 @@
}
}
- @Nullable
- public static Set<String> getIgnoreStringsUnder(final SvnVcs vcs, final VirtualFile dir) {
- try {
- final SVNPropertyData data = vcs.createWCClient().doGetProperty(new File(dir.getPath()), SvnPropertyKeys.SVN_IGNORE, SVNRevision.WORKING, SVNRevision.WORKING);
- final SVNPropertyValue value = (data == null) ? null : data.getValue();
- if (value != null) {
- final Set<String> ignorePatterns = new HashSet<String>();
- final String propAsString = SVNPropertyValue.getPropertyAsString(value);
- final StringTokenizer st = new StringTokenizer(propAsString, "\r\n ");
- while (st.hasMoreElements()) {
- final String ignorePattern = (String) st.nextElement();
- ignorePatterns.add(ignorePattern);
- }
- return ignorePatterns;
- }
- }
- catch (SVNException e) {
- LOG.info(e);
- }
- return null;
- }
-
private static class IgnorePropertyChecker extends IgnorePropertyWorkTemplate {
private final String myExtensionPattern;
private boolean myFilesOk;
@@ -152,7 +128,7 @@
}
protected void processFolder(final VirtualFile folder, final File folderDir, final Set<String> data, final SVNPropertyValue propertyValue)
- throws SVNException {
+ throws VcsException {
if (propertyValue == null) {
myFilesOk = false;
myExtensionOk = false;
@@ -176,7 +152,7 @@
protected void onAfterProcessing(final VirtualFile[] file) throws VcsException {
}
- protected void onSVNException(final SVNException e) {
+ protected void onSVNException(final Exception e) {
myFilesOk = false;
myExtensionOk = false;
}
@@ -207,10 +183,11 @@
protected abstract String getNewPropertyValue(final Set<String> data, final SVNPropertyValue propertyValue);
protected void processFolder(final VirtualFile folder, final File folderDir, final Set<String> data, final SVNPropertyValue propertyValue)
- throws SVNException {
+ throws VcsException {
String newValue = getNewPropertyValue(data, propertyValue);
newValue = (newValue.trim().isEmpty()) ? null : newValue;
- myClient.doSetProperty(folderDir, SvnPropertyKeys.SVN_IGNORE, SVNPropertyValue.create(newValue), false, false, null);
+ myVcs.getFactory(folderDir).createPropertyClient()
+ .setProperty(folderDir, SvnPropertyKeys.SVN_IGNORE, SVNPropertyValue.create(newValue), SVNDepth.EMPTY, false);
if (myUseCommonExtension) {
dirtyScopeManager.dirDirtyRecursively(folder);
@@ -229,7 +206,7 @@
}
}
- protected void onSVNException(final SVNException e) {
+ protected void onSVNException(final Exception e) {
exceptions.add(e.getMessage());
}
}
@@ -247,21 +224,6 @@
}
}
- public static void setIgnores(final SvnVcs vcs, final Collection<String> patterns, final File file)
- throws SVNException {
- final SVNWCClient client = vcs.createWCClient();
- final StringBuilder sb = new StringBuilder();
- for (String pattern : patterns) {
- sb.append(pattern).append('\n');
- }
- if (! patterns.isEmpty()) {
- final String value = sb.toString();
- client.doSetProperty(file, SvnPropertyKeys.SVN_IGNORE, SVNPropertyValue.create(value), false, SVNDepth.EMPTY, null, null);
- } else {
- client.doSetProperty(file, SvnPropertyKeys.SVN_IGNORE, null, false, SVNDepth.EMPTY, null, null);
- }
- }
-
private static String getNewPropertyValueForRemove(final Collection<String> data, @NotNull final String propertyValue) {
final StringBuilder sb = new StringBuilder();
final StringTokenizer st = new StringTokenizer(propertyValue, "\r\n ");
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnSvnkitUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnSvnkitUpdateClient.java
deleted file mode 100644
index d69a47b..0000000
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnSvnkitUpdateClient.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.idea.svn.portable;
-
-import org.tmatesoft.svn.core.SVNDepth;
-import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.SVNURL;
-import org.tmatesoft.svn.core.wc.ISVNEventHandler;
-import org.tmatesoft.svn.core.wc.SVNRevision;
-import org.tmatesoft.svn.core.wc.SVNUpdateClient;
-
-import java.io.File;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/1/12
- * Time: 12:11 PM
- */
-public class SvnSvnkitUpdateClient implements SvnUpdateClientI {
- private final SVNUpdateClient myClient;
- private ISVNEventHandler myDispatcher;
-
- public SvnSvnkitUpdateClient(SVNUpdateClient client) {
- myClient = client;
- }
-
- @Override
- public long doUpdate(File file, SVNRevision revision, boolean recursive) throws SVNException {
- return myClient.doUpdate(file, revision, recursive);
- }
-
- @Override
- public long doUpdate(File file, SVNRevision revision, boolean recursive, boolean force) throws SVNException {
- return myClient.doUpdate(file, revision, recursive, force);
- }
-
- @Override
- public long[] doUpdate(File[] paths,
- SVNRevision revision,
- SVNDepth depth,
- boolean allowUnversionedObstructions,
- boolean depthIsSticky) throws SVNException {
- return myClient.doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky);
- }
-
- @Override
- public long[] doUpdate(File[] paths,
- SVNRevision revision,
- SVNDepth depth,
- boolean allowUnversionedObstructions,
- boolean depthIsSticky,
- boolean makeParents) throws SVNException {
- return myClient.doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, makeParents);
- }
-
- @Override
- public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky)
- throws SVNException {
- return myClient.doUpdate(path, revision, depth, allowUnversionedObstructions, depthIsSticky);
- }
-
- @Override
- public void setUpdateLocksOnDemand(boolean locksOnDemand) {
- myClient.setUpdateLocksOnDemand(locksOnDemand);
- }
-
- @Override
- public long doSwitch(File file, SVNURL url, SVNRevision revision, boolean recursive) throws SVNException {
- return myClient.doSwitch(file, url, revision, recursive);
- }
-
- @Override
- public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException {
- return myClient.doSwitch(file, url, pegRevision, revision, recursive);
- }
-
- @Override
- public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force)
- throws SVNException {
- return myClient.doSwitch(file, url, pegRevision, revision, recursive, force);
- }
-
- @Override
- public long doSwitch(File path,
- SVNURL url,
- SVNRevision pegRevision,
- SVNRevision revision,
- SVNDepth depth,
- boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException {
- return myClient.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky);
- }
-
- @Override
- public long doSwitch(File path,
- SVNURL url,
- SVNRevision pegRevision,
- SVNRevision revision,
- SVNDepth depth,
- boolean allowUnversionedObstructions, boolean depthIsSticky, boolean ignoreAncestry) throws SVNException {
- return myClient.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky, ignoreAncestry);
- }
-
- @Override
- public long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException {
- return myClient.doCheckout(url, dstPath, pegRevision, revision, recursive);
- }
-
- @Override
- public long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force)
- throws SVNException {
- return myClient.doCheckout(url, dstPath, pegRevision, revision, recursive, force);
- }
-
- @Override
- public long doCheckout(SVNURL url,
- File dstPath,
- SVNRevision pegRevision,
- SVNRevision revision,
- SVNDepth depth,
- boolean allowUnversionedObstructions) throws SVNException {
- return myClient.doCheckout(url, dstPath, pegRevision, revision, depth, allowUnversionedObstructions);
- }
-
- @Override
- public long doExport(SVNURL url,
- File dstPath,
- SVNRevision pegRevision,
- SVNRevision revision,
- String eolStyle,
- boolean force,
- boolean recursive) throws SVNException {
- return myClient.doExport(url, dstPath, pegRevision, revision, eolStyle, force, recursive);
- }
-
- @Override
- public long doExport(SVNURL url,
- File dstPath,
- SVNRevision pegRevision,
- SVNRevision revision,
- String eolStyle,
- boolean overwrite,
- SVNDepth depth) throws SVNException {
- return myClient.doExport(url, dstPath, pegRevision, revision, eolStyle, overwrite, depth);
- }
-
- @Override
- public long doExport(File srcPath,
- File dstPath,
- SVNRevision pegRevision,
- SVNRevision revision,
- String eolStyle,
- boolean force,
- boolean recursive) throws SVNException {
- return myClient.doExport(srcPath, dstPath, pegRevision, revision, eolStyle, force, recursive);
- }
-
- @Override
- public long doExport(File srcPath,
- File dstPath,
- SVNRevision pegRevision,
- SVNRevision revision,
- String eolStyle,
- boolean overwrite,
- SVNDepth depth) throws SVNException {
- return myClient.doExport(srcPath, dstPath, pegRevision, revision, eolStyle, overwrite, depth);
- }
-
- @Override
- public void doRelocate(File dst, SVNURL oldURL, SVNURL newURL, boolean recursive) throws SVNException {
- myClient.doRelocate(dst, oldURL, newURL, recursive);
- }
-
- @Override
- public void doCanonicalizeURLs(File dst, boolean omitDefaultPort, boolean recursive) throws SVNException {
- myClient.doCanonicalizeURLs(dst, omitDefaultPort, recursive);
- }
-
- @Override
- public void setExportExpandsKeywords(boolean expand) {
- myClient.setExportExpandsKeywords(expand);
- }
-
- @Override
- public void setEventHandler(ISVNEventHandler dispatcher) {
- myDispatcher = dispatcher;
- myClient.setEventHandler(dispatcher);
- }
-
- @Override
- public void setIgnoreExternals(boolean ignoreExternals) {
- myClient.setIgnoreExternals(ignoreExternals);
- }
-
- public ISVNEventHandler getEventHandler() {
- return myDispatcher;
- }
-}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnUpdateClientI.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnUpdateClientI.java
deleted file mode 100644
index 8eaafa4..0000000
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnUpdateClientI.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.idea.svn.portable;
-
-import org.tmatesoft.svn.core.SVNDepth;
-import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.SVNURL;
-import org.tmatesoft.svn.core.wc.ISVNEventHandler;
-import org.tmatesoft.svn.core.wc.SVNRevision;
-
-import java.io.File;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/1/12
- * Time: 11:59 AM
- */
-public interface SvnUpdateClientI extends SvnMarkerInterface {
- long doUpdate(File file, SVNRevision revision, boolean recursive) throws SVNException;
-
- long doUpdate(File file, SVNRevision revision, boolean recursive, boolean force) throws SVNException;
-
- long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException;
-
- long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky, boolean makeParents) throws SVNException;
-
- long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException;
-
- void setUpdateLocksOnDemand(boolean locksOnDemand);
-
- long doSwitch(File file, SVNURL url, SVNRevision revision, boolean recursive) throws SVNException;
-
- long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException;
-
- long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) throws SVNException;
-
- long doSwitch(File path, SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException;
-
- long doSwitch(File path, SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky, boolean ignoreAncestry) throws SVNException;
-
- long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException;
-
- long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) throws SVNException;
-
- long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions) throws SVNException;
-
- long doExport(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean force, boolean recursive) throws SVNException;
-
- long doExport(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean overwrite, SVNDepth depth) throws SVNException;
-
- long doExport(File srcPath, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean force, boolean recursive) throws SVNException;
-
- long doExport(File srcPath, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean overwrite, SVNDepth depth) throws SVNException;
-
- void doRelocate(File dst, SVNURL oldURL, SVNURL newURL, boolean recursive) throws SVNException;
-
- void doCanonicalizeURLs(File dst, boolean omitDefaultPort, boolean recursive) throws SVNException;
-
- void setExportExpandsKeywords(boolean expand);
- void setEventHandler(ISVNEventHandler dispatcher);
- void setIgnoreExternals(boolean ignoreExternals);
-}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnWcClientI.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnWcClientI.java
index 973058f..036de6b 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnWcClientI.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnWcClientI.java
@@ -19,7 +19,6 @@
import org.tmatesoft.svn.core.wc.*;
import java.io.File;
-import java.io.OutputStream;
import java.util.Collection;
/**
@@ -29,67 +28,7 @@
* Time: 6:54 PM
*/
public interface SvnWcClientI extends SvnMarkerInterface {
- void setAddParameters(ISVNAddParameters addParameters);
- ISVNCommitHandler getCommitHandler();
- void setCommitHandler(ISVNCommitHandler handler);
- void doGetFileContents(File path, SVNRevision pegRevision, SVNRevision revision,
- boolean expandKeywords, OutputStream dst) throws SVNException;
- void doGetFileContents(SVNURL url, SVNRevision pegRevision, SVNRevision revision,
- boolean expandKeywords, OutputStream dst) throws SVNException;
- void doCleanup(File path) throws SVNException;
- void doCleanup(File path, boolean deleteWCProperties) throws SVNException;
- void doSetProperty(File path, String propName, SVNPropertyValue propValue, boolean skipChecks,
- SVNDepth depth, ISVNPropertyHandler handler, Collection changeLists) throws SVNException;
- void doSetProperty(File path, ISVNPropertyValueProvider propertyValueProvider, boolean skipChecks,
- SVNDepth depth, ISVNPropertyHandler handler, Collection changeLists) throws SVNException;
- SVNCommitInfo doSetProperty(SVNURL url, String propName, SVNPropertyValue propValue,
- SVNRevision baseRevision, String commitMessage, SVNProperties revisionProperties,
- boolean skipChecks, ISVNPropertyHandler handler) throws SVNException;
- void doSetRevisionProperty(File path, SVNRevision revision, String propName,
- SVNPropertyValue propValue, boolean force, ISVNPropertyHandler handler) throws SVNException;
- void doSetRevisionProperty(SVNURL url, SVNRevision revision, String propName,
- SVNPropertyValue propValue, boolean force, ISVNPropertyHandler handler) throws SVNException;
- SVNPropertyData doGetProperty( File path, String propName, SVNRevision pegRevision,
- SVNRevision revision) throws SVNException;
- SVNPropertyData doGetProperty( SVNURL url, String propName, SVNRevision pegRevision,
- SVNRevision revision) throws SVNException;
- void doGetProperty(File path, String propName, SVNRevision pegRevision, SVNRevision revision,
- boolean recursive, ISVNPropertyHandler handler) throws SVNException;
- void doGetProperty(File path, String propName, SVNRevision pegRevision, SVNRevision revision,
- SVNDepth depth, ISVNPropertyHandler handler, Collection changeLists) throws SVNException;
- void doGetProperty(SVNURL url, String propName, SVNRevision pegRevision, SVNRevision revision,
- boolean recursive, ISVNPropertyHandler handler) throws SVNException;
- void doGetProperty(SVNURL url, String propName, SVNRevision pegRevision, SVNRevision revision,
- SVNDepth depth, ISVNPropertyHandler handler) throws SVNException;
- void doGetRevisionProperty(File path, String propName, SVNRevision revision, ISVNPropertyHandler handler) throws SVNException;
- long doGetRevisionProperty(SVNURL url, String propName, SVNRevision revision,
- ISVNPropertyHandler handler) throws SVNException;
- void doDelete(File path, boolean force, boolean dryRun) throws SVNException;
- void doDelete(File path, boolean force, boolean deleteFiles, boolean dryRun) throws SVNException;
- void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents,
- boolean recursive) throws SVNException;
- void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents,
- boolean recursive, boolean includeIgnored) throws SVNException;
- void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents,
- SVNDepth depth, boolean includeIgnored, boolean makeParents) throws SVNException;
- void doAdd(File[] paths, boolean force, boolean mkdir, boolean climbUnversionedParents,
- SVNDepth depth, boolean depthIsSticky, boolean includeIgnored, boolean makeParents) throws SVNException;
- void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents,
- SVNDepth depth, boolean depthIsSticky, boolean includeIgnored, boolean makeParents) throws SVNException;
- void doMarkReplaced(File path) throws SVNException;
- void doRevert(File path, boolean recursive) throws SVNException;
- void doRevert(File[] paths, boolean recursive) throws SVNException;
- void doRevert(File[] paths, SVNDepth depth, Collection changeLists) throws SVNException;
- void doResolve(File path, boolean recursive) throws SVNException;
- void doResolve(File path, SVNDepth depth, SVNConflictChoice conflictChoice) throws SVNException;
- void doResolve(File path, SVNDepth depth, boolean resolveContents, boolean resolveProperties,
- SVNConflictChoice conflictChoice) throws SVNException;
- void doResolve(File path, SVNDepth depth, boolean resolveContents, boolean resolveProperties,
- boolean resolveTree, SVNConflictChoice conflictChoice) throws SVNException;
- void doLock(File[] paths, boolean stealLock, String lockMessage) throws SVNException;
- void doLock(SVNURL[] urls, boolean stealLock, String lockMessage) throws SVNException;
- void doUnlock(File[] paths, boolean breakLock) throws SVNException;
- void doUnlock(SVNURL[] urls, boolean breakLock) throws SVNException;
+
void doInfo(File path, SVNRevision revision, boolean recursive, ISVNInfoHandler handler) throws SVNException;
void doInfo(File path, SVNRevision pegRevision, SVNRevision revision, boolean recursive, ISVNInfoHandler handler) throws SVNException;
void doInfo(File path, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth,
@@ -97,12 +36,6 @@
void doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, ISVNInfoHandler handler) throws SVNException;
void doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth,
ISVNInfoHandler handler) throws SVNException;
- String doGetWorkingCopyID( File path, String trailURL) throws SVNException;
- String doGetWorkingCopyID( File path, String trailURL, boolean committed) throws SVNException;
SVNInfo doInfo(File path, SVNRevision revision) throws SVNException;
SVNInfo doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision) throws SVNException;
- void doCleanupWCProperties(File directory) throws SVNException;
- void doSetWCFormat(File directory, int format) throws SVNException;
- void doSetProperty(File path, String propName, SVNPropertyValue propValue, boolean force,
- boolean recursive, ISVNPropertyHandler handler) throws SVNException;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnStatusClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnStatusClient.java
index ddc7784..07edfa2 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnStatusClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnStatusClient.java
@@ -15,6 +15,9 @@
*/
package org.jetbrains.idea.svn.portable;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.wc.ISVNStatusHandler;
@@ -32,16 +35,19 @@
* Time: 9:47 AM
*/
public class SvnkitSvnStatusClient implements SvnStatusClientI {
- private final SVNStatusClient myStatusClient;
- public SvnkitSvnStatusClient(SVNStatusClient statusClient) {
+ @Nullable private final SVNStatusClient myStatusClient;
+ @NotNull private final SvnVcs myVcs;
+
+ public SvnkitSvnStatusClient(@NotNull SvnVcs vcs, @Nullable SVNStatusClient statusClient) {
+ myVcs = vcs;
myStatusClient = statusClient;
}
@Override
public long doStatus(File path, boolean recursive, boolean remote, boolean reportAll, boolean includeIgnored, ISVNStatusHandler handler)
throws SVNException {
- return myStatusClient.doStatus(path, recursive, remote, reportAll, includeIgnored, handler);
+ return getStatusClient().doStatus(path, recursive, remote, reportAll, includeIgnored, handler);
}
@Override
@@ -52,7 +58,7 @@
boolean includeIgnored,
boolean collectParentExternals,
ISVNStatusHandler handler) throws SVNException {
- return myStatusClient.doStatus(path, recursive, remote, reportAll, includeIgnored, collectParentExternals, handler);
+ return getStatusClient().doStatus(path, recursive, remote, reportAll, includeIgnored, collectParentExternals, handler);
}
@Override
@@ -64,7 +70,7 @@
boolean includeIgnored,
boolean collectParentExternals,
ISVNStatusHandler handler) throws SVNException {
- return myStatusClient.doStatus(path, revision, recursive, remote, reportAll, includeIgnored, collectParentExternals, handler);
+ return getStatusClient().doStatus(path, revision, recursive, remote, reportAll, includeIgnored, collectParentExternals, handler);
}
@Override
@@ -77,16 +83,22 @@
boolean collectParentExternals,
ISVNStatusHandler handler,
Collection changeLists) throws SVNException {
- return myStatusClient.doStatus(path, revision, depth, remote, reportAll, includeIgnored, collectParentExternals, handler, changeLists);
+ return getStatusClient()
+ .doStatus(path, revision, depth, remote, reportAll, includeIgnored, collectParentExternals, handler, changeLists);
}
@Override
public SVNStatus doStatus(File path, boolean remote) throws SVNException {
- return myStatusClient.doStatus(path, remote);
+ return getStatusClient().doStatus(path, remote);
}
@Override
public SVNStatus doStatus(File path, boolean remote, boolean collectParentExternals) throws SVNException {
- return myStatusClient.doStatus(path, remote, collectParentExternals);
+ return getStatusClient().doStatus(path, remote, collectParentExternals);
+ }
+
+ @NotNull
+ private SVNStatusClient getStatusClient() {
+ return myStatusClient != null ? myStatusClient : myVcs.createStatusClient();
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnWcClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnWcClient.java
index 4b0076d..faee8ec 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnWcClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnWcClient.java
@@ -21,7 +21,6 @@
import org.tmatesoft.svn.core.wc.*;
import java.io.File;
-import java.io.OutputStream;
import java.util.Collection;
/**
@@ -43,279 +42,6 @@
}
@Override
- public void setAddParameters(ISVNAddParameters addParameters) {
- getClient().setAddParameters(addParameters);
- }
-
- @Override
- public ISVNCommitHandler getCommitHandler() {
- return getClient().getCommitHandler();
- }
-
- @Override
- public void setCommitHandler(ISVNCommitHandler handler) {
- getClient().setCommitHandler(handler);
- }
-
- @Override
- public void doGetFileContents(File path, SVNRevision pegRevision, SVNRevision revision, boolean expandKeywords, OutputStream dst)
- throws SVNException {
- getClient().doGetFileContents(path, pegRevision, revision, expandKeywords, dst);
- }
-
- @Override
- public void doGetFileContents(SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean expandKeywords, OutputStream dst)
- throws SVNException {
- getClient().doGetFileContents(url, pegRevision, revision, expandKeywords, dst);
- }
-
- @Override
- public void doCleanup(File path) throws SVNException {
- getClient().doCleanup(path);
- }
-
- @Override
- public void doCleanup(File path, boolean deleteWCProperties) throws SVNException {
- getClient().doCleanup(path, deleteWCProperties);
- }
-
- @Override
- public void doSetProperty(File path,
- String propName,
- SVNPropertyValue propValue,
- boolean skipChecks,
- SVNDepth depth,
- ISVNPropertyHandler handler,
- Collection changeLists) throws SVNException {
- getClient().doSetProperty(path, propName, propValue, skipChecks, depth, handler, changeLists);
- }
-
- @Override
- public void doSetProperty(File path,
- ISVNPropertyValueProvider propertyValueProvider,
- boolean skipChecks,
- SVNDepth depth,
- ISVNPropertyHandler handler,
- Collection changeLists) throws SVNException {
- getClient().doSetProperty(path, propertyValueProvider, skipChecks, depth, handler, changeLists);
- }
-
- @Override
- public SVNCommitInfo doSetProperty(SVNURL url,
- String propName,
- SVNPropertyValue propValue,
- SVNRevision baseRevision,
- String commitMessage,
- SVNProperties revisionProperties,
- boolean skipChecks,
- ISVNPropertyHandler handler) throws SVNException {
- return getClient().doSetProperty(url, propName, propValue, baseRevision, commitMessage, revisionProperties, skipChecks, handler);
- }
-
- @Override
- public void doSetRevisionProperty(File path,
- SVNRevision revision,
- String propName,
- SVNPropertyValue propValue,
- boolean force,
- ISVNPropertyHandler handler) throws SVNException {
- getClient().doSetRevisionProperty(path, revision, propName, propValue, force, handler);
- }
-
- @Override
- public void doSetRevisionProperty(SVNURL url,
- SVNRevision revision,
- String propName,
- SVNPropertyValue propValue,
- boolean force,
- ISVNPropertyHandler handler) throws SVNException {
- getClient().doSetRevisionProperty(url, revision, propName, propValue, force, handler);
- }
-
- @Override
- public SVNPropertyData doGetProperty(File path, String propName, SVNRevision pegRevision, SVNRevision revision) throws SVNException {
- return getClient().doGetProperty(path, propName, pegRevision, revision);
- }
-
- @Override
- public SVNPropertyData doGetProperty(SVNURL url, String propName, SVNRevision pegRevision, SVNRevision revision) throws SVNException {
- return getClient().doGetProperty(url, propName, pegRevision, revision);
- }
-
- @Override
- public void doGetProperty(File path,
- String propName,
- SVNRevision pegRevision,
- SVNRevision revision,
- boolean recursive,
- ISVNPropertyHandler handler) throws SVNException {
- getClient().doGetProperty(path, propName, pegRevision, revision, recursive, handler);
- }
-
- @Override
- public void doGetProperty(File path,
- String propName,
- SVNRevision pegRevision,
- SVNRevision revision,
- SVNDepth depth,
- ISVNPropertyHandler handler,
- Collection changeLists) throws SVNException {
- getClient().doGetProperty(path, propName, pegRevision, revision, depth, handler, changeLists);
- }
-
- @Override
- public void doGetProperty(SVNURL url,
- String propName,
- SVNRevision pegRevision,
- SVNRevision revision,
- boolean recursive,
- ISVNPropertyHandler handler) throws SVNException {
- getClient().doGetProperty(url, propName, pegRevision, revision, recursive, handler);
- }
-
- @Override
- public void doGetProperty(SVNURL url,
- String propName,
- SVNRevision pegRevision,
- SVNRevision revision,
- SVNDepth depth,
- ISVNPropertyHandler handler) throws SVNException {
- getClient().doGetProperty(url, propName, pegRevision, revision, depth, handler);
- }
-
- @Override
- public void doGetRevisionProperty(File path, String propName, SVNRevision revision, ISVNPropertyHandler handler) throws SVNException {
- getClient().doGetRevisionProperty(path, propName, revision, handler);
- }
-
- @Override
- public long doGetRevisionProperty(SVNURL url, String propName, SVNRevision revision, ISVNPropertyHandler handler) throws SVNException {
- return getClient().doGetRevisionProperty(url, propName, revision, handler);
- }
-
- @Override
- public void doDelete(File path, boolean force, boolean dryRun) throws SVNException {
- getClient().doDelete(path, force, dryRun);
- }
-
- @Override
- public void doDelete(File path, boolean force, boolean deleteFiles, boolean dryRun) throws SVNException {
- getClient().doDelete(path, force, deleteFiles, dryRun);
- }
-
- @Override
- public void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents, boolean recursive) throws SVNException {
- getClient().doAdd(path, force, mkdir, climbUnversionedParents, recursive);
- }
-
- @Override
- public void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents, boolean recursive, boolean includeIgnored)
- throws SVNException {
- getClient().doAdd(path, force, mkdir, climbUnversionedParents, recursive, includeIgnored);
- }
-
- @Override
- public void doAdd(File path,
- boolean force,
- boolean mkdir,
- boolean climbUnversionedParents,
- SVNDepth depth,
- boolean includeIgnored,
- boolean makeParents) throws SVNException {
- getClient().doAdd(path, force, mkdir, climbUnversionedParents, depth, includeIgnored, makeParents);
- }
-
- @Override
- public void doAdd(File[] paths,
- boolean force,
- boolean mkdir,
- boolean climbUnversionedParents,
- SVNDepth depth,
- boolean depthIsSticky,
- boolean includeIgnored,
- boolean makeParents) throws SVNException {
- getClient().doAdd(paths, force, mkdir, climbUnversionedParents, depth, depthIsSticky, includeIgnored, makeParents);
- }
-
- @Override
- public void doAdd(File path,
- boolean force,
- boolean mkdir,
- boolean climbUnversionedParents,
- SVNDepth depth,
- boolean depthIsSticky,
- boolean includeIgnored,
- boolean makeParents) throws SVNException {
- getClient().doAdd(path, force, mkdir, climbUnversionedParents, depth, depthIsSticky, includeIgnored, makeParents);
- }
-
- @Override
- public void doMarkReplaced(File path) throws SVNException {
- getClient().doMarkReplaced(path);
- }
-
- @Override
- public void doRevert(File path, boolean recursive) throws SVNException {
- getClient().doRevert(path, recursive);
- }
-
- @Override
- public void doRevert(File[] paths, boolean recursive) throws SVNException {
- getClient().doRevert(paths, recursive);
- }
-
- @Override
- public void doRevert(File[] paths, SVNDepth depth, Collection changeLists) throws SVNException {
- getClient().doRevert(paths, depth, changeLists);
- }
-
- @Override
- public void doResolve(File path, boolean recursive) throws SVNException {
- getClient().doResolve(path, recursive);
- }
-
- @Override
- public void doResolve(File path, SVNDepth depth, SVNConflictChoice conflictChoice) throws SVNException {
- getClient().doResolve(path, depth, conflictChoice);
- }
-
- @Override
- public void doResolve(File path, SVNDepth depth, boolean resolveContents, boolean resolveProperties, SVNConflictChoice conflictChoice)
- throws SVNException {
- getClient().doResolve(path, depth, resolveContents, resolveProperties, conflictChoice);
- }
-
- @Override
- public void doResolve(File path,
- SVNDepth depth,
- boolean resolveContents,
- boolean resolveProperties,
- boolean resolveTree,
- SVNConflictChoice conflictChoice) throws SVNException {
- getClient().doResolve(path, depth, resolveContents, resolveProperties, resolveTree, conflictChoice);
- }
-
- @Override
- public void doLock(File[] paths, boolean stealLock, String lockMessage) throws SVNException {
- getClient().doLock(paths, stealLock, lockMessage);
- }
-
- @Override
- public void doLock(SVNURL[] urls, boolean stealLock, String lockMessage) throws SVNException {
- getClient().doLock(urls, stealLock, lockMessage);
- }
-
- @Override
- public void doUnlock(File[] paths, boolean breakLock) throws SVNException {
- getClient().doUnlock(paths, breakLock);
- }
-
- @Override
- public void doUnlock(SVNURL[] urls, boolean breakLock) throws SVNException {
- getClient().doUnlock(urls, breakLock);
- }
-
- @Override
public void doInfo(File path, SVNRevision revision, boolean recursive, ISVNInfoHandler handler) throws SVNException {
getClient().doInfo(path, revision, recursive, handler);
}
@@ -349,16 +75,6 @@
}
@Override
- public String doGetWorkingCopyID(File path, String trailURL) throws SVNException {
- return getClient().doGetWorkingCopyID(path, trailURL);
- }
-
- @Override
- public String doGetWorkingCopyID(File path, String trailURL, boolean committed) throws SVNException {
- return getClient().doGetWorkingCopyID(path, trailURL, committed);
- }
-
- @Override
public SVNInfo doInfo(File path, SVNRevision revision) throws SVNException {
return getClient().doInfo(path, revision);
}
@@ -367,24 +83,4 @@
public SVNInfo doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision) throws SVNException {
return getClient().doInfo(url, pegRevision, revision);
}
-
- @Override
- public void doCleanupWCProperties(File directory) throws SVNException {
- getClient().doCleanupWCProperties(directory);
- }
-
- @Override
- public void doSetWCFormat(File directory, int format) throws SVNException {
- getClient().doSetWCFormat(directory, format);
- }
-
- @Override
- public void doSetProperty(File path,
- String propName,
- SVNPropertyValue propValue,
- boolean force,
- boolean recursive,
- ISVNPropertyHandler handler) throws SVNException {
- getClient().doSetProperty(path, propName, propValue, force, recursive, handler);
- }
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java
index f6d2c56..59ba154 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java
@@ -95,19 +95,47 @@
@Nullable SVNPropertyValue value,
@Nullable SVNDepth depth,
boolean force) throws VcsException {
+ runSetProperty(SvnTarget.fromFile(file), property, null, depth, value, force);
+ }
+
+ @Override
+ public void setRevisionProperty(@NotNull SvnTarget target,
+ @NotNull String property,
+ @NotNull SVNRevision revision,
+ @Nullable SVNPropertyValue value,
+ boolean force) throws VcsException {
+ runSetProperty(target, property, revision, null, value, force);
+ }
+
+ private void runSetProperty(@NotNull SvnTarget target,
+ @NotNull String property,
+ @Nullable SVNRevision revision,
+ @Nullable SVNDepth depth,
+ @Nullable SVNPropertyValue value,
+ boolean force) throws VcsException {
List<String> parameters = new ArrayList<String>();
boolean isDelete = value == null;
parameters.add(property);
+ if (revision != null) {
+ parameters.add("--revprop");
+ CommandUtil.put(parameters, revision);
+ }
if (!isDelete) {
parameters.add(SVNPropertyValue.getPropertyAsString(value));
// --force could only be used in "propset" command, but not in "propdel" command
CommandUtil.put(parameters, force, "--force");
}
- CommandUtil.put(parameters, file);
+ CommandUtil.put(parameters, target);
CommandUtil.put(parameters, depth);
- CommandUtil.execute(myVcs, SvnTarget.fromFile(file), isDelete ? SvnCommandName.propdel : SvnCommandName.propset, parameters, null);
+ // For some reason, command setting ignore property when working directory equals target directory (like
+ // "svn propset svn:ignore *.java . --depth empty") tries to set ignore also on child files and fails with error like
+ // "svn: E200009: Cannot set 'svn:ignore' on a file ('...File1.java')". So here we manually force home directory to be used.
+ // NOTE: that setting other properties (not svn:ignore) does not cause such error.
+ CommandUtil
+ .execute(myVcs, target, CommandUtil.getHomeDirectory(), isDelete ? SvnCommandName.propdel : SvnCommandName.propset, parameters,
+ null);
}
private void fillListParameters(@NotNull SvnTarget target,
@@ -211,7 +239,7 @@
// such behavior is required to compatibility with SVNKit as some logic in merge depends on
// whether null property data or property data with empty string value is returned
if (value != null) {
- result = new SVNPropertyData(property, SVNPropertyValue.create(value.trim()), null);
+ result = new SVNPropertyData(property, SVNPropertyValue.create(value.trim()), LF_SEPARATOR_OPTIONS);
}
return result;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java
index 2f1ba5e..12bc0e9 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java
@@ -1,11 +1,15 @@
package org.jetbrains.idea.svn.properties;
import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.util.LineSeparator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.api.SvnClient;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNPropertyValue;
+import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
+import org.tmatesoft.svn.core.wc.ISVNOptions;
import org.tmatesoft.svn.core.wc.ISVNPropertyHandler;
import org.tmatesoft.svn.core.wc.SVNPropertyData;
import org.tmatesoft.svn.core.wc.SVNRevision;
@@ -18,6 +22,13 @@
*/
public interface PropertyClient extends SvnClient {
+ ISVNOptions LF_SEPARATOR_OPTIONS = new DefaultSVNOptions() {
+ @Override
+ public byte[] getNativeEOL() {
+ return CharsetToolkit.getUtf8Bytes(LineSeparator.LF.getSeparatorString());
+ }
+ };
+
@Nullable
SVNPropertyData getProperty(@NotNull final SvnTarget target,
@NotNull final String property,
@@ -39,4 +50,10 @@
@Nullable SVNPropertyValue value,
@Nullable SVNDepth depth,
boolean force) throws VcsException;
+
+ void setRevisionProperty(@NotNull SvnTarget target,
+ @NotNull String property,
+ @NotNull SVNRevision revision,
+ @Nullable SVNPropertyValue value,
+ boolean force) throws VcsException;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java
index ee72e59..d55eb68 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java
@@ -31,9 +31,9 @@
try {
if (!revisionProperty) {
if (target.isFile()) {
- return myVcs.createWCClient().doGetProperty(target.getFile(), property, target.getPegRevision(), revision);
+ return createClient().doGetProperty(target.getFile(), property, target.getPegRevision(), revision);
} else {
- return myVcs.createWCClient().doGetProperty(target.getURL(), property, target.getPegRevision(), revision);
+ return createClient().doGetProperty(target.getURL(), property, target.getPegRevision(), revision);
}
} else {
return getRevisionProperty(target, property, revision);
@@ -44,6 +44,14 @@
}
}
+ @NotNull
+ private SVNWCClient createClient() {
+ SVNWCClient client = myVcs.createWCClient();
+ client.setOptions(LF_SEPARATOR_OPTIONS);
+
+ return client;
+ }
+
@Override
public void getProperty(@NotNull SvnTarget target,
@NotNull String property,
@@ -68,7 +76,26 @@
@Nullable SVNDepth depth,
boolean force) throws VcsException {
try {
- myVcs.createWCClient().doSetProperty(file, property, value, force, depth, null, null);
+ createClient().doSetProperty(file, property, value, force, depth, null, null);
+ }
+ catch (SVNException e) {
+ throw new SvnBindException(e);
+ }
+ }
+
+ @Override
+ public void setRevisionProperty(@NotNull SvnTarget target,
+ @NotNull String property,
+ @NotNull SVNRevision revision,
+ @Nullable SVNPropertyValue value,
+ boolean force) throws VcsException {
+ try {
+ if (target.isFile()) {
+ createClient().doSetRevisionProperty(target.getFile(), revision, property, value, force, null);
+ }
+ else {
+ createClient().doSetRevisionProperty(target.getURL(), revision, property, value, force, null);
+ }
}
catch (SVNException e) {
throw new SvnBindException(e);
@@ -80,7 +107,7 @@
@Nullable SVNRevision revision,
@Nullable SVNDepth depth,
@Nullable ISVNPropertyHandler handler) throws VcsException {
- SVNWCClient client = myVcs.createWCClient();
+ SVNWCClient client = createClient();
try {
if (target.isURL()) {
@@ -94,7 +121,7 @@
}
private SVNPropertyData getRevisionProperty(@NotNull SvnTarget target, @NotNull final String property, @Nullable SVNRevision revision) throws SVNException{
- final SVNWCClient client = myVcs.createWCClient();
+ final SVNWCClient client = createClient();
final SVNPropertyData[] result = new SVNPropertyData[1];
ISVNPropertyHandler handler = new ISVNPropertyHandler() {
@Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java
index 72741ce..391077eb 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java
@@ -35,10 +35,7 @@
import com.intellij.openapi.vcs.changes.patch.ApplyPatchExecutor;
import com.intellij.openapi.vcs.changes.patch.FilePatchInProgress;
import com.intellij.openapi.vcs.changes.patch.PatchWriter;
-import com.intellij.openapi.vfs.CharsetToolkit;
-import com.intellij.openapi.vfs.VfsUtil;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.VirtualFileWrapper;
+import com.intellij.openapi.vfs.*;
import com.intellij.util.WaitForProgressToShow;
import com.intellij.util.containers.MultiMap;
@@ -79,7 +76,7 @@
new FileSaverDescriptor("Save patch to", ""), myProject);
final VirtualFile baseDir = myProject.getBaseDir();
final VirtualFileWrapper save = dialog.save(baseDir, "TheirsChanges.patch");
- if (save != null && save.getFile() != null) {
+ if (save != null) {
final CommitContext commitContext = new CommitContext();
final VirtualFile baseForPatch = myBaseForPatch == null ? baseDir : myBaseForPatch;
@@ -107,7 +104,7 @@
for (Map.Entry<VirtualFile, Collection<FilePatchInProgress>> entry : patchGroups.entrySet()) {
final VirtualFile vf = entry.getKey();
final String currBasePath = vf.getPath();
- final String relativePath = VfsUtil.getRelativePath(vf, baseDir, '/');
+ final String relativePath = VfsUtilCore.getRelativePath(vf, baseDir, '/');
final boolean toConvert = !StringUtil.isEmptyOrSpaces(relativePath) && !".".equals(relativePath);
for (FilePatchInProgress patchInProgress : entry.getValue()) {
final TextFilePatch patch = patchInProgress.getPatch();
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/CmdUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/CmdUpdateClient.java
new file mode 100644
index 0000000..a6a4d0f
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/CmdUpdateClient.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.svn.update;
+
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.commandLine.BaseUpdateCommandListener;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandLineInfoClient;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.tmatesoft.svn.core.*;
+import org.tmatesoft.svn.core.wc.SVNEvent;
+import org.tmatesoft.svn.core.wc.SVNEventAction;
+import org.tmatesoft.svn.core.wc.SVNInfo;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: Irina.Chernushina
+ * Date: 2/1/12
+ * Time: 12:13 PM
+ */
+// TODO: Currently make inherit SVNKit update implementation not to duplicate setXxx() methods.
+public class CmdUpdateClient extends SvnKitUpdateClient {
+ private static final Pattern ourExceptionPattern = Pattern.compile("svn: E(\\d{6}): .+");
+ private static final String ourAuthenticationRealm = "Authentication realm:";
+
+ @Override
+ public long[] doUpdate(final File[] paths, final SVNRevision revision, final SVNDepth depth, final boolean allowUnversionedObstructions,
+ final boolean depthIsSticky, final boolean makeParents) throws SVNException {
+ // since one revision is passed -> I assume same repository here
+ checkWorkingCopy(paths[0]);
+
+ final List<String> parameters = new ArrayList<String>();
+
+ fillParameters(parameters, revision, depth, depthIsSticky, allowUnversionedObstructions);
+ CommandUtil.put(parameters, makeParents, "--parents");
+ CommandUtil.put(parameters, myIgnoreExternals, "--ignore-externals");
+ CommandUtil.put(parameters, paths);
+
+ return run(paths, parameters, SvnCommandName.up);
+ }
+
+ private void checkWorkingCopy(@NotNull File path) throws SVNException {
+ final SvnCommandLineInfoClient infoClient = new SvnCommandLineInfoClient(myVcs);
+ final SVNInfo info = infoClient.doInfo(path, SVNRevision.UNDEFINED);
+
+ if (info == null || info.getURL() == null) {
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_WORKING_COPY, path.getPath()));
+ }
+ }
+
+ private long[] run(@NotNull File[] paths, @NotNull List<String> parameters, @NotNull SvnCommandName command) throws SVNException {
+ File base = paths[0];
+ base = base.isDirectory() ? base : base.getParentFile();
+
+ final AtomicReference<long[]> updatedToRevision = new AtomicReference<long[]>();
+ updatedToRevision.set(new long[0]);
+
+ final BaseUpdateCommandListener listener = createCommandListener(paths, updatedToRevision, base);
+ try {
+ CommandUtil.execute(myVcs, SvnTarget.fromFile(base), command, parameters, listener);
+ }
+ catch (VcsException e) {
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e));
+ }
+
+ listener.throwIfException();
+
+ return updatedToRevision.get();
+ }
+
+ private BaseUpdateCommandListener createCommandListener(final File[] paths,
+ final AtomicReference<long[]> updatedToRevision,
+ final File base) {
+ return new BaseUpdateCommandListener(base, myDispatcher) {
+ final long[] myRevisions = new long[paths.length];
+
+ @Override
+ protected void beforeHandler(@NotNull SVNEvent event) {
+ if (SVNEventAction.UPDATE_COMPLETED.equals(event.getAction())) {
+ final long eventRevision = event.getRevision();
+ for (int i = 0; i < paths.length; i++) {
+ final File path = paths[i];
+ if (FileUtil.filesEqual(path, event.getFile())) {
+ myRevisions[i] = eventRevision;
+ break;
+ }
+ }
+ }
+ }
+
+ @Override
+ public void processTerminated(int exitCode) {
+ super.processTerminated(exitCode);
+ updatedToRevision.set(myRevisions);
+ }
+ };
+ }
+
+ private static void fillParameters(@NotNull List<String> parameters,
+ @Nullable SVNRevision revision,
+ @Nullable SVNDepth depth,
+ boolean depthIsSticky,
+ boolean allowUnversionedObstructions) {
+
+ CommandUtil.put(parameters, revision);
+ CommandUtil.put(parameters, depth, depthIsSticky);
+ CommandUtil.put(parameters, allowUnversionedObstructions, "--force");
+ parameters.add("--accept");
+ parameters.add("postpone");
+ }
+
+
+ private void checkForException(final StringBuffer sbError) throws SVNException {
+ if (sbError.length() == 0) return;
+ final String message = sbError.toString();
+ final Matcher matcher = ourExceptionPattern.matcher(message);
+ if (matcher.matches()) {
+ final String group = matcher.group(1);
+ if (group != null) {
+ try {
+ final int code = Integer.parseInt(group);
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.getErrorCode(code), message));
+ } catch (NumberFormatException e) {
+ //
+ }
+ }
+ }
+ if (message.contains(ourAuthenticationRealm)) {
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.AUTHN_CREDS_UNAVAILABLE, message));
+ }
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.UNKNOWN, message));
+ }
+
+ @Override
+ public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky)
+ throws SVNException {
+ final long[] longs = doUpdate(new File[]{path}, revision, depth, allowUnversionedObstructions, depthIsSticky, false);
+ return longs[0];
+ }
+
+ @Override
+ public long doSwitch(File path,
+ SVNURL url,
+ SVNRevision pegRevision,
+ SVNRevision revision,
+ SVNDepth depth,
+ boolean allowUnversionedObstructions,
+ boolean depthIsSticky) throws SVNException {
+ checkWorkingCopy(path);
+
+ List<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, SvnTarget.fromURL(url, pegRevision));
+ CommandUtil.put(parameters, path, false);
+ fillParameters(parameters, revision, depth, depthIsSticky, allowUnversionedObstructions);
+ parameters.add("--ignore-ancestry");
+
+ long[] revisions = run(new File[]{path}, parameters, SvnCommandName.switchCopy);
+
+ return revisions != null && revisions.length > 0 ? revisions[0] : -1;
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnKitUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnKitUpdateClient.java
new file mode 100644
index 0000000..a847975
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnKitUpdateClient.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.svn.update;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc.SVNUpdateClient;
+
+import java.io.File;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: Irina.Chernushina
+ * Date: 2/1/12
+ * Time: 12:11 PM
+ */
+public class SvnKitUpdateClient extends BaseSvnClient implements UpdateClient {
+
+ @Nullable protected ISVNEventHandler myDispatcher;
+ protected boolean myIgnoreExternals;
+ protected boolean myLocksOnDemand;
+
+ @Override
+ public long[] doUpdate(File[] paths,
+ SVNRevision revision,
+ SVNDepth depth,
+ boolean allowUnversionedObstructions,
+ boolean depthIsSticky,
+ boolean makeParents) throws SVNException {
+ return getClient().doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, makeParents);
+ }
+
+ @Override
+ public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky)
+ throws SVNException {
+ return getClient().doUpdate(path, revision, depth, allowUnversionedObstructions, depthIsSticky);
+ }
+
+ @Override
+ public long doSwitch(File path,
+ SVNURL url,
+ SVNRevision pegRevision,
+ SVNRevision revision,
+ SVNDepth depth,
+ boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException {
+ return getClient().doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky);
+ }
+
+ @Override
+ public void setUpdateLocksOnDemand(boolean locksOnDemand) {
+ myLocksOnDemand = locksOnDemand;
+ }
+
+ @Override
+ public void setEventHandler(ISVNEventHandler dispatcher) {
+ myDispatcher = dispatcher;
+ }
+
+ @Override
+ public void setIgnoreExternals(boolean ignoreExternals) {
+ myIgnoreExternals = ignoreExternals;
+ }
+
+ @NotNull
+ private SVNUpdateClient getClient() {
+ SVNUpdateClient client = myVcs.createUpdateClient();
+
+ client.setEventHandler(myDispatcher);
+ client.setIgnoreExternals(myIgnoreExternals);
+ client.setUpdateLocksOnDemand(myLocksOnDemand);
+
+ return client;
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
index 148d717..af9ef2e 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
@@ -25,7 +25,6 @@
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
import org.jetbrains.idea.svn.api.ClientFactory;
-import org.jetbrains.idea.svn.portable.SvnUpdateClientI;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.io.SVNRepository;
@@ -83,11 +82,11 @@
final boolean isSwitch = rootInfo != null && rootInfo.getUrl() != null && ! rootInfo.getUrl().equals(sourceUrl);
final SVNRevision updateTo = rootInfo != null && rootInfo.isUpdateToRevision() ? rootInfo.getRevision() : SVNRevision.HEAD;
if (isSwitch) {
- final SvnUpdateClientI updateClient = createUpdateClient(configuration, root, true, sourceUrl);
+ final UpdateClient updateClient = createUpdateClient(configuration, root, true, sourceUrl);
myHandler.addToSwitch(root, sourceUrl);
rev = updateClient.doSwitch(root, rootInfo.getUrl(), SVNRevision.UNDEFINED, updateTo, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false);
} else {
- final SvnUpdateClientI updateClient = createUpdateClient(configuration, root, false, sourceUrl);
+ final UpdateClient updateClient = createUpdateClient(configuration, root, false, sourceUrl);
rev = updateClient.doUpdate(root, updateTo, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false);
}
@@ -96,14 +95,14 @@
return rev;
}
- private SvnUpdateClientI createUpdateClient(SvnConfiguration configuration, File root, boolean isSwitch, SVNURL sourceUrl) {
+ private UpdateClient createUpdateClient(SvnConfiguration configuration, File root, boolean isSwitch, SVNURL sourceUrl) {
boolean is17 = WorkingCopyFormat.ONE_DOT_SEVEN.equals(myVcs.getWorkingCopyFormat(root));
boolean isSupportedProtocol =
SvnAuthenticationManager.HTTP.equals(sourceUrl.getProtocol()) || SvnAuthenticationManager.HTTPS.equals(sourceUrl.getProtocol());
// TODO: Update this with just myVcs.getFactory(root) when switch and authentication protocols are implemented for command line
ClientFactory factory = is17 && (isSwitch || !isSupportedProtocol) ? myVcs.getSvnKitFactory() : myVcs.getFactory(root);
- final SvnUpdateClientI updateClient = factory.createUpdateClient();
+ final UpdateClient updateClient = factory.createUpdateClient();
if (! isSwitch) {
updateClient.setIgnoreExternals(configuration.IGNORE_EXTERNALS);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateClient.java
new file mode 100644
index 0000000..b68829e
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateClient.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.svn.update;
+
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+
+import java.io.File;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: Irina.Chernushina
+ * Date: 2/1/12
+ * Time: 11:59 AM
+ */
+public interface UpdateClient extends SvnClient {
+
+ long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky, boolean makeParents) throws SVNException;
+
+ long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException;
+
+ void setUpdateLocksOnDemand(boolean locksOnDemand);
+
+ long doSwitch(File path, SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException;
+
+ void setEventHandler(ISVNEventHandler dispatcher);
+ void setIgnoreExternals(boolean ignoreExternals);
+}
diff --git a/plugins/terminal/lib/jediterm-pty-0.08.jar b/plugins/terminal/lib/jediterm-pty-0.08.jar
index f7073d5..e9ef4dd 100644
--- a/plugins/terminal/lib/jediterm-pty-0.08.jar
+++ b/plugins/terminal/lib/jediterm-pty-0.08.jar
Binary files differ
diff --git a/plugins/terminal/resources/META-INF/terminal.xml b/plugins/terminal/resources/META-INF/terminal.xml
index 24a8466..a0282b7 100644
--- a/plugins/terminal/resources/META-INF/terminal.xml
+++ b/plugins/terminal/resources/META-INF/terminal.xml
@@ -13,5 +13,14 @@
<applicationService serviceInterface="org.jetbrains.plugins.terminal.TerminalView"
serviceImplementation="org.jetbrains.plugins.terminal.TerminalView"/>
+
+ <projectConfigurable instance="org.jetbrains.plugins.terminal.TerminalOptionsConfigurable"/>
</extensions>
+
+ <application-components>
+ <component>
+ <interface-class>org.jetbrains.plugins.terminal.TerminalOptionsProvider</interface-class>
+ <implementation-class>org.jetbrains.plugins.terminal.TerminalOptionsProvider</implementation-class>
+ </component>
+ </application-components>
</idea-plugin>
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java
index fcf0627..3477859b 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java
@@ -171,7 +171,7 @@
openSession(terminalWidget, createTtyConnector(process));
}
catch (Exception e) {
- throw new RuntimeException(e.getMessage(), e);
+ LOG.error("Can't open terminal session:" + e.getMessage(), e);
}
}
}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java
index d5caf0b..56664cf 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java
@@ -9,6 +9,7 @@
import com.jediterm.terminal.ui.TerminalAction;
import com.jediterm.terminal.ui.TerminalWidget;
import com.jediterm.terminal.ui.settings.SettingsProvider;
+import com.jediterm.terminal.ui.settings.TabbedSettingsProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -21,7 +22,7 @@
*/
public class JBTabbedTerminalWidget extends TabbedTerminalWidget {
- public JBTabbedTerminalWidget(@NotNull SettingsProvider settingsProvider, @NotNull Predicate<TerminalWidget> createNewSessionAction) {
+ public JBTabbedTerminalWidget(@NotNull TabbedSettingsProvider settingsProvider, @NotNull Predicate<TerminalWidget> createNewSessionAction) {
super(settingsProvider, createNewSessionAction);
convertActions(this, getActions());
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
index 84a9d2f..e8fd25b 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
@@ -20,6 +20,7 @@
package org.jetbrains.plugins.terminal;
import com.google.common.base.Predicate;
+import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.keymap.Keymap;
@@ -27,7 +28,6 @@
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.util.JBHiDPIScaledImage;
import com.intellij.util.RetinaImage;
-import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import com.jediterm.terminal.display.BackBuffer;
import com.jediterm.terminal.display.StyleState;
@@ -96,8 +96,9 @@
}
}
- protected void setupAntialiasing(Graphics graphics, boolean antialiasing) {
- GraphicsUtil.setupAntialiasing(graphics, antialiasing, false);
+ @Override
+ protected void setupAntialiasing(Graphics graphics) {
+ UISettings.setupAntialiasing(graphics);
}
@Override
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSchemeColorPalette.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSchemeColorPalette.java
new file mode 100644
index 0000000..4803140
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSchemeColorPalette.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.terminal;
+
+import com.intellij.execution.process.ColoredOutputTypeRegistry;
+import com.intellij.execution.process.ConsoleHighlighter;
+import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.jediterm.terminal.emulator.ColorPalette;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.*;
+
+/**
+ * @author traff
+ */
+public class JBTerminalSchemeColorPalette extends ColorPalette {
+
+ private final EditorColorsScheme myColorsScheme;
+
+ protected JBTerminalSchemeColorPalette(EditorColorsScheme scheme) {
+ super();
+ myColorsScheme = scheme;
+ }
+
+ @Override
+ public Color[] getIndexColors() {
+ Color[] result = XTERM_PALETTE.getIndexColors();
+ for (int i = 1; i < 7; i++) {
+ result[i] = myColorsScheme.getAttributes(ColoredOutputTypeRegistry.getAnsiColorKey(i)).getForegroundColor();
+ }
+ return result;
+ }
+}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java
index b67002e9..b0f9cc3 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java
@@ -2,9 +2,11 @@
import com.intellij.application.options.OptionsConstants;
import com.intellij.execution.ui.ConsoleViewContentType;
+import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.actionSystem.Shortcut;
import com.intellij.openapi.editor.colors.*;
+import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.options.FontSize;
@@ -18,6 +20,7 @@
import com.jediterm.terminal.TtyConnector;
import com.jediterm.terminal.emulator.ColorPalette;
import com.jediterm.terminal.ui.settings.DefaultSettingsProvider;
+import com.jediterm.terminal.ui.settings.DefaultTabbedSettingsProvider;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,7 +35,7 @@
/**
* @author traff
*/
-class JBTerminalSystemSettingsProvider extends DefaultSettingsProvider {
+class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider {
private final EditorColorsScheme myColorScheme;
@@ -52,7 +55,7 @@
@Override
public ColorPalette getTerminalColorPalette() {
- return SystemInfo.isWindows ? ColorPalette.WINDOWS_PALETTE : ColorPalette.XTERM_PALETTE;
+ return new JBTerminalSchemeColorPalette(myColorScheme);
}
private KeyStroke[] getKeyStrokesByActionId(String actionId) {
@@ -74,6 +77,16 @@
}
@Override
+ public String tabName(TtyConnector ttyConnector, String sessionName) { //for local terminal use name from settings
+ if (ttyConnector instanceof PtyProcessTtyConnector) {
+ return TerminalOptionsProvider.getInstance().getTabName();
+ }
+ else {
+ return sessionName;
+ }
+ }
+
+ @Override
public float getLineSpace() {
return myColorScheme.getConsoleLineSpacing();
}
@@ -131,10 +144,41 @@
return (float)myColorScheme.getConsoleFontSize();
}
+
+ @Override
+ public boolean useAntialiasing() {
+ return UISettings.getInstance().ANTIALIASING_IN_EDITOR;
+ }
+
+ @Override
+ public int caretBlinkingMs() {
+ return EditorSettingsExternalizable.getInstance().getBlinkPeriod();
+ }
+
public EditorColorsScheme getColorScheme() {
return createBoundColorSchemeDelegate(null);
}
+ @Override
+ public boolean audibleBell() {
+ return TerminalOptionsProvider.getInstance().audibleBell();
+ }
+
+ @Override
+ public boolean enableMouseReporting() {
+ return TerminalOptionsProvider.getInstance().enableMouseReporting();
+ }
+
+ @Override
+ public boolean copyOnSelect() {
+ return TerminalOptionsProvider.getInstance().copyOnSelection();
+ }
+
+ @Override
+ public boolean pasteOnMiddleMouseClick() {
+ return TerminalOptionsProvider.getInstance().pasteOnMiddleMouseButton();
+ }
+
@NotNull
public EditorColorsScheme createBoundColorSchemeDelegate(@Nullable final EditorColorsScheme customGlobalScheme) {
return new MyColorSchemeDelegate(customGlobalScheme);
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java
index dc8c410..064dad9 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java
@@ -39,21 +39,36 @@
super(project);
myDefaultCharset = Charset.forName("UTF-8");
+ String shellPath = TerminalOptionsProvider.getInstance().getShellPath();
+
if (SystemInfo.isUnix) {
File rcFile = findRCFile();
- if (rcFile != null) {
- myCommand = new String[]{"/bin/bash", "--rcfile", rcFile.getAbsolutePath(), "-i"};
+ String shellName = getShellName(shellPath);
+
+ if (rcFile != null && (shellName.equals("bash") || shellName.equals("sh"))) {
+ myCommand = new String[]{shellPath, "--rcfile", rcFile.getAbsolutePath(), "-i"};
+ }
+ else if (hasLoginArgument(shellName)) {
+ myCommand = new String[]{shellPath, "--login"};
}
else {
- myCommand = new String[]{"/bin/bash", "--login"};
+ myCommand = shellPath.split(" ");
}
}
else {
- myCommand = new String[]{"cmd.exe"};
+ myCommand = new String[]{shellPath};
}
}
+ private static boolean hasLoginArgument(String name) {
+ return name.equals("bash") || name.equals("sh") || name.equals("zsh");
+ }
+
+ private static String getShellName(String path) {
+ return new File(path).getName();
+ }
+
private static File findRCFile() {
try {
final String folder = PtyUtil.getJarFolder();
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalOptionsConfigurable.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalOptionsConfigurable.java
new file mode 100644
index 0000000..9ea8fa2
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalOptionsConfigurable.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.terminal;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+ * @author traff
+ */
+public class TerminalOptionsConfigurable implements SearchableConfigurable, Configurable.NoScroll, Disposable {
+ public static final String TERMINAL_SETTINGS_HELP_REFERENCE = "reference.settings.terminal";
+
+ private TerminalSettingsPanel myPanel;
+
+ private final TerminalOptionsProvider myOptionsProvider;
+ private Project myProject;
+
+ public TerminalOptionsConfigurable(Project project) {
+ myOptionsProvider = TerminalOptionsProvider.getInstance();
+ myProject = project;
+ }
+
+ @NotNull
+ @Override
+ public String getId() {
+ return "terminal";
+ }
+
+ @Override
+ public Runnable enableSearch(String option) {
+ return null;
+ }
+
+
+ @Nls
+ @Override
+ public String getDisplayName() {
+ return "Terminal";
+ }
+
+ @Override
+ public String getHelpTopic() {
+ return TERMINAL_SETTINGS_HELP_REFERENCE;
+ }
+
+ @Override
+ public JComponent createComponent() {
+ myPanel = new TerminalSettingsPanel();
+
+ return myPanel.createPanel(myOptionsProvider);
+ }
+
+ @Override
+ public boolean isModified() {
+ return myPanel.isModified();
+ }
+
+ @Override
+ public void apply() throws ConfigurationException {
+ myPanel.apply();
+ }
+
+
+ @Override
+ public void reset() {
+ myPanel.reset();
+ }
+
+ @Override
+ public void disposeUIResources() {
+ Disposer.dispose(this);
+ }
+
+ @Override
+ public void dispose() {
+ myPanel = null;
+ }
+}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalOptionsProvider.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalOptionsProvider.java
new file mode 100644
index 0000000..dd59065
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalOptionsProvider.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.terminal;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.text.StringUtil;
+import com.jediterm.terminal.emulator.ColorPalette;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+/**
+ * @author traff
+ */
+@State(
+ name = "TerminalOptionsProvider",
+ storages = {
+ @Storage(
+ file = StoragePathMacros.APP_CONFIG + "/terminal.xml"
+ )}
+)
+public class TerminalOptionsProvider implements PersistentStateComponent<TerminalOptionsProvider.State>, ExportableApplicationComponent {
+ private State myState = new State();
+
+ public static TerminalOptionsProvider getInstance() {
+ return ApplicationManager.getApplication().getComponent(TerminalOptionsProvider.class);
+ }
+
+ @Override
+ public State getState() {
+ return myState;
+ }
+
+ @Override
+ public void loadState(State state) {
+ myState.myShellPath = state.myShellPath;
+ myState.myCloseSessionOnLogout = state.myCloseSessionOnLogout;
+ myState.myReportMouse = state.myReportMouse;
+ myState.mySoundBell = state.mySoundBell;
+ myState.myTabName = state.myTabName;
+ myState.myCopyOnSelection = state.myCopyOnSelection;
+ myState.myPasteOnMiddleMouseButton = state.myPasteOnMiddleMouseButton;
+ }
+
+ public boolean closeSessionOnLogout() {
+ return myState.myCloseSessionOnLogout;
+ }
+
+ public boolean enableMouseReporting() {
+ return myState.myReportMouse;
+ }
+
+ public boolean audibleBell() {
+ return myState.mySoundBell;
+ }
+
+ public String getTabName() {
+ return myState.myTabName;
+ }
+
+ public static class State {
+ public String myShellPath = getDefaultShellPath();
+ public String myTabName = "Local";
+ public boolean myCloseSessionOnLogout = true;
+ public boolean myReportMouse = true;
+ public boolean mySoundBell = true;
+ public boolean myCopyOnSelection = true;
+ public boolean myPasteOnMiddleMouseButton = true;
+ }
+
+ public String getShellPath() {
+ return myState.myShellPath;
+ }
+
+ private static String getDefaultShellPath() {
+ if (SystemInfo.isUnix) {
+ return "/bin/bash";
+ }
+ else {
+ return "cmd.exe";
+ }
+ }
+
+ public void setShellPath(String shellPath) {
+ myState.myShellPath = shellPath;
+ }
+
+ public void setTabName(String tabName) {
+ myState.myTabName = tabName;
+ }
+
+ public void setCloseSessionOnLogout(boolean closeSessionOnLogout) {
+ myState.myCloseSessionOnLogout = closeSessionOnLogout;
+ }
+
+ public void setReportMouse(boolean reportMouse) {
+ myState.myReportMouse = reportMouse;
+ }
+
+ public void setSoundBell(boolean soundBell) {
+ myState.mySoundBell = soundBell;
+ }
+
+ public boolean copyOnSelection() {
+ return myState.myCopyOnSelection;
+ }
+
+ public void setCopyOnSelection(boolean copyOnSelection) {
+ myState.myCopyOnSelection = copyOnSelection;
+ }
+
+ public boolean pasteOnMiddleMouseButton() {
+ return myState.myPasteOnMiddleMouseButton;
+ }
+
+ public void setPasteOnMiddleMouseButton(boolean pasteOnMiddleMouseButton) {
+ myState.myPasteOnMiddleMouseButton = pasteOnMiddleMouseButton;
+ }
+
+ @Override
+ public void initComponent() {
+ }
+
+ @Override
+ public void disposeComponent() {
+ }
+
+ @NotNull
+ @Override
+ public File[] getExportFiles() {
+ return new File[]{new File(PathManager.getOptionsPath() + File.separatorChar + "terminal.xml")};
+ }
+
+ @NotNull
+ @Override
+ public String getPresentableName() {
+ return "TerminalOptions";
+ }
+
+ @NotNull
+ @Override
+ public String getComponentName() {
+ return "TerminalOptionsProvider";
+ }
+}
+
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.form b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.form
new file mode 100644
index 0000000..45678d4
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.form
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.plugins.terminal.TerminalSettingsPanel">
+ <grid id="27dc6" binding="myWholePanel" 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>
+ <xy x="20" y="20" width="500" height="400"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <grid id="8f9b9" layout-manager="GridLayoutManager" row-count="6" 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="7" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <clientProperties>
+ <BorderFactoryClass class="java.lang.String" value=""/>
+ </clientProperties>
+ <border type="none"/>
+ <children>
+ <grid id="57ec0" 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="0" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="b854b" 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>
+ <horizontalTextPosition value="2"/>
+ <text value="Default shell"/>
+ </properties>
+ </component>
+ <component id="8b4db" class="javax.swing.JTextField" binding="myShellTextField">
+ <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>
+ <component id="f633a" 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>
+ <horizontalTextPosition value="2"/>
+ <text value="Tab name"/>
+ </properties>
+ </component>
+ <component id="5495b" class="javax.swing.JTextField" binding="myTabNameTextField">
+ <constraints>
+ <grid row="1" 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>
+ <vspacer id="d777c">
+ <constraints>
+ <grid row="5" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </vspacer>
+ <grid id="caa1d" 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="1" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="f974" class="com.intellij.ui.components.JBCheckBox" binding="myCloseSessionCheckBox">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Close session when it ends"/>
+ </properties>
+ </component>
+ <hspacer id="4d085">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </hspacer>
+ <grid id="b4260" 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="1" 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/>
+ <border type="none"/>
+ <children>
+ <component id="7a03b" class="com.intellij.ui.components.JBCheckBox" binding="mySoundBellCheckBox">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Audible bell"/>
+ </properties>
+ </component>
+ <hspacer id="d3b9">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </hspacer>
+ </children>
+ </grid>
+ </children>
+ </grid>
+ <grid id="efc62" 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="2" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="e2773" class="com.intellij.ui.components.JBCheckBox" binding="myMouseReportCheckBox">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Mouse reporting"/>
+ </properties>
+ </component>
+ <hspacer id="2f4aa">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </hspacer>
+ </children>
+ </grid>
+ <grid id="e134" 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="3" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="f1844" class="com.intellij.ui.components.JBCheckBox" binding="myCopyOnSelectionCheckBox">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Copy to clipboard on selection"/>
+ </properties>
+ </component>
+ <hspacer id="f4740">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </hspacer>
+ </children>
+ </grid>
+ <grid id="5aa62" 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="4" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="8a427" class="com.intellij.ui.components.JBCheckBox" binding="myPasteOnMiddleButtonCheckBox">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Paste on middle mouse button click"/>
+ </properties>
+ </component>
+ <hspacer id="cfc3e">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </hspacer>
+ </children>
+ </grid>
+ </children>
+ </grid>
+ </children>
+ </grid>
+ <buttonGroups>
+ <group name="1">
+ <member id="3c34e"/>
+ <member id="97f18"/>
+ <member id="12b2e"/>
+ </group>
+ </buttonGroups>
+</form>
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.java
new file mode 100644
index 0000000..0400bb3
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.terminal;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.ui.components.JBCheckBox;
+
+import javax.swing.*;
+
+/**
+ * @author traff
+ */
+public class TerminalSettingsPanel {
+ private JPanel myWholePanel;
+ private JTextField myShellTextField;
+ private JBCheckBox mySoundBellCheckBox;
+ private JBCheckBox myCloseSessionCheckBox;
+ private JBCheckBox myMouseReportCheckBox;
+ private JTextField myTabNameTextField;
+ private JBCheckBox myPasteOnMiddleButtonCheckBox;
+ private JBCheckBox myCopyOnSelectionCheckBox;
+ private TerminalOptionsProvider myOptionsProvider;
+
+ public JComponent createPanel(TerminalOptionsProvider provider) {
+ myOptionsProvider = provider;
+
+ return myWholePanel;
+ }
+
+ public boolean isModified() {
+ return !Comparing.equal(myShellTextField.getText(), myOptionsProvider.getShellPath())
+ || !Comparing.equal(myTabNameTextField.getText(), myOptionsProvider.getTabName())
+ || (myCloseSessionCheckBox.isSelected() != myOptionsProvider.closeSessionOnLogout())
+ || (myMouseReportCheckBox.isSelected() != myOptionsProvider.enableMouseReporting())
+ || (mySoundBellCheckBox.isSelected() != myOptionsProvider.audibleBell())
+ || (myCopyOnSelectionCheckBox.isSelected() != myOptionsProvider.copyOnSelection())
+ || (myPasteOnMiddleButtonCheckBox.isSelected() != myOptionsProvider.pasteOnMiddleMouseButton())
+ ;
+ }
+
+ public void apply() {
+ myOptionsProvider.setShellPath(myShellTextField.getText());
+ myOptionsProvider.setTabName(myTabNameTextField.getText());
+ myOptionsProvider.setCloseSessionOnLogout(myCloseSessionCheckBox.isSelected());
+ myOptionsProvider.setReportMouse(myMouseReportCheckBox.isSelected());
+ myOptionsProvider.setSoundBell(mySoundBellCheckBox.isSelected());
+ myOptionsProvider.setCopyOnSelection(myCopyOnSelectionCheckBox.isSelected());
+ myOptionsProvider.setPasteOnMiddleMouseButton(myPasteOnMiddleButtonCheckBox.isSelected());
+ }
+
+ public void reset() {
+ myShellTextField.setText(myOptionsProvider.getShellPath());
+ myTabNameTextField.setText(myOptionsProvider.getTabName());
+ myCloseSessionCheckBox.setSelected(myOptionsProvider.closeSessionOnLogout());
+ myMouseReportCheckBox.setSelected(myOptionsProvider.enableMouseReporting());
+ mySoundBellCheckBox.setSelected(myOptionsProvider.audibleBell());
+ myCopyOnSelectionCheckBox.setSelected(myOptionsProvider.copyOnSelection());
+ myPasteOnMiddleButtonCheckBox.setSelected(myOptionsProvider.pasteOnMiddleMouseButton());
+ }
+}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java
index 188be8f..ff54c00 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java
@@ -2,11 +2,13 @@
import com.intellij.icons.AllIcons;
import com.intellij.notification.EventLog;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
@@ -75,6 +77,15 @@
}
}
});
+
+ Disposer.register(project, new Disposable() {
+ @Override
+ public void dispose() {
+ if (myTerminalWidget != null) {
+ myTerminalWidget.dispose();
+ }
+ }
+ });
}
private Content createToolWindowContentPanel(@Nullable LocalTerminalDirectRunner terminalRunner,
@@ -102,7 +113,7 @@
content.setCloseable(true);
content.setPreferredFocusableComponent(terminalWidget.getComponent());
-
+
return content;
}
diff --git a/plugins/testng/src/META-INF/plugin.xml b/plugins/testng/src/META-INF/plugin.xml
index fe64bc8..fff400d 100644
--- a/plugins/testng/src/META-INF/plugin.xml
+++ b/plugins/testng/src/META-INF/plugin.xml
@@ -56,6 +56,10 @@
<forcedElementWeigher implementation="com.theoryinpractice.testng.TestNGForcedElementWeigher"/>
<gotoRelatedProvider implementation="com.theoryinpractice.testng.TestNGRelatedFilesProvider"/>
<methodReferencesSearch implementation="com.theoryinpractice.testng.DataProviderSearcher"/>
+ <stacktrace.fold substring="at org.testng.internal."/>
+ <stacktrace.fold substring="at org.testng.TestRunner."/>
+ <stacktrace.fold substring="at org.testng.SuiteRunner."/>
+ <stacktrace.fold substring="at org.testng.TestNG.run"/>
</extensions>
<extensionPoints >
<extensionPoint qualifiedName="com.theoryinpractice.testng.listener" interface="org.testng.IDEATestNGListener"/>
diff --git a/plugins/testng/src/com/theoryinpractice/testng/TestNGFramework.java b/plugins/testng/src/com/theoryinpractice/testng/TestNGFramework.java
index 0df50c5..1cf1f53 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/TestNGFramework.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/TestNGFramework.java
@@ -167,6 +167,11 @@
return inClass;
}
+ @Override
+ public char getMnemonic() {
+ return 'N';
+ }
+
public FileTemplateDescriptor getSetUpMethodFileTemplateDescriptor() {
return new FileTemplateDescriptor("TestNG SetUp Method.java");
}
diff --git a/resources-en/src/messages/CompilerBundle.properties b/resources-en/src/messages/CompilerBundle.properties
index 902e3df..b9167ee 100644
--- a/resources-en/src/messages/CompilerBundle.properties
+++ b/resources-en/src/messages/CompilerBundle.properties
@@ -155,7 +155,7 @@
label.text.class.path=Class &Path:
element.type.name.artifact=Artifact
dialog.title.choose.artifacts=Choose Artifacts
-node.text.0.directory.content=''{0}'' directory content
+node.text.0.directory.content=''{0}'' directory contents
element.type.name.library.files=Library Files
node.text.0.compile.output=''{0}'' compile output
node.text.0.test.compile.output=''{0}'' test compile output
diff --git a/resources-en/src/messages/DebuggerBundle.properties b/resources-en/src/messages/DebuggerBundle.properties
index 11189d3..01984ee 100644
--- a/resources-en/src/messages/DebuggerBundle.properties
+++ b/resources-en/src/messages/DebuggerBundle.properties
@@ -445,3 +445,5 @@
action.kill.process.text=Kill Process
action.kill.process.description=Forcibly terminate debugged application
evaluation.error.unknown.method.return.type=Cannot resolve method return type: {0}
+
+java.breakpoint.title=Java Line Breakpoints
diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml
index b83adb0..1460baf 100644
--- a/resources/src/META-INF/IdeaPlugin.xml
+++ b/resources/src/META-INF/IdeaPlugin.xml
@@ -1429,8 +1429,6 @@
<wizardMode implementation="com.intellij.ide.util.newProjectWizard.modes.CreateProjectFromSourcesMode" id="CreateProjectFromSourcesMode" order="after CreateFromScratchMode"/>
<wizardMode implementation="com.intellij.ide.util.newProjectWizard.modes.CreateModuleFromSourcesMode" id="CreateModuleFromSourcesMode" order="after CreateProjectFromSourcesMode"/>
- <projectWizard.projectCategory implementation="com.intellij.ide.projectWizard.CommonJavaProjectCategory"/>
-
<projectTemplateParameterFactory implementation="com.intellij.openapi.module.BasePackageParameterFactory"/>
<projectStructureDetector implementation="com.intellij.ide.util.projectWizard.importSources.impl.JavaProjectStructureDetector" order="first"/>
@@ -1478,6 +1476,8 @@
implementationClass="org.jetbrains.generate.tostring.inspection.FieldNotUsedInToStringInspection"/>
<codeInsight.unresolvedReferenceQuickFixProvider implementation="com.intellij.jarFinder.FindJarQuickFixProvider"/>
+
+ <xdebugger.breakpointType implementation="org.jetbrains.java.debugger.breakpoints.JavaBreakpointType"/>
</extensions>
<actions>
diff --git a/spellchecker/src/com/intellij/spellchecker/dictionary/ProjectDictionary.java b/spellchecker/src/com/intellij/spellchecker/dictionary/ProjectDictionary.java
index b72c8f4..dd8c11c 100644
--- a/spellchecker/src/com/intellij/spellchecker/dictionary/ProjectDictionary.java
+++ b/spellchecker/src/com/intellij/spellchecker/dictionary/ProjectDictionary.java
@@ -31,7 +31,6 @@
private String activeName;
private Set<EditableDictionary> dictionaries;
-
public ProjectDictionary() {
}
@@ -50,10 +49,6 @@
return DEFAULT_PROJECT_DICTIONARY_NAME;
}
- public String getActiveName() {
- return activeName;
- }
-
public void setActiveName(String name) {
activeName = name;
}
@@ -124,7 +119,6 @@
return result;
}
-
@Override
public void replaceAll(@Nullable Collection<String> words) {
getActiveDictionary().replaceAll(words);
@@ -144,7 +138,10 @@
}
Set<String> words = new HashSet<String>();
for (Dictionary dictionary : dictionaries) {
- words.addAll(dictionary.getWords());
+ Set<String> otherWords = dictionary.getWords();
+ if (otherWords != null) {
+ words.addAll(otherWords);
+ }
}
return words;
}
diff --git a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
index b660e4c..8e65b7f 100644
--- a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
+++ b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
@@ -11,6 +11,7 @@
arity
asensitive
aspectj
+async
attr
attlist
auth
@@ -84,6 +85,7 @@
cron
ctrl
customizer
+cyclomatic
datafile
datafiles
datetime
diff --git a/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionarySplitter.java b/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionarySplitter.java
index 247ae43..998732f 100644
--- a/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionarySplitter.java
+++ b/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionarySplitter.java
@@ -16,7 +16,6 @@
package com.intellij.spellchecker.state;
import com.intellij.openapi.components.StateSplitter;
-import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.text.UniqueNameGenerator;
@@ -31,22 +30,20 @@
* @author shkate@jetbrains.com
*/
public class ProjectDictionarySplitter implements StateSplitter {
-
+ @Override
public List<Pair<Element, String>> splitState(Element e) {
final UniqueNameGenerator generator = new UniqueNameGenerator();
-
List<Pair<Element, String>> result = new ArrayList<Pair<Element, String>>();
- for (Element element : JDOMUtil.getElements(e)) {
- final String name = generator.generateUniqueName(FileUtil.sanitizeFileName(element.getAttributeValue(DictionaryState.NAME_ATTRIBUTE))) + ".xml";
-
- result.add(new Pair<Element, String>(element, name));
+ for (Element element : e.getChildren()) {
+ result.add(Pair.create(element, generator.generateUniqueName(FileUtil.sanitizeFileName(element.getAttributeValue(DictionaryState.NAME_ATTRIBUTE))) + ".xml"));
}
return result;
}
+ @Override
public void mergeStatesInto(Element target, Element[] elements) {
for (Element e : elements) {
target.addContent(e);
}
}
-}
+}
\ No newline at end of file
diff --git a/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionaryState.java b/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionaryState.java
index 717af47..4237d88 100644
--- a/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionaryState.java
+++ b/spellchecker/src/com/intellij/spellchecker/state/ProjectDictionaryState.java
@@ -16,7 +16,6 @@
package com.intellij.spellchecker.state;
import com.intellij.openapi.components.*;
-import com.intellij.openapi.project.Project;
import com.intellij.spellchecker.dictionary.EditableDictionary;
import com.intellij.spellchecker.dictionary.ProjectDictionary;
import com.intellij.util.xmlb.annotations.AbstractCollection;
@@ -36,31 +35,17 @@
scheme = StorageScheme.DIRECTORY_BASED, stateSplitter = ProjectDictionarySplitter.class)
}
)
-public class ProjectDictionaryState implements PersistentStateComponent<ProjectDictionaryState>{
-
+public class ProjectDictionaryState implements PersistentStateComponent<ProjectDictionaryState> {
@Property(surroundWithTag = false) @AbstractCollection(surroundWithTag = false, elementTypes = DictionaryState.class)
public List<DictionaryState> dictionaryStates = new ArrayList<DictionaryState>();
-
private ProjectDictionary projectDictionary;
- private String currentUser;
- private Project project;
public ProjectDictionaryState() {
}
- public void setProject(Project project) {
- this.project = project;
- }
-
- public void setCurrentUser(String currentUser) {
- this.currentUser = currentUser;
- }
-
-
@Transient
public void setProjectDictionary(ProjectDictionary projectDictionary) {
- currentUser = projectDictionary.getActiveName();
dictionaryStates.clear();
Set<EditableDictionary> projectDictionaries = projectDictionary.getDictionaries();
if (projectDictionaries != null) {
@@ -72,21 +57,22 @@
@Transient
public ProjectDictionary getProjectDictionary() {
- if (projectDictionary==null){
+ if (projectDictionary == null) {
projectDictionary = new ProjectDictionary();
}
return projectDictionary;
}
+ @Override
public ProjectDictionaryState getState() {
- if (projectDictionary!=null){
+ if (projectDictionary != null) {
//ensure all dictionaries within project dictionary will be stored
setProjectDictionary(projectDictionary);
}
return this;
}
-
+ @Override
public void loadState(ProjectDictionaryState state) {
if (state != null) {
this.dictionaryStates = state.dictionaryStates;
diff --git a/xml/impl/src/com/intellij/codeInsight/editorActions/moveUpDown/XmlMover.java b/xml/impl/src/com/intellij/codeInsight/editorActions/moveUpDown/XmlMover.java
index 98e646c..770ac7a 100644
--- a/xml/impl/src/com/intellij/codeInsight/editorActions/moveUpDown/XmlMover.java
+++ b/xml/impl/src/com/intellij/codeInsight/editorActions/moveUpDown/XmlMover.java
@@ -19,6 +19,7 @@
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.UnfairTextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiNamedElement;
@@ -106,7 +107,7 @@
movedLineStart = updateMovedRegionStart(document, movedLineStart, textRange.getStartOffset(), info, down);
}
- final TextRange moveDestinationRange = new TextRange(
+ final TextRange moveDestinationRange = new UnfairTextRange(
document.getLineStartOffset(info.toMove2.startLine),
document.getLineEndOffset(info.toMove2.endLine - 1)
);
diff --git a/xml/impl/src/com/intellij/ide/highlighter/HtmlFileHighlighter.java b/xml/impl/src/com/intellij/ide/highlighter/HtmlFileHighlighter.java
index daff833..151b4aa 100644
--- a/xml/impl/src/com/intellij/ide/highlighter/HtmlFileHighlighter.java
+++ b/xml/impl/src/com/intellij/ide/highlighter/HtmlFileHighlighter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -80,11 +80,13 @@
keys1.put(XmlTokenType.XML_BAD_CHARACTER, HighlighterColors.BAD_CHARACTER);
}
+ @Override
@NotNull
public Lexer getHighlightingLexer() {
return new HtmlHighlightingLexer();
}
+ @Override
@NotNull
public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
return pack(XmlHighlighterColors.HTML_CODE, pack(keys1.get(tokenType), keys2.get(tokenType)));
diff --git a/xml/impl/src/com/intellij/ide/highlighter/XmlFileHighlighter.java b/xml/impl/src/com/intellij/ide/highlighter/XmlFileHighlighter.java
index 4b68ad9..6c515a1 100644
--- a/xml/impl/src/com/intellij/ide/highlighter/XmlFileHighlighter.java
+++ b/xml/impl/src/com/intellij/ide/highlighter/XmlFileHighlighter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -134,6 +134,7 @@
myIsXHtml = xhtml;
}
+ @Override
@NotNull
public Lexer getHighlightingLexer() {
if (myIsDtd) {
@@ -145,6 +146,7 @@
}
}
+ @Override
@NotNull
public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
return pack(keys1.get(tokenType), keys2.get(tokenType));
diff --git a/xml/impl/src/com/intellij/lexer/HtmlHighlightingLexer.java b/xml/impl/src/com/intellij/lexer/HtmlHighlightingLexer.java
index 5a44c3f..660e215 100644
--- a/xml/impl/src/com/intellij/lexer/HtmlHighlightingLexer.java
+++ b/xml/impl/src/com/intellij/lexer/HtmlHighlightingLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.xml.XmlTokenType;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class HtmlHighlightingLexer extends BaseHtmlLexer {
@@ -96,7 +97,7 @@
registerHandler(XmlTokenType.XML_COMMENT_CHARACTERS,value);
}
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
super.start(buffer, startOffset, endOffset, initialState);
if ((initialState & EMBEDDED_LEXER_ON)!=0) {
diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/lexer/CompactSyntaxLexerAdapter.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/lexer/CompactSyntaxLexerAdapter.java
index f16484d..b6911cc 100644
--- a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/lexer/CompactSyntaxLexerAdapter.java
+++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/lexer/CompactSyntaxLexerAdapter.java
@@ -25,6 +25,7 @@
import com.intellij.util.text.CharArrayUtil;
import gnu.trove.TIntIntHashMap;
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.kohsuke.rngom.parse.compact.*;
@@ -130,6 +131,7 @@
return CharArrayUtil.fromSequence(myBuffer);
}
+ @NotNull
@Override
public CharSequence getBufferSequence() {
return myBuffer;
@@ -173,7 +175,7 @@
}
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
myBuffer = buffer;
final Reader reader = new CharSequenceReader(buffer, startOffset, endOffset);
diff --git a/xml/xml-psi-impl/src/com/intellij/ide/highlighter/DTDFileType.java b/xml/xml-psi-impl/src/com/intellij/ide/highlighter/DTDFileType.java
index 276837d..3c9005d 100644
--- a/xml/xml-psi-impl/src/com/intellij/ide/highlighter/DTDFileType.java
+++ b/xml/xml-psi-impl/src/com/intellij/ide/highlighter/DTDFileType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,21 +30,25 @@
super(DTDLanguage.INSTANCE);
}
+ @Override
@NotNull
public String getName() {
return "DTD";
}
+ @Override
@NotNull
public String getDescription() {
return IdeBundle.message("filetype.description.dtd");
}
+ @Override
@NotNull
public String getDefaultExtension() {
return "dtd";
}
+ @Override
public Icon getIcon() {
return AllIcons.FileTypes.Dtd;
}
diff --git a/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XHtmlFileType.java b/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XHtmlFileType.java
index 9d282e2..f8d96be 100644
--- a/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XHtmlFileType.java
+++ b/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XHtmlFileType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,21 +29,25 @@
super(XHTMLLanguage.INSTANCE);
}
+ @Override
@NotNull
public String getName() {
return "XHTML";
}
+ @Override
@NotNull
public String getDescription() {
return IdeBundle.message("filetype.description.xhtml");
}
+ @Override
@NotNull
public String getDefaultExtension() {
return "xhtml";
}
+ @Override
public Icon getIcon() {
return AllIcons.FileTypes.Xhtml;
}
diff --git a/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XmlFileType.java b/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XmlFileType.java
index 7c0447d..fecf473 100644
--- a/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XmlFileType.java
+++ b/xml/xml-psi-impl/src/com/intellij/ide/highlighter/XmlFileType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,21 +32,25 @@
super(XMLLanguage.INSTANCE);
}
+ @Override
@NotNull
public String getName() {
return "XML";
}
+ @Override
@NotNull
public String getDescription() {
return IdeBundle.message("filetype.description.xml");
}
+ @Override
@NotNull
public String getDefaultExtension() {
return DEFAULT_EXTENSION;
}
+ @Override
public Icon getIcon() {
return AllIcons.FileTypes.Xml;
}
diff --git a/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java b/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java
index 5cb76ec..013d94e 100644
--- a/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java
+++ b/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
import com.intellij.psi.xml.XmlTokenType;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
@@ -239,7 +240,7 @@
tokenHandlers.put(elementType,value);
}
- public void start(final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
+ public void start(@NotNull final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
initState(initialState);
super.start(buffer, startOffset, endOffset, initialState & BASE_STATE_MASK);
}
diff --git a/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java b/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java
index 98858a3..34864b6 100644
--- a/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java
+++ b/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
import com.intellij.psi.TokenType;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.xml.XmlTokenType;
+import org.jetbrains.annotations.NotNull;
/**
* @author Maxim.Mossienko
@@ -51,7 +52,7 @@
private int myTokenEnd;
@Override
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
myTokenType = null;
super.start(buffer, startOffset, endOffset, initialState);
}
diff --git a/xml/xml-psi-impl/src/com/intellij/lexer/_XmlLexer.java b/xml/xml-psi-impl/src/com/intellij/lexer/_XmlLexer.java
index d78deb8..199ce9d 100644
--- a/xml/xml-psi-impl/src/com/intellij/lexer/_XmlLexer.java
+++ b/xml/xml-psi-impl/src/com/intellij/lexer/_XmlLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,8 @@
/* It's an automatically generated code. Do not modify it. */
package com.intellij.lexer;
+import org.jetbrains.annotations.NotNull;
+
public class _XmlLexer extends FlexAdapter {
private int myState = __XmlLexer.YYINITIAL;
@@ -43,7 +45,7 @@
packState();
}
- public void start(final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
+ public void start(@NotNull final CharSequence buffer, final int startOffset, final int endOffset, final int initialState) {
super.start(buffer, startOffset, endOffset, initialState);
handleState(initialState);
}
diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/parsing/xml/DtdParsing.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/parsing/xml/DtdParsing.java
index 8819dc3..b8c6b2a 100644
--- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/parsing/xml/DtdParsing.java
+++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/parsing/xml/DtdParsing.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.xml.XmlElementType;
import com.intellij.psi.xml.XmlEntityDecl;
+import org.jetbrains.annotations.NotNull;
/**
* @author Mike
@@ -65,7 +66,7 @@
new DtdLexer(false) {
final int myInitialState = getLexerInitialState(type, contextType);
@Override
- public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
super.start(buffer, startOffset, endOffset, myInitialState);
}
}, chars
diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java
index c986bb1..b030815 100644
--- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java
+++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java
@@ -296,7 +296,7 @@
final String schemaLocationDeclaration = getAttributeValue("schemaLocation", XmlUtil.XML_SCHEMA_INSTANCE_URI);
if (noNamespaceDeclaration != null) {
- map = initializeSchema(XmlUtil.EMPTY_URI, null, noNamespaceDeclaration, map);
+ map = initializeSchema(XmlUtil.EMPTY_URI, null, noNamespaceDeclaration, null);
}
if (schemaLocationDeclaration != null) {
final StringTokenizer tokenizer = new StringTokenizer(schemaLocationDeclaration);
@@ -334,7 +334,7 @@
return null;
}
- private Map<String, CachedValue<XmlNSDescriptor>> initializeSchema(final String namespace,
+ private Map<String, CachedValue<XmlNSDescriptor>> initializeSchema(final @NotNull String namespace,
@Nullable final String version,
final String fileLocation,
Map<String, CachedValue<XmlNSDescriptor>> map) {
@@ -422,7 +422,7 @@
}
@Nullable
- private PsiMetaOwner retrieveOwner(final XmlFile file, final String namespace) {
+ private PsiMetaOwner retrieveOwner(final XmlFile file, final @NotNull String namespace) {
if (file == null) {
return namespace.equals(XmlUtil.getTargetSchemaNsFromTag(this)) ? this : null;
}